> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.itential.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.itential.com/_mcp/server.

# Two-step token authentication

> How to configure two-step token authentication in an adapter, covering both the service instance configuration and the .system endpoint configuration.

Two-step token authentication is one of the most common API authentication methods. The adapter sends credentials in an initial request and receives a token, which it then uses in all subsequent requests.

In standard two-step token authentication:

1. A username and password are sent in the body of an initial token request.
2. The external system authenticates the credentials and returns a token in the response body.
3. The token is placed in a header field on all subsequent requests.

## Configure the service instance configuration

Two-step token authentication requires changes in two places: theItential Platform service instance configuration and the adapter's endpoint configuration in the `.system` entity. This section covers the service instance configuration.

The relevant properties are in the `authentication` section of theItential Platform service instance configuration for the adapter, accessible throughItential Platform Admin Essentials. For a full description of all authentication properties, see [Service instance configuration](/adapters/configure/service-instance-configuration/properties/overview).

| Property              | Description                                                                                                                                                                                                   |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `auth_method`         | Set to `"request_token"`. Provide the username and password in their respective properties. The `password` field can be encrypted using Itential Platform's encryption.                                       |
| `auth_field`          | The location where the token is placed on **subsequent requests** — not the initial token request. Headers are the most common placement. For the `Authorization` header, use `header.headers.Authorization`. |
| `auth_field_format`   | The format of the token on **subsequent requests** — not the initial token request. Use `{token}` as the variable.                                                                                            |
| `token_timeout`       | How long the token is valid, in milliseconds. Setting this prevents the adapter from performing the two-step exchange on every call.                                                                          |
| `token_cache`         | Set to `local`. The adapter caches the token in memory.                                                                                                                                                       |
| `invalid_token_error` | The HTTP error code the external system returns when the token is invalid (typically `401`). When this error is received, the adapter automatically requests a new token and retries the original call.       |

### Example

```json
"authentication": {
  "auth_method": "request_token",
  "username": "systemuser",
  "password": "systempassword",
  "token_timeout": 180000,
  "token_cache": "local",
  "invalid_token_error": 401,
  "auth_field": "header.headers.Authorization",
  "auth_field_format": "{token}"
}
```

## Configure the endpoint configuration

The endpoint configuration for the adapter is located at `/adapter-home-dir/entities/.system`. This directory contains the `action.json` file and the request and response schema files that define how the adapter acquires a token.

### action.json

The `action.json` file tells the adapter library how to make the token request.

