Subsections of API Guide

API Quick start

Introduction

Overview

In this document, we will guide you through the process of using Acreto API to define a new Thing. To do this, we will:

  1. Authenticate to get an access token
  2. List ecosystems to find the one we will use
  3. List Profile Groups to find the one we will use
  4. Create a new Thing
  5. Read the Thing to ensure it was created
  6. Commit changes

Prerequisites

Before you start, you will need to:

Conventions

Our API follows the following conventions, standards and best practices:

API versioning

This document describes API version 2. Our approach to versioning allows us to guarantee backward compatibility of APIs.

API endpoints

Production:

Environment varialbles

All examples in this document are constructed as curl commands. For convenience, the following environment variables are used in these examples:

  • ENDPOINT=https://api-is-rock-solid.acreto.net/v2
  • USERNAME=someone@somedomain.com
  • PASSWORD=************
  • TOKEN - access token retrieved from /auth/login endpoint
  • CUSTOMERUUID - ID of customer (organization) account
  • ECOSYSTEMUUID - ID of the ecosystem to be used

API basics

Authentication

Unless stated otherwise, each request sent to API should contain an access token in the “Authorization: Bearer” header. This token can be retrieved from /auth/login endpoint (see below).

Example of the header:

Authorization: Bearer GciiIUI1NiIsInR5cCI6IkpXVCJ9.JleHBpcnkiOjYwMCwicm9sZOiJmaW5hbmlX2FkbWlucy42NzxNjMyYi1iMzM3LTRjZDAtM2NiYy1lOTAwZTJjNzdmYTMgc3VwZXJZG1pbnMuNjc0MTYzMmItYjMzNy00Y2QNjYmMtZTkwMGUyYzc3ZmEzIiwic2VjanVLMVpSM2dvVmowNFRwSFRFSkJXS3giLCJ1c2VybmFtZSI6ImxrbGltZWsrZG9jQGdtYWlsLmNvbSIsInV1aWQiOiMS1kMDU4LTBjMzYtZGU2NS1lZmY0MWUwY2EwNjMifQ.YR7Vm8ys2p3NHJs65QymqBPJ52lsnOXcxj_1WSbyMh0

The token has set an expiration time, set to 600 seconds by default. When the token expires, the API request will fail with HTTP status 401. Your application should detect such a situation, retrieve a new token and retry the failed request.

Coming soon: Expiry time will be exposed as part of the response to /auth/login request, as expiry field.

Object updates

To handle updates, we use HTTP PUT method. Unless stated otherwise, PUT replaces the resource in its entirety. It means that:

  • any update operation MUST contain all fields of the resource,
  • sending PUT request without some field will either remove it from the resource or set it to “zero value”.

One important exception here is updating credentials (like passwords), which usually has its own endpoint. See API documentation for details.

Commits

Acreto Platform relies on a transactional model. Changes introduced to an ecosystem are not applied immediately; you need to commit them first.

Ecosystem status

Ecosystem object contains status field. You should avoid doing any changes to the ecosystem which is in status different than:

  • ok
  • pending_changes

executed, and you should re-check the status later. Another interesting status is commit_in_progress. It means commit is being

If the ecosystem gets into ecosystem_error status, please contact support.

Creating the Thing

Login to get access token

To retrieve access token, you need to send your username and password to /auth/login endpoint.

Request:

curl -X POST -H 'Content-type: application/json'  ${ENDPOINT}/auth/login -d "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}"  | jq .

Response:

{
  "accessToken": "bGciOiJIUzI1NiIsCI6IkpXVCJ9.aW5hbmNlX2FkbWlucy42NzQxNMuNjc0MTYzMmItYjMzNy00Y2QwLTNjYmMtNFRwSFRFSkJXS3giLCJ1c2VybmFtZSI6ImxrbGltZTBjMzYtZGU2NS1lZmwNjMifQ.YR72lsnOXcxj_1WSbyMh0",
  "customers": [
    {
      "name": "Documentation",
      "uuid": "6741632b-b337-4cd0-3cbc-e900e2c77fa3"
    }
  ]
}

Put the content of accessToken into TOKEN environment variable and customer uuid into CUSTOMERUUID environment variable for future reference.

TOKEN="bGciOiJIUzI1NiIsCI6IkpXVCJ9.aW5hbmNlX2FkbWlucy42NzQxNMuNjc0MTYzMmItYjMzNy00Y2QwLTNjYmMtNFRwSFRFSkJXS3giLCJ1c2VybmFtZSI6ImxrbGltZTBjMzYtZGU2NS1lZmwNjMifQ.YR72lsnOXcxj_1WSbyMh0"
CUSTOMERUUID="6741632b-b337-4cd0-3cbc-e900e2c77fa3"

