Knowledge Article
Best practice: Using personal access tokens in IdentityNow
Author
neil_mcglennon
SailPoint
Overview
As we describe in our IdentityNow REST API Authentication guide, if you are writing any sort of scripts or programs that leverage the IdentityNow APIs, which OAuth 2.0 grant from you should use typically depends on what you are doing, and which user context you need in order to operate under.
Because scripts, code, or programs do not have an interactive web-interface it is difficult (but not impossible) to implement a working authorization code flow. Because of this, most scripts or programs typically run as a client credential grant flow.
If your APIs can work under and API context without a user, then leveraging a client credential grant flow using an OAuth client credentials is ideal. However, if your APIs need a user or admin context, then leveraging a client credential grant flow using Personal Access Token credentials is more apt for your usage.
What is a Personal Access Token?
The easiest way to think of a personal access token, is a special OAuth 2.0 client credential tied to a specific user, which as such it gives the same context as the user, without having to give out that user's credentials.
The best way to illustrate the difference is to look at the difference between calling the client credential flow with a personal access token vs a normal OAuth 2.0 client credential.
If you were to call the client credential grant with a personal access token, you would get a JWT access token, which once decoded, might look like this:
{
"tenant_id": "58eb06a4-dcd7-4e96-8fac-cca2afc03e61",
"pod": "stg01-useast1",
"org": "example",
"identity_id": "ff80818155fe8c080155fe8d925b0316",
"user_name": "slpt.services",
"scope": [
"read",
"write"
],
"strong_auth": true,
"exp": 1574236847,
"authorities": [
"ORG_ADMIN"
],
"jti": "d5b1a59a-9de5-439a-9a0c-5eec0e2e1d78",
"client_id": "550e2d8644e04beabaf860bf1cfd7b2a"
}
In this token, notice how there is an identity_id and user_name specified, and the authorities reflects the permissions of that identity. In this case, the identity / user is an administrator, who can configure IdentityNow.
As a comparison, if you were to call the client credential grant with a normal OAuth 2.0 client credential, your JWT access token, which once decoded, might look like this:
{
"accessType": "OFFLINE",
"tenant_id": "58eb06a4-dcd7-4e96-8fac-cca2afc03e61",
"internal": false,
"pod": "stg01-useast1",
"strong_auth_supported": false,
"org": "example",
"scope": [
"read",
"write"
],
"exp": 1574194160,
"authorities": [
"API"
],
"jti": "cb86ad7e-ac6a-4bfb-b52e-85e889cb56d3",
"enabled": true,
"client_id": "fcc0ddbb-105c-4cd7-b95e-0276cbe45b90"
}
Here you can see that there is no identity_id and user_name specified, and the authorities reflects this as an API user.
Now you may be thinking, why does this matter?
Most REST APIs have requirements - either from authorities, or that they must be operated as a user - under a user's context. For example, access request REST APIs assume that they are operating from a certain person or requester. As another example, some adminsitrative APIs require both a user context (for auditing) and an administrative authority.
Some OAuth 2.0 grant types, like authorization code, do in fact grant a user context. Because scripts, code, or programs do not have an interactive web-interface it is difficult (but not impossible) to implement a working authorization code flow. Because of this, most scripts or programs typically run as a client credential grant flow.
So, if you need a client credential grant flow for your script or code, and want to run this in a user's context, then using personal access tokens is a perfect fit.
Creating a Personal Access Token
A personal access token is a one-time generated token. It can then be used in configurations, in lieu of a password, to operate in a user's context.
To generate a personal access token using the IdentityNow UI, refer to the online help for Managing personal access tokens.
To generate a personal access token using the REST API, refer to the corresponding API documentation.
An example call might look like this:
curl -X POST \
https://example.api.identitynow.com/beta/personal-access-tokens \
-H 'Authorization: Bearer eyJh...dJ94' \
-H 'Content-Type: application/json' \
-H 'cache-control: no-cache' \
-d '{
"name": "My Integration"
}'
If successful, a JSON object representing the created Personal Access Token object will be given as a response. For example:
- HTTP 201 Created
- Content-Type: application/json
{
"id": "86f1dc6fe8f54414950454cbb11278fa",
"name": "My Integration",
"secret": "d2be94f1fb61d0a1c63fa78ba941776e21ac6b674808db24d6426839ed758091",
"created": "2019-11-11T21:04:38.203Z",
"owner": {
"type": "IDENTITY",
"id": "ff80818155fe8c080155fe8d925b0316",
"name": "slpt.services"
}
}
NOTE: This is the only time the Personal Access Tokens' secret attribute will be displayed. Take note for future use.
Once we have the Personal Access Token's id and secret value, we can leverage those in a standard OAuth 2.0 client credential grant flow.
Authentication with Personal Access Tokens
As mentioned above, once we have the Personal Access Token's id and secret value, we can leverage those in a standard OAuth 2.0 client credential grant flow.
Further Reading: https://oauth.net/2/grant-types/client-credentials/
This grant type is used by clients to obtain an access token outside the context of a user. This is probably the simplest authentication flow.
The overall authorization flow looks like this:
- The client submits an OAuth 2.0 Token Request to IdentityNow in the form:
POST https://{tenant}.api.identitynow.com/oauth/token?grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}
- IdentityNow validates the token request and submits a response. If successful, the response will contain a JWT access token as indicated in the Token Response section.
The query parameters for in the OAuth 2.0 Token Request for the Client Credential grant are as follows:
Key | Description |
grant_type | Set to |
client_id | This is the Personal Access Token's |
client_secret | This is the Personal Access Token's |
Here is an example call OAuth 2.0 Token Request for the Client Credential grant, using a personal access token.
curl -X POST \
'https://example.api.identitynow.com/oauth/token?grant_type=client_credentials&client_id=86f1dc6fe8f54414950454cbb11278fa&client_secret=d2be94f1fb61d0a1c63fa78ba941776e21ac6b674808db24d6426839ed758091' \
-H 'cache-control: no-cache'
If successful, the response you get back will contain an access_token.
The access_token contains the JSON Web Token which is subsequently used in any further REST API calls through the IdentityNow API gateway. To use this access token simply include it in an authorization header as a bearer token. For example:
curl -X GET \
'https://example.api.identitynow.com/beta/accounts' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRfaWQiOiI1OGViMDZhNC1kY2Q3LTRlOTYtOGZhYy1jY2EyYWZjMDNlNjEiLCJpbnRlcm5hbCI6ZmFsc2UsInBvZCI6ImNvb2siLCJvcmciOiJuZWlsLXRlc3QiLCJpZGVudGl0eV9pZCI6ImZmODA4MTgxNTVmZThjMDgwMTU1ZmU4ZDkyNWIwMzE2IiwidXNlcl9uYW1lIjoic2xwdC5zZXJ2aWNlcyIsInN0cm9uZ19hdXRoIjp0cnVlLCJhdXRob3JpdGllcyI6WyJPUkdfQURNSU4iXSwiZW5hYmxlZCI6dHJ1ZSwiY2xpZW50X2lkIjoiZmNjMGRkYmItMTA1Yy00Y2Q3LWI5NWUtMDI3NmNiZTQ1YjkwIiwiYWNjZXNzVHlwZSI6Ik9GRkxJTkUiLCJzdHJvbmdfYXV0aF9zdXBwb3J0ZWQiOmZhbHNlLCJ1c2VyX2lkIjoiNTk1ODI2Iiwic2NvcGUiOlsicmVhZCIsIndyaXRlIl0sImV4cCI6MTU2NTg5MTA2MywianRpIjoiOTQ5OWIyOTktOTVmYS00N2ZiLTgxNWMtODVkNWY2YjQzZTg2In0.zJYfjIladuGHoLXr92EOJ3A9qGNkiG5UJ9eqrtSYXAQ' \
-H 'cache-control: no-cache'
Important Security Considerations
As a final note, while the Personal Access Tokens are very convenient, it is important to realize that these can effectively act as a user in IdentityNow REST APIs. Treat these Personal Access Tokens as if they were passwords. Do not share them, keep them in a safe place, and have a policy to rotate these every so often. Good security practice is still essential.