| Property           | Description                                                                                                                                                                                        |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`             | Must be `getToken`.                                                                                                                                                                                |
| `protocol`         | Always `REST`.                                                                                                                                                                                     |
| `method`           | The HTTP method for the token request — typically `POST` or `GET`.                                                                                                                                 |
| `entitypath`       | The path for the token request. Supports global adapter variables such as `{base_path}` and `{version}`.                                                                                           |
| `requestSchema`    | Relative path to the request schema file.                                                                                                                                                          |
| `responseSchema`   | Relative path to the response schema file.                                                                                                                                                         |
| `timeout`          | Optional timeout override for this call, if different from the global `attempt_timeout`.                                                                                                           |
| `sendEmpty`        | Whether to send a body when there is no data to include.                                                                                                                                           |
| `requestDatatype`  | How data is sent to the external system. Common values: `JSON`, `URLENCODE`.                                                                                                                       |
| `responseDatatype` | How data is returned to the adapter. Common values: `JSON`, `PLAIN`.                                                                                                                               |
| `headers`          | Additional headers to include with the token request. Can also override automatic adapter headers.                                                                                                 |
| `sso`              | An alternate host to authenticate against. Provide `protocol`, `host`, and `port` when authentication is handled by a different server than the one defined in the service instance configuration. |
| `responseObjects`  | How to handle the token response and where to find mock data for stub mode.                                                                                                                        |

```json
{
  "name": "getToken",
  "protocol": "REST",
  "method": "POST",
  "entitypath": "/api/{version}/authentication/signin",
  "requestSchema": "schemaTokenReq.json",
  "responseSchema": "schemaTokenResp.json",
  "timeout": 0,
  "sendEmpty": false,
  "requestDatatype": "JSON",
  "responseDatatype": "JSON",
  "headers": {
    "Accept": "*/*"
  },
  "sso": {
    "protocol": "",
    "host": "",
    "port": 0
  },
  "responseObjects": [
    {
      "type": "default",
      "key": "",
      "mockFile": "mockdatafiles/gettoken.json"
    }
  ]
}
```

### Request schema

The request schema (`schemaTokenReq.json`) defines the data sent in the token request. Most fields should remain unchanged. The fields most commonly modified are:

| Property        | Description                                                                                                                                                                                                        |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `translate`     | Set to `true` whenever field names need to be translated (for example, `username` → `user`).                                                                                                                       |
| `dynamicfields` | Set to `true` to allow fields not defined in the schema to be included in the request.                                                                                                                             |
| `username`      | Maps to the `username` in the service instance configuration. Do not change the property name. Change only `external_name` to match what the external system expects (common values: `username`, `user`, `login`). |
| `password`      | Maps to the `password` in the service instance configuration. Do not change the property name. Change only `external_name` to match what the external system expects (common values: `password`, `passwd`, `pwd`). |

You can also add `client_id`, `client_secret`, and `grant_type` fields following the same pattern as `username` and `password`. Additional static fields with default values can also be added to send fixed data with every token request.

```json
{
  "$id": "reqTokenSchema.json",
  "type": "object",
  "schema": "http://json-schema.org/draft-07/schema#",
  "translate": true,
  "dynamicfields": true,
  "properties": {
    "ph_request_type": {
      "type": "string",
      "description": "type of request (internal to adapter)",
      "default": "getToken",
      "enum": ["getToken", "healthcheck"],
      "external_name": "ph_request_type"
    },
    "username": {
      "type": "string",
      "description": "username to log in with",
      "external_name": "user"
    },
    "password": {
      "type": "string",
      "description": "password to log in with",
      "external_name": "passwd"
    }
  },
  "definitions": {}
}
```

### Response schema

The response schema (`schemaTokenResp.json`) defines the data extracted from the token response. Most fields should remain unchanged. The fields most commonly modified are:

| Property        | Description                                                                                                                                                         |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `translate`     | Set to `true` whenever field names need to be translated (for example, `access_token` → `token`).                                                                   |
| `dynamicfields` | Set to `true` to allow fields not defined in the schema to be included.                                                                                             |
| `token`         | Defines where the token is found in the response. Change `external_name` to match the field name the external system uses (common values: `token`, `access_token`). |
| `tokenp2`       | Defines where a secondary value is found in the response, when needed. Change `external_name` to match the field name (common values: `session_id`).                |

```json
{
  "$id": "respTokenSchema.json",
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "translate": true,
  "properties": {
    "ph_request_type": {
      "type": "string",
      "description": "type of request (internal to adapter)",
      "default": "getToken",
      "enum": ["getToken"],
      "external_name": "ph_request_type"
    },
    "token": {
      "type": "string",
      "description": "the token returned from the system",
      "external_name": "access_token"
    }
  },
  "definitions": {}
}
```

## Variations

Two-step token has many variations. The following table describes common options and how to configure them.

| Variation                               | Configuration                                                                                                    |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Token in a different header field       | Set `auth_field` to `"header.headers.X-AUTH-TOKEN"`.                                                             |
| Token in the URL path (before the `?`)  | Set `auth_field` to `"urlpath"`.                                                                                 |
| Token in the URL query (after the `?`)  | Set `auth_field` to `"url"`.                                                                                     |
| Token in the request body               | Set `auth_field` to `"body.field"`.                                                                              |
| Different token format                  | Set `auth_field_format` to `"{token}"` or `"Bearer {token}"`.                                                    |
| Different token lifetime                | Adjust `token_timeout` to the appropriate value in milliseconds.                                                 |
| URL-encoded token request               | Set `requestDatatype` to `URLENCODE`. Supported values: `JSON`, `XML`, `PLAIN`, `FORM`, `URLENCODE`, `URLQUERY`. |
| Non-JSON token response                 | Set `responseDatatype` to the appropriate value. Supported values: `JSON`, `XML`, `PLAIN`, `XML2JSON`.           |
| Field names differ from defaults        | Update `external_name` in `schemaTokenReq.json` or `schemaTokenResp.json`.                                       |
| Override default headers                | Specify header overrides in the `headers` object of `action.json`, for example `"Accept": "*/*"`.                |
| Authenticate against a different server | Populate the `sso` object in `action.json` with the `protocol`, `host`, and `port` of the authentication server. |

### Example: token in a custom header with URL-encoded request and SSO server

**Service instance configuration**

```json
"authentication": {
  "auth_method": "request_token",
  "username": "systemuser",
  "password": "systempassword",
  "token_timeout": 3600000,
  "token_cache": "local",
  "invalid_token_error": 401,
  "auth_field": "header.headers.X-AUTH-TOKEN",
  "auth_field_format": "Bearer {token}"
}
```

**action.json**

```json
{
  "name": "getToken",
  "protocol": "REST",
  "method": "POST",
  "entitypath": "/api/{version}/authentication/signin",
  "requestSchema": "schemaTokenReq.json",
  "responseSchema": "schemaTokenResp.json",
  "timeout": 0,
  "sendEmpty": false,
  "requestDatatype": "URLENCODE",
  "responseDatatype": "PLAIN",
  "headers": {
    "Accept": "*/*"
  },
  "sso": {
    "protocol": "https",
    "host": "DNSname or IP",
    "port": 443
  },
  "responseObjects": [
    {
      "type": "default",
      "key": "",
      "mockFile": "mockdatafiles/gettoken.json"
    }
  ]
}
```