> 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.

# Advanced authentication

> An introduction to complex adapter authentication scenarios that use two-step token flows with custom configurations.

Most complex authentication scenarios can be handled by modifying one or more of the following:

* The `authentication` section of theItential Platform service instance configuration inItential Platform Admin Essentials
* The endpoint configuration at `/adapter-home-dir/entities/.system`, including `action.json` and the token request and response schemas
* `callProperties` in the `reqObj` within `adapter.js`

The pages in this section cover complex two-step token scenarios — cases where a token is retrieved in an initial request and then used in subsequent calls. Some of these patterns are more common than others, but each demonstrates how to extend or modify the standard flow to support different authentication requirements.

Some authentication methods are not yet supported by the adapter libraries. If you encounter a method that is not covered here, contact the Itential Adapters Team for assistance.

## Flexible authentication

Adapter authentication is highly flexible. You can customize it at several levels, depending on what the external system requires.

**Service instance configuration** (IAP Admin Essentials, `authentication` section):

* Authentication type
* Credentials
* Token expiration
* Format of auth data on outbound requests

**Endpoint configuration** (`/adapter-home-dir/entities/.system`):

* The `getToken` action in `action.json`
* Token request and response schemas

**Code-level changes in `adapter.js`**:

* Pass `authData` or `callProperties` on a per-call basis
* Implement custom authentication logic for scenarios the adapter library does not support

For example, one system required a secret to be passed through SHA-1 with HMAC. This was achieved by adding SHA-1/HMAC calls to `adapter.js` and setting additional request headers using adapter properties — without any changes to the adapter library.

## Custom authentication

If the external system requires an authentication method that the adapter libraries do not support, you have two options:

* **Request a library change.** Contact the Adapter Team to ask if the method can be added to the adapter library. This is the preferred path when possible.
* **Implement custom authentication in `adapter.js`.** When a library change is not possible, or you need a faster solution, you can add authentication logic directly to `adapter.js`.

The `adapter.js` file has access to all service instance configuration settings through `this.allProps`. For example, to read the username from the authentication section, use `this.allProps.authentication.username`.

## Recommended pattern

The recommended approach is to add a `getAuthorization` method that encapsulates the full authentication process and makes the actual request to the external system. All other adapter methods then delegate to `getAuthorization` rather than handling authentication themselves. This isolates authentication logic and minimizes the number of places that need to change if the authentication method evolves.

## Configuration

### adapter.js

Make the following changes:

1. Add `getAuthorization` to the `myIgnore` array inside `iapGetAdapterWorkflowFunctions` so it is excluded from unit test coverage checks.
2. Implement the `getAuthorization` method. It should accept the entity, action, request object, translate flag, and any data needed for authentication. Inside the method, make the authentication call, assign the resulting auth data to the request object's headers, and then make the actual API call.
3. Replace the request logic in all adapter methods with a call to `getAuthorization`.
4. Update `genericAdapterRequests` the same way, or those requests will fail due to missing authentication.

```javascript
iapGetAdapterWorkflowFunctions(inIgnore) {
  let myIgnore = [
    'healthCheck',
    'iapGetAdapterWorkflowFunctions',
    'iapHasAdapterEntity',
    'iapVerifyAdapterCapability',
    'iapUpdateAdapterEntityCache',
    'hasEntities',
    'getAuthorization'
  ];

  // ...
}

// getAuthorization authenticates, updates the request object, and makes the call.
getAuthorization(entity, action, requestObj, translate, dataNeedForAuth, callback) {

  return this.requestHandlerInst.identifyRequest('Auth', 'login', dataNeedForAuth, translate, (authData, authError) => {

    // Assign auth data to the request headers
    Object.assign(requestObj.addlHeaders, authData);

    // Make the actual API call with auth applied
    return this.requestHandlerInst.identifyRequest(entity, action, requestObj, translate, callback);

  // ...
}

// Example: calling getAuthorization from an adapter method
return this.getAuthorization(
  'Bucket',
  'abortMultipartUpload',
  reqObj,
  true,
  {
    username: this.allProps.authentication.username,
    password: this.allProps.authentication.password
  },
  (irReturnData, irReturnError) => {
    // handle response
  }
);
```