List ecosystems and select the one to use

To list ecosystems owned by the customer, run GET requests against ecosystems endpoint.

Request:

curl -X GET -H 'Content-type: application/json' -H "Authorization: Bearer $TOKEN"  ${ENDPOINT}/customers/$CUSTOMERUUID/ecosystems|jq .

Response:

[
  {
    "created": "2020-09-30T10:24:00.000Z",
    "name": "Documentation Ecosystem",
    "nsps": [
      {
        "name": "EWR1",
        "status": "green"
      }
    ],
    "owner": {
      "fullName": "John Doe",
      "username": "someone@somedomain.com",
      "uuid": "5fdb6311-d058-0c36-de65-eff41e0ca063"
    },
    "status": "pending_changes",
    "uuid": "049d6701-a8d3-ca61-662e-3f6adbbd4156"
  }
]

Save ecosystem UUID into ECOSYSTEMUUID environment variable for future reference.

ECOSYSTEMUUID=049d6701-a8d3-ca61-662e-3f6adbbd4156

List Profile Groups

To create a Thing, we will need a Profile Group. Fortunately, first Profile Group is created automatically, so we just need to list them and get group UUID.

Request:

curl -X GET -H 'Content-type: application/json' -H "Authorization: Bearer $TOKEN"  ${ENDPOINT}/customers/$CUSTOMERUUID/ecosystems/$ECOSYSTEMUUID/groups|jq .

Response:

[
  {
    "name": "Profile Group 1",
    "uuid": "06f93ee9-3153-3111-8150-01b3d5389106"
  }
]

Save profile group UUID to GROUPUUID environment variable for future reference.

GROUPUUID="06f93ee9-3153-3111-8150-01b3d5389106"

Create a Thing

To create a Thing, we will send POST request to devices endpoint.

Request:

curl -X POST -H 'Content-type: application/json' -H "Authorization: Bearer $TOKEN" ${ENDPOINT}/customers/$CUSTOMERUUID/ecosystems/$ECOSYSTEMUUID/devices -d "{\"name\":\"My first Thing\", \"type\": \"device\",\"category\":\"IoT\",\"assetValue\":1, \"profileGroup\": \"$GROUPUUID\" }"

Response:

{
  "assetValue": 1,
  "category": "IoT",
  "expiry": {
    "time": "0001-01-01T00:00:00.000Z",
    "type": ""
  },
  "name": "My first Thing",
  "profileGroup": "06f93ee9-3153-3111-8150-01b3d5389106",
  "type": "device",
  "uuid": "c86c8910-1770-818b-a0c8-cf9d91201255"
}

Save Thing UUID to THINGUUID environment variable for future reference.

THINGUUID="c86c8910-1770-818b-a0c8-cf9d91201255"

Read the Thing

To ensure that the Thing was created successfully, we will try to read it.

Request:

curl -X GET -H 'Content-type: application/json' -H "Authorization: Bearer $TOKEN"  ${ENDPOINT}/customers/$CUSTOMERUUID/ecosystems/$ECOSYSTEMUUID/devices/$THINGUUID

Response:

{
  "assetValue": 1,
  "category": "IoT",
  "expiry": {
    "time": "0001-01-01T00:00:00.000Z",
    "type": ""
  },
  "name": "My first Thing",
  "profileGroup": "06f93ee9-3153-3111-8150-01b3d5389106",
  "type": "device",
  "uuid": "c86c8910-1770-818b-a0c8-cf9d91201255"
}

As you see, the Thing has been created successfully. To get it working, we need to commit our changes.

Commit changes

To commit changes, we’ll send an empty POST request to commits endpoint.

Request:

curl -X POST -H 'Content-type: application/json' -H "Authorization: Bearer $TOKEN"  ${ENDPOINT}/customers/$CUSTOMERUUID/ecosystems/$ECOSYSTEMUUID/commits

Response: none

Monitor ecosystem status to see commit progress

Now, we need to monitor status of the ecosystem to see when commit is done. For new ecosystems, it can take several minutes.

We’ll repeat a GET request to read the ecosystem in a loop, until ecosystem status changes from commit_in_progress to ok.

Request:

curl -X GET -H 'Content-type: application/json' -H "Authorization: Bearer $TOKEN"  ${ENDPOINT}/customers/$CUSTOMERUUID/ecosystems/$ECOSYSTEMUUID

Response:

