Consent and delegation
Delegated User Management v2 API
Lets trusted people at customer and partner organizations manage their own users' access. DMv2 holds organizations, users, applications, permissions, access roles, admin roles, admin scopes and invitations. It is API-only: everything goes through the Correlation Layer API.
https://{tenant-host}/dm/correlation/apiaudience correlation-layer111 operationsWhen to use it
- Build a custom admin portal where partner admins invite and manage their own users.
- Provision organizations, access roles and permissions from a backend or a pipeline.
- Read a user's organizations and access roles to make an authorization decision.
Connect
- Base URL
https://{tenant-host}/dm/correlation/api- Token
POST https://{tenant-host}/oauth/v1/tokenwithgrant_type=client_credentials. The client ID and secret go in the form body.checked live- Client to create
- Access admin → Web clients → a dedicated client with the grant type Client credentials. Not an API client: those are only for Access's own configuration API.checked live
- Default audiences
- add
correlation-layer. A client with it wrote to DMv2 on a tenant; the tenant's own DMv2 clients have no audience at all. A token with no audience was refused with 401; a token with another service's audience got 403 (scope missing), not 401.not confirmed - Default scopes
correlation:<object>:<get|post|patch|put|delete>for each object you touch, e.g.correlation:role:get. Use only the scopes Access defines on your tenant (Access admin → Scopes). Tenants can define a subset: one checked defines 28 and none for admin roles, admin scopes, validation schemas, custom objects or search.checked live- Scope length
- The full spec set is about 1,500 characters joined with spaces. Access fails to issue a token past 1024. Split the scopes over two clients, or put some under Additional scopes and ask for them with
scope=on the token request.checked live - Whose rights apply
- With a client-credentials token DMv2 acts as the client and applies no delegation. With a signed-in admin's token it applies that admin's admin roles and scopes.not confirmed
curl -s https://{tenant-host}/oauth/v1/token \
-d grant_type=client_credentials \
-d client_id=$CLIENT_ID \
-d client_secret=$CLIENT_SECRET
curl -s "https://{tenant-host}/dm/correlation/api/v1/roles?pageSize=5&pageNumber=1" \
-H "Authorization: Bearer $ACCESS_TOKEN"Operations
Open an operation to see its parameters and code, and send it to your tenant. The token needs the listed scope. The credential operations (sign-ins, authenticators, one-time codes, temporary password) name correlation:user:credential:* scopes that many tenants don't define.
Connect to your tenant
Then open any operation below and send it.Sends grant_type=client_credentials to https://{tenant-host}/oauth/v1/token through this site's server. The secret and token stay in this tab only; host and client ID are remembered.
What trips people up
Lists have no totals
not confirmedLists answer {"content": [...], "pageSize": n, "pageNumber": n}. Read content, not items. Page with pageSize (at most 100) and pageNumber; the last page is empty or shorter than pageSize.
A service client bypasses delegation
not confirmedA client-credentials token can create, change and delete anything its scopes allow, in any organization. Check who may do what before you call, keep your own audit of the real person, and guard the secret like a DMv2 root credential. correlation:admin is not needed.
Role dates are set on assignment only
not confirmedstartDate / endDate are taken when a role is assigned. To change an end date, remove the role (POST /users/{id}/roles/remove) and assign it again. Dates in the past are refused.
Ended assignments are still returned
not confirmedDMv2 stores validity dates but doesn't hide ended roles or memberships. Filter on the dates yourself. The activeRoles / activeMemberships parameters may help, but their effect isn't verified.
GET /users/{id}/roles doesn't say where a role is held
not confirmedPass organizationId and ask per organization. A role can be assigned in an organization the user isn't a member of.
Offer a role from the root down
not confirmedA role is only available where its parent organization has it. Assigning it directly at a child fails with "not available to organization". POST /organizations/{root}/roles with includeSubOrganizations: true.
There is no move user
not confirmedAdd the user to the new organization, re-read, then remove them from the old one. Removing a user from an organization drops all their relationships there, member and admin. A user with no organization lands in the system "orphan" organization.
Admin-role writes need scopes tenants may lack
not confirmedAssigning admin roles from a service client needs correlation:admin-role:post|patch|delete. Many tenants define none; then those calls fail with 403.
The root organization has type admin-system-root
not confirmedUse it as parentId for top-level organizations. Find it with GET /v1/organizations rather than hard-coding an id.
Errors
Errors carry status (a name), code (the HTTP status) and message. The spec also lists 408 and 503 on every operation.
| 401 | UNAUTHENTICATED | No token, an expired one, or one DMv2 doesn't accept (seen with a token that had no audience). |
| 403 | PERMISSION_DENIED | "Forbidden resource": the token lacks the operation's scope, or the admin's delegation doesn't cover the object. |
| 404 | No object with this id, e.g. after a delete. | |
| 408 | The service timed out. Read back before retrying a write. |
When a call fails
| Reply | Means | What to change |
|---|---|---|
| The service answers 401 | The token lacks this service's audience, or it expired. | Add the audience to the client's Default audiences (Access admin → Web clients → the client), then get a new token. |
| The service answers 403 and the token has the audience | A scope the operation needs is missing. | Add one of the operation's scopes to the client's Default scopes. Use the scope names your tenant lists under Access admin → Scopes. |
| Token endpoint: 401 invalid_client | Unknown client ID or wrong secret. | Check the client ID and paste the secret again. |
| Token endpoint: 400 unauthorized_client | The client may not use client credentials. | Add the grant type Client credentials to the web client. |
| Token endpoint: 400 invalid_request about an audience | You asked for an audience the client doesn't have. | Add it to Default audiences, or stop asking for it. |
| Token endpoint: 500 right after scopes were added | The client's Default scopes, joined with spaces, are over about 1024 characters. | Move scopes to Additional scopes and request them per call, or split the work over two clients. |
| {"code":"not_found","message":"The requested location was not found"} | That service isn't deployed on this tenant. | Nothing to change in the client. Ask whoever runs the tenant. |
Two kinds of client exist in Access. Service APIs like this one take a web client with the Client credentials grant. Access's own configuration API takes an API client: a web client sent there gets 401 invalid_credentials.