Service Account Quick Start

A tutorial to teach users to connect to Chassi API Endpoints using OAuth 2.0 and Service Accounts.

Service Accounts

Chassi APIs are secured using the OAuth 2.0 protocol for authentication and authorization, which requires a valid OAuth access token to be provided when making API requests.

Chassi supports the common OAuth 2.0 authentication scenarios, and in particular, the Client Credentials Grant which enables machine-to-machine communication when you want to invoke an API request from non-interactive applications (a CLI, IoT device, a daemon, or a Service running on your backend) where the token is issued to the application itself, instead of an end user.

A unique Service Account will be assigned for your Experiment Tenant as well as your Production Tenant, if you have one.

📘

Getting a Service Account

In the Chassi Early Access Program, we are manually distributing Service Accounts to customers. If you do not have a Service Account to connect to the Chassi APIs for your Experiment Tenant or your Production Tenant, contact your Chassi Sales Representative. Once the Early Access Program ends, you will be able to generate your own Service Accounts freely from the API Manager.

The Service Account provides the unique client ID and client secret credentials needed to make the authorization grant request for an OAuth 2.0 access token.

OAuth 2.0 access tokens are more secure than plain API keys since an access token has a much smaller lifespan and must be renewed periodically. Think of it as a rotating API key. This ensures that tokens cannot be passed around like can happen with plain API keys. The client secret, which is contained in the Service Account, can also be regenerated as needed.

❗️

The Service Account is Secret

Keep the Service Account and its information secret, because it contains the confidential information needed in order to access your API. Do not store the Service Account in Git or other unsecured mechanisms. Only store it in secure key stores or other security mechanisms where the contents of the Service Account cannot be exposed without a security challenge. Consider using technology like Hashicorp Vault to store API credentials for your application.

API Request Flow

Before you begin, you will need a Service Account for either your Experiment Tenant or your Production Tenant. Using the information contained in the Service Account, as shown in Figure 1 below, your Service Application requests an access token from the Chassi Auth Endpoint, then the Service Application extracts the token from the response, and includes the access token to the Chassi API Endpoint that you want to request as part of the HTTP header.

1050

Chassi API Request Flow (Figure 1)

📘

Best Practice Notice

Given the security implications of getting the implementation correct, we strongly encourage you to use open source OAuth 2.0 libraries for your programming language when interacting with Chassi's OAuth 2.0 endpoints. It is a best practice to use the well-debugged code provided by others, and it will help you protect yourself and your users. When selecting open source software, always verify that it fulfills your feature requirements, that you have the skillset to evaluate and use the code, it has a strong community supporting the project, there is help if you need it, has good documentation, has a good reputation for being secure, and finally, it has a license that meets your requirements. [Search: Key Considerations for Selecting Open Source Software]

Steps to Authenticate

All applications follow a basic pattern when accessing a Chassi API Endpoint using an OAuth 2.0 access token. At a high level, you follow four steps:

1. Obtain OAuth 2.0 Credentials from an Assigned Chassi Service Account.

A typical Chassi Service Account contains the following information and provides the client id and client secret credentials used to request an access token which is valid for a specific Operational Space and its associated Definitional Space.