{
  "created": "2020-09-30T10:24:00.000Z",
  "name": "Documentation Ecosystem",
  "nsps": [
    {
      "name": "EWR1",
      "status": "green"
    }
  ],
  "owner": {
    "fullName": "John Doe",
    "username": "someone@somedomain.com",
    "uuid": "5fdb6311-d058-0c36-de65-eff41e0ca063"
  },
  "status": "commit_in_progress",
  "uuid": "049d6701-a8d3-ca61-662e-3f6adbbd4156"
}

Summary

In this document, we went through a process of creating new Thing inside an ecosystem.

API Multi-Factor Authentication

Introduction

Overview

In this document, we will guide you through the Acreto Multi-Factor Authentication mechanism, as implemented in Acreto API for administrative needs.

Acreto’s Multi-Factor Authentication uses Time-based One-Time Passwords (TOTP) and was tested with the Google Authenticator app.

Acreto’s Multi-Factor Authentication consists of the following steps:

  1. initial configuration
  2. using two-factor authentication

Prerequisites

Before you start, you will need to:

Conventions

In this document, we follow conventions and use variables as defined in API Quick start.

TOTP initial configuration

To configure TOTP multi-factor authentication for a user, you need to follow the following process:

  1. Log in as the user
  2. Generate TOTP keys using POST ​/users​/{username}​/otp endpoint
  3. Add Acreto to your Google Authenticator by scanning generated QR code
  4. Activate multi-factor authentication by providing user-supplied verification code to PATCH ​/users​/{username}​/otp endpoint

Initial configuration example

Generate TOTP keys

Request:

curl -X 'POST' \
  'https://api-is-rock-solid.acreto.net/v2/users/user%40email.com/otp' \
  -H 'accept: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -d ''

Response:

{
  "barcode": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADIEAAAAADYoy0BAAAGYUlEQVR4nOyd0Y7bOgxEsxf5/1/uRQu4SAjRHF........rkJggg==",
  "secret": "P3YOQUQT1234O2S5FNDOAMMBM7NGFQKG",
  "url": "otpauth://totp/Acreto:user@domain.com?algorithm=SHA1&digits=6&issuer=Acreto&period=30&secret=P3YOQUQT1234O2S5FNDOAMMBM7NGFQKG"
}

Display QR code to the user

<html>
<body>
 <img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAMgAAADIEAAAAADYoy0BAAAGYUlEQVR4nOyd0Y7bOgxEsxf5/1/uRQu4SAjRHF........rkJggg==" />
</body>
</html>

Activate MFA using verification code

Request:

curl -X 'PATCH' \
  'https://dev-api-never-works.acreto.net/v2/users/user%40email.com/otp' \
  -H 'accept: application/json' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "123456"
}'

Response: HTTP status 204.

Using multi-factor authentication

To correctly support multi-factor authentication, your app needs to detect HTTP status code 424. Once such a code is received, the app should resend the failed request with an additional HTTP Header, X-OTP, containing TOTP code generated by the TOTP app (Google Authenticator).

Login without one-time password

Request:

curl -ik -X 'POST' \
  'https://dev-api-never-works.acreto.net/v2/auth/login' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "password": "******************",
  "username": "user@domain.com"
}'

Response (with headers):

HTTP/1.1 424 Failed Dependency
Content-Type: application/json
Vary: Origin
X-Request-Id: f4a12ef8-5134-c510-c409-b634ff4e4681
Date: Mon, 10 May 2021 16:31:58 GMT
Content-Length: 146

{"code":16432,"message":"This operation requires multi-factor authentication. Please retry with proper multi-factor authentication infromation."}

As you see, we got HTTP status 424. A request needs to be repeated with X-OTP header included.

Login with one-time password

Request:

curl -X 'POST'   'http://localhost:7010/v2/auth/login'   -H 'accept: application/json'   -H 'Content-Type: application/json' -H "X-OTP: 000000"  -d '{
  "password": "******************",
  "username": "user@domain.com"
}'

Response:

{
  "accessToken":"etgrevfdsr5byu57uj6t57uj657ub76yJh......HkShSxy9wUWMs3C_U5mOZq7vpIG7p73gMCpsDZthn90",
  "customers":
    [
      {"name":"Some Customer","uuid":"b7921abe-28e8-40aa-b527-00586e2ce3f1"},
      {"name":"Some Customer 2","uuid":"b7921abe-28e8-40aa-b527-00586e2ce3f1"}
    ],
  "expiry":600
}

VPN Connection Profile API

Introduction

Overview

In this document, we will describe how VPN connection profile configuration can be obtained from the Acreto Ecosystem using the API.

