Migrate to Management API Endpoints with Access Tokens
Using ID tokens to call Management API endpoints is being deprecated. You must use access tokens. The grace period for this migration started on March 31, 2018.
After you complete your migration to access tokens, turn off the Allow ID Tokens for Management API v2 Authentication toggle in the Dashboard.
If you use ID tokens to call any of the following endpoints, then you are affected by this migration. These endpoints can now accept regular access tokens. Nothing else changes in how the endpoints work. You should expect the same request and response schemas and only need to update the token that you use for authorization.
Endpoints affected
Endpoint | Use Case |
---|---|
GET /api/v2/users/{id} | Retrieve a user's information |
GET /api/v2/users/{id}/enrollments | Retrieve all Guardian MFA enrollments for a user |
PATCH /api/v2/users/{id} | Update a user's information |
DELETE /api/v2/users/{id}/multifactor/{provider} | Delete the MFA provider settings for a user |
POST /api/v2/device-credentials | Create a public key for a device |
DELETE /api/v2/device-credentials/{id} | Delete a device credential |
POST/api/v2/users/{id}/identities | Link user accounts from various identity providers |
DELETE /api/v2/users/{id}/identities/{provider}/{user_id} | Unlink user accounts |
Actions
Scope changes
The actions you can perform with the Management API depend on the scopes that your access token contains. With this migration, you can either get a limited access token that can update only the logged-in user's data or an access token that can update the data of any user. In the following matrix, you can see the scopes that your token needs to have per case and per endpoint.
For example, if you get an access token that contains the scope read:users
, you can retrieve the data of any user using the GET /api/v2/users/{id}
endpoint. However, if your token contains the scope read:current_user
, you can only retrieve the information of the currently logged-in user (the one that the token was issued for).
Endpoint | Scope for current user | Scope for any user |
---|---|---|
GET /api/v2/users/{id} | read:current_user |
read:users |
GET /api/v2/users/{id}/enrollments | read:current_user |
read:users |
POST/api/v2/users/{id}/identities | update:current_user_identities |
update:users |
DELETE /api/v2/users/{id}/identities/{provider}/{user_id} | update:current_user_identities |
update:users |
PATCH /api/v2/users/{id} | update:current_user_metadata |
update:users |
PATCH /api/v2/users/{id} | create:current_user_metadata |
update:users |
DELETE /api/v2/users/{id}/multifactor/{provider} | delete:current_user_metadata |
update:users |
POST /api/v2/device-credentials | create:current_user_device_credentials |
create:device_credentials |
DELETE /api/v2/device-credentials/{id} | delete:current_user_device_credentials |
delete:device_credentials |
Get access tokens
Auth0 has changed how you get a token for the previously mentioned endpoints. There are several variations on how you authenticate a user and get tokens, depending on the technology and the OAuth 2.0 flow you use to authenticate:
SPA running in a browser: Use the Authorization endpoint.
Web app running on a server, a mobile app, a server process, or a highly trusted app: Use the Token endpoint.
Cross-authentication: Use embedded Lock or auth0.js to authenticate users when the requests come from different domains.
Authorization endpoint
In this section, we will use an example to show the differences in how you get a token with the Authorization endpoint. Keep in mind that no matter which endpoint you want to migrate, the changes are the same, the only thing that differs is the scopes that you specify in the request.
In the example below, you use the GET User by ID
endpoint to retrieve the full profile information of the logged-in user. To do so, first, we will authenticate the user using the Implicit grant and retrieve the token(s). Below you can see an implementation of the old approach that gets an ID Token and then uses it to call the endpoint.
https://{yourDomain}/authorize?
scope=openid
&response_type=id_token
&client_id={yourClientId}
&redirect_uri=https://{yourApp}/callback
&nonce={nonce}
&state={opaqueValue}
Was this helpful?
In the example below, you can see the new approach that gets an access token.
https://{yourDomain}/authorize?
audience=https://{yourDomain}/api/v2/
&scope=read:current_user
&response_type=token%20id_token
&client_id={yourClientId}
&redirect_uri=https://{yourApp}/callback
&nonce={nonce}
&state={opaqueValue}
Was this helpful?
To get an access token that can access the Management API:
Set the
audience
tohttps://{yourDomain}/api/v2/
Ask for the scope
${scope}
Set the
response_type
toid_token token
so Auth0 will send both an ID token and an access token
If you decode the received access token and review its contents you will see the following:
{
"iss": "https://{yourDomain}/",
"sub": "auth0|5a620d29a840170a9ef43672",
"aud": "https://{yourDomain}/api/v2/",
"iat": 1521031317,
"exp": 1521038517,
"azp": "{yourClientId}",
"scope": "${scope}"
}
Was this helpful?
Notice that aud
is set to your tenant's API URI, scope
is set to ${scope}
, and sub
is set to the user ID of the logged-in user.
Once you have the access token you can use it to call the endpoint. This part remains the same, nothing else changes in the request except for the value you use as Bearer
token. The response remains also the same.
Token endpoint
In this section, we will use an example to show the differences in how you get a token with the Token endpoint. Keep in mind though that no matter which endpoint you want to migrate, the changes are the same, the only thing that differs is the scopes that you specify in the request.
In the example below, you want to use the GET User by ID
endpoint to retrieve the full profile information of the logged-in user. First, authenticate the user using the Password Exchange grant and then retrieve the token(s). Below you can see an implementation of the old approach that gets an ID Token (and then uses it to call the endpoint).
POST https://{yourDomain}/oauth/token
Content-Type: application/x-www-form-urlencoded
{
"grant_type": "password",
"username": "{yourUsername}",
"password": "{yourPassword}",
"scope": "openid",
"client_id": "{yourClientId}",
"client_secret": "{yourClientSecret}",
}
Was this helpful?
In the example below, you can see the new approach that gets an access token as well.
POST https://{yourDomain}/oauth/token
Content-Type: application/x-www-form-urlencoded
{
"grant_type": "password",
"username": "{yourUsername}",
"password": "{yourPassword}",
"audience": "https://{yourDomain}/api/v2/",
"scope": "read:current_user",
"client_id": "{yourClientId}",
"client_secret": "{yourClientSecret}",
}
Was this helpful?
In order to get an Access Token that can access the Management API:
Set the
aud
tohttps://{yourDomain}/api/v2/
Ask for the scope
read:current_user
Once you have the access token you can use it to call the endpoint. This part remains the same, nothing else changes in the request except for the value you use as Bearer
token. The response remains also the same.
Embedded Lock or auth0.js
If you embed either Lock or auth0.js v9 in your application, then you are using cross-origin authentication. This is used to authenticate users when the requests come from different domains.
If you use auth0.js to access the Management API and manage your users, then your script will have to be updated.
In the example below, you can see the old approach.
// get an ID Token
var webAuth = new auth0.WebAuth({
clientID: '{yourClientId}',
domain: '{yourDomain}',
redirectUri: 'https://{yourApp}/callback',
scope: 'openid',
responseType: 'id_token'
});
// create a new instance
var auth0Manage = new auth0.Management({
domain: '{yourDomain}',
token: '{yourIdToken}'
});
Was this helpful?
In this example, you can see the new approach.
// get an Access Token
var webAuth = new auth0.WebAuth({
clientID: '{yourClientId}',
domain: '{yourDomain}',
redirectUri: 'https://{yourApp}/callback',
audience: 'https://{yourDomain}/api/v2/',
scope: 'read:current_user',
responseType: 'token id_token'
});
// create a new instance
var auth0Manage = new auth0.Management({
domain: '{yourDomain}',
token: '{yourMgmtApiAccessToken}'
});
Was this helpful?
Ask for both an ID token and an access token in the response
responseType: 'token id_token'
Set the Management API as the intended audience of the token
audience: 'https://YOUR_DOMAIN/api/v2/'
Ask for the required permission
scope: 'read:current_user'
Authenticate with the Management API using the access token
Account Linking changes
The changes in this functionality are the following:
You can no longer use an ID Token at the
Authorization
headerIf you use an access token at the
Authorization
header, withupdate:users
as the granted permission, then you can send at the request's body either theuser_id
or the ID Token of the secondary accountIf you use an access token at the
Authorization
header, withupdate:current_user_metadata
as the granted permission, then you can only send the ID Token of the secondary account in the request's body. The following must apply:The ID token must be signed using
RS256
(you can set this value at Dashboard > Applications > Application Settings > Advanced Settings > OAuth)The claim
aud
of the ID token, must identify the application, and be the same value with theazp
claim of the access token
Restrictions
The access tokens used to access the Management API must only hold one value at the aud
claim. If your token contains more than one value, then your request to the Management API will error out.