[{
  "id" : "335324e7-96e1-4c27-8b32-e5a79a926568",
  "clientId" : "1550099831-production.ahd-8pw-rtu-5jk.chassi.api.chassi.com",
  "clientSecret" : "76d37e06-7ca9-4ab7-8b60-4c11d7eab192",
  "description" : "Customer Tenant Prod Service Account",
  "enabled" : true,
  "tokenEndpoint" : "https://auth.chassi.com/auth/realms/ahd-8pw-rtu-5jk/protocol/openid-connect/token",
  "scopedRoles" : {
    "dab0b816-f6f1-4fcf-93f2-731358750b50" : [ "user.basic-user" ],
    "54f69128-0301-483b-9dac-e3ec57ea07d7" : [ "user.basic-user" ]
}]

Service Accounts cannot be shared across Operational Spaces. However, each Service Account can always access the Tenant Application's Definitional Space. For example, if you had two Operational Spaces called "Stage" and "Production", you would use one Service Account to access your "Production" Operational Space and another Service Account to access your "Stage" Operational Space. Both Service Accounts would be able to access the Definitional Space since this access is built into every Service Account by default.

You can easily identify which Tenant and Operational Space a Service Account is for by looking at the clientId in the Service Account. The value is in the format of tenantId:appSpaceName:random. Additionally, in the scopedRoles section of the Service Account, each of the keys contains the appSpaceId as a UUID of each Application Space the Service Account is set up to access. One of the UUIDs will be for the Operational Space, and the other for the Definitional Space. If you're not sure which UUID belongs to which Application Space, you can switch to your Tenant in the Chassi UI and open the info modal for each of your Application Spaces in IAM and Admin.

Notice the tokenEndpoint in the Service Account and realize that each Tenant will have a unique URI to get an access token.

2. Obtain an Access Token from the Chassi Authorization Endpoint.

Before your application can access your private data using a Chassi API Endpoint, it must obtain an access token that grants access to that API. A single access token can grant varying degrees of access to multiple APIs depending on the associated scope of permissions.

To request an access token, perform a POST operation to the token endpoint specified by the Service Account with a payload in the following format ( using cURL example ):

curl --request POST \
    -d "grant_type=client_credentials"  \
    -d "client_id=1550099831-production.ahd-8pw-rtu-5jk.chassi.api.chassi.com" \
    -d "client_secret=76d37e06-7ca9-4ab7-8b60-4c11d7eab192" \
    https://auth.chassi.com/auth/realms/ahd-8pw-rtu-5jk/protocol/openid-connect/token

If the Chassi Auth endpoint grants the requests, then an access token is returned to your application. If the request is not granted, then the server returns an error.

A successful response looks something like the following and contains an access token access_token (which is a signed JSON Web Token), the token's type token_type (which is Bearer), and in how much time it expires expires_in in Unix time (86400 seconds, which means 24 hours). The refresh token can be ignored because it is not needed for the client credentials grant, which is the type of grant the Service Account uses.

{
  "access_token":"eyJz93a...k4laUWw",
  "token_type":"bearer",
  "expires_in":300,
  "not-before-policy":1542782681,
  "refresh_expires_in":1200,
  "refresh_token":"dfJk54b...d6maYWw"
}

3. Include the Access Token with every Chassi API Endpoint Request

After an application obtains an access token, it includes the token with each request to a Chassi API Endpoint as an HTTP authorization header.

curl --request GET \
 -H "Content-Type: application/json"
 -H "Authorization: Bearer eyJz93a...k4laUWw" \
 https://ahd-8pw-rtu-5jk.api.chassi.com/dab0b816-f6f1-4fcf-93f2-731358750b50/lifecycle/1/lifecycles

📘

Best Practice Notice

It is possible to send OAuth 2.0 tokens as URI query-string parameters, but we don't recommend it, because URI parameters can end up in log files that are not completely secure. Also, it is good REST practice to avoid creating unnecessary URI parameter names.

If the access token is valid and is scoped for the requested application space and API endpoint, then the API will return the requested data. If the access token is expired or invalid, then an error will be returned.

Access tokens are valid only for the application space identifiers and permissions described in the scopedRoles section of the Service Account data. However, the same access token can be used multiple times for similar API requests until the token expires.

4. Refresh the Access Token, When Necessary

Access tokens have limited lifetimes typically only five minutes. If your application needs access to a Chassi API beyond the lifetime of a single access token, then this process should be repeated to request a new access token.

🚧

Prepare for Token Expiration

You must write your code to anticipate the possibility that a granted token might no longer work. A token will no longer work if it expires or if the client secret has been changed. Your application should have an expected result when the API Endpoint cannot authenticate properly, or even in a severe case where the Chassi API Endpoint is not available due to a network hop being down outside the control of you or Chassi.

📘

Best Practice Notice

It is very important that you refresh the token only when needed, instead of for every request. Refreshing every request would result in twice the amount of latency because you would be making two calls for every API transaction. Every request to Chassi is metered, including authentication requests. Calling the API excessively may result in a higher bill at the end of your billing cycle than it could otherwise be.