-
Notifications
You must be signed in to change notification settings - Fork 71
Add scope pinning and other improvements to privilege worker docs #1539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,19 +1,19 @@ | ||||||||||||||||||
| --- | ||||||||||||||||||
| description: Learn how an application can access the Token Vault to exchange a JWT bearer token for an access or refresh token to call external APIs. | ||||||||||||||||||
| description: Learn how an application can access the Token Vault to exchange a JWT bearer token for an access token to call external APIs. | ||||||||||||||||||
| title: Privileged Worker Token Exchange with Token Vault | ||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| <Callout icon="file-lines" color="#0EA5E9" iconType="regular"> | ||||||||||||||||||
| Privileged Worker Token Exchange with Token Vault is currently in Beta. To learn more about Auth0’s product release cycle, read [Product Release Stages](/docs/troubleshoot/product-lifecycle/product-release-stages). To participate in this program, contact [Auth0 Support](https://support.auth0.com/) or your Technical Account Manager. | ||||||||||||||||||
| Privileged Worker Token Exchange with Token Vault is currently in Early Access. To learn more about Auth0’s product release cycle, read [Product Release Stages](/docs/troubleshoot/product-lifecycle/product-release-stages). To participate in this program, contact [Auth0 Support](https://support.auth0.com/) or your Technical Account Manager. | ||||||||||||||||||
| </Callout> | ||||||||||||||||||
|
Comment on lines
6
to
8
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please use the |
||||||||||||||||||
|
|
||||||||||||||||||
| Token Vault supports the Privileged Worker Token Exchange, which enables a client application to exchange a signed JWT (subject token) for an external provider’s access or refresh token (requested token). | ||||||||||||||||||
| Token Vault supports the Privileged Worker Token Exchange, which enables a client application to exchange a signed JWT (subject token) for an external provider’s access token (requested token). | ||||||||||||||||||
|
|
||||||||||||||||||
| After successful user authentication and authorization, a client application typically passes the user context, which contains the user's identity, permissions, and session state, as an access or refresh token to perform the token exchange with Token Vault. In service-to-service flows, a client application, such as a backend application or service worker, may need to access resources on the user’s behalf, but because the “user is not present” in an interactive session, the client application doesn’t have access to the user context. | ||||||||||||||||||
|
|
||||||||||||||||||
| In these service-to-service scenarios, the client application can generate a signed JWT bearer token and use it as the subject token to perform the token exchange and receive the necessary tokens to call external APIs. This means the client application can perform actions on the user’s behalf without an active user interaction or session. | ||||||||||||||||||
|
|
||||||||||||||||||
| To use the Privileged Worker Token Exchange with Token Vault, the client application must be a highly privileged client that can also request refresh tokens from external providers via Token Vault. It should authenticate with Token Vault using asymmetric cryptographic methods such as [Private Key JWT](/docs/get-started/authentication-and-authorization-flow/authenticate-with-private-key-jwt) assertion or [mutual TLS authentication](/docs/get-started/authentication-and-authorization-flow/authenticate-with-mtls). | ||||||||||||||||||
| To use the Privileged Worker Token Exchange with Token Vault, the client application must be a highly privileged client that can request access tokens from external providers via Token Vault. It should authenticate with Token Vault using asymmetric cryptographic methods such as [Private Key JWT](/docs/get-started/authentication-and-authorization-flow/authenticate-with-private-key-jwt) assertion or [mutual TLS authentication](/docs/get-started/authentication-and-authorization-flow/authenticate-with-mtls). | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Prerequisites | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -28,86 +28,107 @@ Before configuring Privileged Worker Token Exchange for your client application: | |||||||||||||||||
|
|
||||||||||||||||||
| ## Configure client application | ||||||||||||||||||
|
|
||||||||||||||||||
| To configure the client application's privileged access to Token Vault, you need to provide a public key that will be used to verify a signed JWT as the subject token. | ||||||||||||||||||
| To configure the client application's privileged access to Token Vault, you need to provide a public key that will be used to verify a signed JWT as the subject token. You also need to restrict which IP addresses the client may make requests from, and pin the client to the connections and scopes it's allowed to request — without these, the Privileged Worker Token Exchange will not work. | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
|
|
||||||||||||||||||
| <Tabs><Tab title="Auth0 Dashboard"> | ||||||||||||||||||
|
|
||||||||||||||||||
| 1. Navigate to **Applications > Applications** and select your application. | ||||||||||||||||||
| 2. Select the **Settings** tab, scroll to the **Privileged Worker** section, and toggle on **Enable Privileged Worker**. In the modal, select an existing public key credential or upload a new one, then select **Save**. | ||||||||||||||||||
| 3. Once the credential is saved, enter at least one IP address or CIDR range in the **IP Allowlist** field. | ||||||||||||||||||
| 4. Select **Save Changes**. | ||||||||||||||||||
| 4. Under **Permissions**, select **Add Permission**. In the modal, select a **Connection** and enter the **Scopes** this connection is allowed to request, then select **Save**. Repeat for each connection you want to allow. You can configure up to 5 permissions and 20 scopes in total. | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
| 5. Select **Save Changes**. | ||||||||||||||||||
| 6. For each connection referenced in **Permissions**, make sure it's also enabled for this application. Navigate to **Authentication > [Connection type]**, select the connection, go to the **Applications** tab, and toggle the connection on for your application. | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
|
|
||||||||||||||||||
| <Frame></Frame> | ||||||||||||||||||
|
|
||||||||||||||||||
| </Tab><Tab title="Management API"> | ||||||||||||||||||
| Similar to [configuring JAR](/docs/get-started/applications/configure-jar#configure-jwt-secured-authorization-requests-jar), you can set the Token Vault privileged access public key when creating a new client: | ||||||||||||||||||
| You can set the Token Vault privileged access public key, IP allowlist, and grants when creating a new client. The public key credential is configured similarly to [configuring JAR](/docs/get-started/applications/configure-jar#configure-jwt-secured-authorization-requests-jar): | ||||||||||||||||||
|
|
||||||||||||||||||
| ```bash lines | ||||||||||||||||||
| POST https://{yourDomain}.auth0.com/api/v2/clients | ||||||||||||||||||
| Authorization: Bearer <YOUR_MANAGEMENT_API_ACCESS_TOKEN> | ||||||||||||||||||
| Content-Type: application/json | ||||||||||||||||||
| { | ||||||||||||||||||
| "name": "My App using JAR", | ||||||||||||||||||
| “grant_types”: [“urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token”], | ||||||||||||||||||
| “oidc_conformant”: true, | ||||||||||||||||||
| “is_first_party”: true, | ||||||||||||||||||
| “jwt_configuration”: { | ||||||||||||||||||
| “alg”: 'RS256', | ||||||||||||||||||
| }, | ||||||||||||||||||
|
|
||||||||||||||||||
| "name": "My App using Privilege Worker", | ||||||||||||||||||
| "grant_types": [ | ||||||||||||||||||
| "urn:auth0:params:oauth:grant-type:token-exchange:federated-connection-access-token" | ||||||||||||||||||
| ], | ||||||||||||||||||
| "oidc_conformant": true, | ||||||||||||||||||
| "is_first_party": true, | ||||||||||||||||||
| "jwt_configuration": { | ||||||||||||||||||
| "alg": "RS256" | ||||||||||||||||||
| }, | ||||||||||||||||||
| "token_vault_privileged_access": { | ||||||||||||||||||
| "credentials": [{ | ||||||||||||||||||
| "credentials": [ | ||||||||||||||||||
| { | ||||||||||||||||||
| "name": "My credential for Token Vault Privileged Access", | ||||||||||||||||||
| "credential_type": "public_key", | ||||||||||||||||||
| "pem": "<YOUR PEM FILE CONTENT>", | ||||||||||||||||||
| "pem": "<YOUR_PEM_FILE_CONTENT>", | ||||||||||||||||||
| "alg": "RS256" | ||||||||||||||||||
| }] | ||||||||||||||||||
| }, | ||||||||||||||||||
| } | ||||||||||||||||||
| ], | ||||||||||||||||||
| "ip_allowlist": [ | ||||||||||||||||||
| "<YOUR_SERVER_IP_ADDRESS>" | ||||||||||||||||||
| ], | ||||||||||||||||||
| "grants": [ | ||||||||||||||||||
| { | ||||||||||||||||||
| "connection": "<YOUR_CONNECTION_NAME>", | ||||||||||||||||||
| "scopes": ["<YOUR_REQUIRED_SCOPE>"] | ||||||||||||||||||
| } | ||||||||||||||||||
| ] | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| You can also update an existing client with the Token Vault privileged access public key: | ||||||||||||||||||
| You can also update an existing client with the Token Vault privileged access public key, IP allowlist, and grants: | ||||||||||||||||||
|
|
||||||||||||||||||
| ```bash lines | ||||||||||||||||||
| PATCH https://{yourDomain}.auth0.com/api/v2/clients/{yourClientId} | ||||||||||||||||||
| Authorization: Bearer <YOUR_MANAGEMENT_API_ACCESS_TOKEN> | ||||||||||||||||||
| Content-Type: application/json | ||||||||||||||||||
| { | ||||||||||||||||||
| "token_vault_privileged_access": { | ||||||||||||||||||
| "credentials": [{"id": "<YOUR CREDENTIAL ID>"}] | ||||||||||||||||||
| "credentials": [{"id": "<YOUR_CREDENTIAL_ID>"}], | ||||||||||||||||||
| "ip_allowlist": ["<YOUR_SERVER_IP_ADDRESS>"], | ||||||||||||||||||
| "grants": [ | ||||||||||||||||||
| { | ||||||||||||||||||
| "connection": "<YOUR_CONNECTION_NAME>", | ||||||||||||||||||
| "scopes": ["<YOUR_REQUIRED_SCOPE>"] | ||||||||||||||||||
| } | ||||||||||||||||||
| ] | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| The credential `id` is returned in the response when you created your client. If you need to look it up, retrieve it with a GET request: | ||||||||||||||||||
|
|
||||||||||||||||||
| ```bash lines | ||||||||||||||||||
| GET https://{yourDomain}.auth0.com/api/v2/clients/{yourClientId} | ||||||||||||||||||
| GET https://{yourDomain}.auth0.com/api/v2/clients/{yourClientId}/credentials | ||||||||||||||||||
| Authorization: Bearer <YOUR_MANAGEMENT_API_ACCESS_TOKEN> | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| The `token_vault_privileged_access.credentials[].id` field in the response contains the credential ID. | ||||||||||||||||||
|
|
||||||||||||||||||
| ### Configure IP allowlist | ||||||||||||||||||
|
|
||||||||||||||||||
| To restrict which IP addresses may make Privileged Worker exchange requests, configure an `ip_allowlist` on your client. This binds the client credential to known server egress IPs, so a leaked credential cannot be used from an arbitrary IP address. Both IPv4 and IPv6 addresses and CIDR ranges are supported, with a maximum of 10 entries. | ||||||||||||||||||
| For each connection referenced in `grants`, the connection must also be enabled for this client. Enable it with: | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
|
|
||||||||||||||||||
| ```bash lines | ||||||||||||||||||
| PATCH https://{yourDomain}.auth0.com/api/v2/clients/{yourClientId} | ||||||||||||||||||
| PATCH https://{yourDomain}.auth0.com/api/v2/connections/{yourConnectionId}/clients | ||||||||||||||||||
| Authorization: Bearer <YOUR_MANAGEMENT_API_ACCESS_TOKEN> | ||||||||||||||||||
| Content-Type: application/json | ||||||||||||||||||
| { | ||||||||||||||||||
| "token_vault_privileged_access": { | ||||||||||||||||||
| "credentials": [{"id": "<YOUR_CREDENTIAL_ID>"}], | ||||||||||||||||||
| "ip_allowlist": ["<YOUR_SERVER_IP_ADDRESS>"] | ||||||||||||||||||
| [ | ||||||||||||||||||
| { | ||||||||||||||||||
| "client_id": "<YOUR_CLIENT_ID>", | ||||||||||||||||||
| "status": true | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
| ] | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
| </Tab></Tabs> | ||||||||||||||||||
|
|
||||||||||||||||||
| The `ip_allowlist` (**IP Allowlist** in the Dashboard) restricts which IP addresses may make Privileged Worker exchange requests. This binds the client credential to known server egress IPs, so a leaked credential cannot be used from an arbitrary IP address. Both IPv4 and IPv6 addresses and CIDR ranges are supported, with a maximum of 10 entries. | ||||||||||||||||||
|
|
||||||||||||||||||
| The `grants` (**Permissions** in the Dashboard) pins the client to a specific set of connections and, within each connection, a specific set of scopes. A Privileged Worker token exchange request is rejected if it targets a connection not listed in `grants`. Additionally, requesting a narrower scope than what was granted causes Token Vault to return a token restricted to that narrower scope provided the identity provider supports downscoping, otherwise the request fails rather than silently returning the full granted scope. A maximum of 5 connections and 20 scopes (across all connections combined) can be configured. Note that the listed connection must be enabled for the client, as described above. | ||||||||||||||||||
|
|
||||||||||||||||||
| <Callout icon="file-lines" color="#0EA5E9" iconType="regular"> | ||||||||||||||||||
| Configuring an `ip_allowlist` is required as part of the client configuration. Any Privileged Worker token exchange request from an IP not in the list will be rejected. | ||||||||||||||||||
| `ip_allowlist` and `grants` are not required to save a client's configuration, but both must be populated for the Privileged Worker Token Exchange to work: any request from an IP not in `ip_allowlist`, or for a connection or scope not in `grants`, will be rejected. | ||||||||||||||||||
| </Callout> | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Create signed JWT subject token | ||||||||||||||||||
|
|
@@ -134,6 +155,7 @@ The JWT has a standard format and claims: | |||||||||||||||||
| | `exp` | Optional. Expiration timestamp. Tokens older than 60 seconds are rejected regardless. | | ||||||||||||||||||
| | `jti` | Required. A unique identifier for this JWT (UUID v4 recommended) for replay protection. | | ||||||||||||||||||
| | `audit_context` | Required. A human-readable string (1–256 characters) describing the business reason for this privileged access. | | ||||||||||||||||||
| | `org_id` | Optional. The organization ID, if the request is scoped to an organization. | | ||||||||||||||||||
|
|
||||||||||||||||||
| The following is an example JWT: | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -151,7 +173,8 @@ The following is an example JWT: | |||||||||||||||||
| exp: 1758800540, | ||||||||||||||||||
| nbf: 1758799540, | ||||||||||||||||||
| jti: "<UNIQUE_JWT_ID>", | ||||||||||||||||||
| audit_context: "<REASON_FOR_ACCESS>" | ||||||||||||||||||
| audit_context: "<REASON_FOR_ACCESS>", | ||||||||||||||||||
| org_id: "<YOUR_ORGANIZATION_ID>" | ||||||||||||||||||
| } | ||||||||||||||||||
| ``` | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -171,6 +194,8 @@ import * as jwt from 'jsonwebtoken'; | |||||||||||||||||
| sub: USER_ID, | ||||||||||||||||||
| jti: uuidv4(), | ||||||||||||||||||
| audit_context: 'Automated nightly sync for compliance report', | ||||||||||||||||||
| // org_id is optional; include it if this request is scoped to an organization | ||||||||||||||||||
| org_id: ORGANIZATION_ID, | ||||||||||||||||||
| }, | ||||||||||||||||||
| privateKey, | ||||||||||||||||||
| { | ||||||||||||||||||
|
|
@@ -187,7 +212,7 @@ import * as jwt from 'jsonwebtoken'; | |||||||||||||||||
| Once you have the signed JWT, you can make a request for the access token for the external API: | ||||||||||||||||||
|
|
||||||||||||||||||
| ```bash lines | ||||||||||||||||||
| curl --request POST 'https://{yourDomain}/oauth/token' \ | ||||||||||||||||||
| curl --request POST 'https://{yourDomain}.auth0.com/oauth/token' \ | ||||||||||||||||||
| --header 'Content-Type: application/json' \ | ||||||||||||||||||
| --data '{ | ||||||||||||||||||
| "client_id": "<YOUR_CLIENT_ID>", | ||||||||||||||||||
|
|
@@ -207,7 +232,7 @@ curl --request POST 'https://{yourDomain}/oauth/token' \ | |||||||||||||||||
| | `client_secret` | Client secret. **Note:** For Privileged Worker Token Exchange, we recommend using Private Key JWT or mTLS authentication. | | ||||||||||||||||||
| | `subject_token_type` | Type of subject token. For Privileged Worker Token Exchange, set to JWT: `urn:ietf:params:oauth:token-type:jwt` | | ||||||||||||||||||
| | `subject_token` | The signed JWT bearer token that the Auth0 Authorization Server validates to identify the user. | | ||||||||||||||||||
| | `requested_token_type` | The requested token type. For Privileged Worker Token Exchange, you can request an access or refresh token. | | ||||||||||||||||||
| | `requested_token_type` | The requested token type. For Privileged Worker Token Exchange, this should always be `http://auth0.com/oauth/token-type/token-vault-access-token`. | | ||||||||||||||||||
| | `connection` | The connection name, in this case, `google-oauth2`. | | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
|
|
||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.