On a technical level, this process consists of the following steps:

  1. IT Admin geneates the device token
  2. IT Admin delivers the device token to the End-User through a secure channel, for example using invitation feature
  3. End-User downloads the VPN Connection Profile Configuration using the device token
  4. End-User uses downloaded VPN Connection Profile Configuration to establish sa ecure connection to Acreto Ecosystem

Prerequisites

Before you start, you will need to:

You should also complete the API Quick start.

Environment variables

All examples in this document are constructed as curl commands. For convenience, the following environment variables are used in these examples:

  • ENDPOINT=https://api-is-rock-solid.acreto.net/v2
  • TOKEN - access token retrieved from /auth/login endpoint
  • customer_uuid - ID of customer (organization) account
  • ecosystem_uuid - ID of the ecosystem to be used
  • DEVICE_TOKEN - device token is needed to obtain VPN connection profile
  • user_uuid - user identifier of the user for which we generate VPN connection profile, which can be retrieved from the GET ​/customers​/{customer_uuid}​/ecosystems​/{ecosystem_uuid}​/users endpoint
  • device_uid - Thing identifier of a thing for which we generate VPN connection profile; can be retrieved from the GET /customers/{customerUUID}/ecosystems/{ecosystemUUID}/devices endpoint

VPN Connection Profile Configuration format

VPN connection profile configuration is a valid OpenVPN config file, and can be used to establish an OpenVPN connection to the Ecosystem.

Things vs Users

Acreto Ecosystem allows the generation of 2 types of VPN connection profiles:

  • Thing, which is authenticated based on a secret key contained inside the VPN Connection Profile Configuration (“something you have” authentication factor)
  • User, which is authenticated based on username and password combination provided by the user during connection (“something you know” authentication factor)

Access and device tokens

Note there are two types of tokens: TOKEN, which is used to authenticate access requests and should be generated based on IT Admin’s username and password, and DEVICE_TOKEN, which can be shared with End Users and used only to download the VPN connection profile.

Device token generation

User

To generate a device token for a user, you should send a POST request to /customers/{customer_uuid}/ecosystems/{ecosystem_uuid}/users/{user_uuid}/token endpoint. This endpoint takes only one optional argument, which is time to live, (ttl) in seconds. If omitted, it will be set to a default value.

Note that ttl is subject to security policies within the Acreto platform, and it is not guaranteed that generated token will have ttl provided in the request. We recommend omitting this parameter and using the default value.

Request:

curl -X POST -d '{}' -H 'Content-type: application/json' -H "Authorization: Bearer $TOKEN"  ${ENDPOINT}/customers/${customer_uuid}/ecosystems/${ecosystem_uuid}/users/${user_uuid}/token|jq .

Response:

{"token":"s.iibxqytafX1YvSRk9q7HSaYE"}

Save the value of “token” key into DEVICE_TOKEN variable for future reference:

DEVICE_TOKEN="s.iibxqytafX1YvSRk9q7HSaYE"

Thing

To generate a device token for a Thing, you should send a POST request to /customers/{customer_uuid}/ecosystems/{ecosystem_uuid}/devices/{device_uuid}/token endpoint. This endpoint takes only one optional argument, which is time to live, (ttl) in seconds. If omitted, it will be set to a default value.

Note that ttl is subject to security policies within the Acreto platform, and it is not guaranteed that generated token will have ttl provided in the request. We recommend omitting this parameter and using the default value.

Request:

curl -X POST -d '{}' -H 'Content-type: application/json' -H "Authorization: Bearer $TOKEN"  ${ENDPOINT}/customers/${customer_uuid}/ecosystems/${ecosystem_uuid}/devices/${device_uuid}/token|jq .

Response:

{"token":"s.iibxqytafX1YvSRk9q7HSaYE"}

Save the value of “token” key into DEVICE_TOKEN variable for future reference:

DEVICE_TOKEN="s.iibxqytafX1YvSRk9q7HSaYE"

Retrieve VPN Connection Profile Configuration

To retrieve VPN Connection Profile configuration, End-User should send GET request to endpoint /tlsvpn/config/{platform}?_token={DEVICE_TOKEN}. {platform} should be openvpn-udp (other options are not implemented at the time of writing).

Request:

curl ${ENDPOINT}/tlsvpn/config/openvpn-udp?_token=${DEVICE_TOKEN}

Response:

In response, VPN Connection Profile Configuration is returned as a file of type application/x-openvpn-profile.

Note that the End-User should correctly detect and interpret error codes; in particular, if the DEVICE_TOKEN is invalid or expired, the request will return HTTP 403 status.

Summary

In this document, we went through the process of retrieving VPN Connection Profile Configuration from Acreto API.