Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions docs/resource-specific-documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,43 @@ resourceServers:
}
```

### Auth0 My Account API — `authorization_policy`

The `authorization_policy` field can be set on the **Auth0 My Account API** resource server (the system resource server with identifier `https://<tenant-domain>/me/`) when the `acr` feature flag is enabled on the tenant. It specifies an Authentication Context Class Reference (ACR) policy that controls the authentication assurance requirements for access tokens issued to that API.

**YAML Example**

```yaml
resourceServers:
- name: Auth0 My Account API
identifier: https://your-tenant.auth0.com/me/
authorization_policy:
policy_id: '019b76da-a800-73c9-b656-b349ae415c17'
```

To clear the policy, set it to `null`:

```yaml
resourceServers:
- name: Auth0 My Account API
identifier: https://your-tenant.auth0.com/me/
authorization_policy: null
```

**Directory Example**

```json
{
"name": "Auth0 My Account API",
"identifier": "https://your-tenant.auth0.com/me/",
"authorization_policy": {
"policy_id": "019b76da-a800-73c9-b656-b349ae415c17"
}
}
```

> **Note:** `authorization_policy` is only accepted by the Auth0 API for the My Account resource server and only when the `acr` feature flag is enabled on the tenant.

## Universal Login

### Pages
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "Auth0 My Account API",
"identifier": "https://##AUTH0_DOMAIN##/me/",
"token_lifetime": 86400,
"skip_consent_for_verifiable_first_party_clients": true,
"authorization_policy": {
"policy_id": "019b76da-a800-73c9-b656-b349ae415c17"
}
}
6 changes: 6 additions & 0 deletions examples/yaml/tenant.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ resourceServers:
description: "read account"
# client_id: "if linked to a resource server client (readonly)"
# Add other resource server settings (https://auth0.com/docs/api/management/v2#!/Resource_Servers/post_resource_servers)
-
name: "Auth0 My Account API"
identifier: "https://##AUTH0_DOMAIN##/me/"
# authorization_policy is only applicable to the My Account API when the acr feature flag is enabled
authorization_policy:
policy_id: "019b76da-a800-73c9-b656-b349ae415c17"

tokenExchangeProfiles:
- name: "Custom Authentication Profile"
Expand Down
2 changes: 2 additions & 0 deletions src/tools/auth0/handlers/resourceServers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export default class ResourceServersHandler extends DefaultHandler {
'identifier',
'id',
'is_system',
'authorization_policy',
];
const sanitized: any = {};
allowedKeys.forEach((key) => {
Expand Down Expand Up @@ -204,6 +205,7 @@ export default class ResourceServersHandler extends DefaultHandler {
skip_consent_for_verifiable_first_party_clients:
update.skip_consent_for_verifiable_first_party_clients,
subject_type_authorization: update.subject_type_authorization,
authorization_policy: update.authorization_policy,
};

return this.client.resourceServers.update(id, updateFields);
Expand Down
116 changes: 116 additions & 0 deletions test/tools/auth0/handlers/resourceServers.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,122 @@ describe('#resourceServers handler', () => {
});
});

it('should preserve authorization_policy on system resource server export (getType)', async () => {
const systemResourceServer = {
id: 'rs_system',
identifier: 'https://api.system.com/me/',
name: 'Auth0 My Account API',
is_system: true,
token_lifetime: 86400,
skip_consent_for_verifiable_first_party_clients: true,
authorization_policy: { policy_id: '019b76da-a800-73c9-b656-b349ae415c17' },
scopes: [{ value: 'read:users' }], // Should be removed
signing_alg: 'RS256', // Should be removed
};

const auth0 = {
resourceServers: {
list: (params) => mockPagedData(params, 'resource_servers', [systemResourceServer]),
},
pool,
};

const handler = new resourceServers.default({ client: pageClient(auth0), config });
const result = await handler.getType();

expect(result[0]).to.have.property('authorization_policy');
expect(result[0].authorization_policy).to.deep.equal({
policy_id: '019b76da-a800-73c9-b656-b349ae415c17',
});
expect(result[0]).to.not.have.property('scopes');
expect(result[0]).to.not.have.property('signing_alg');
});

it('should include authorization_policy in update payload for Auth0 My Account API', async () => {
let updateCalledWith = null;
const existingResourceServer = {
id: 'rs_my_account',
identifier: 'https://auth0.com/my-account/me/',
name: 'Auth0 My Account API',
is_system: true,
};

const auth0 = {
resourceServers: {
create: () => Promise.resolve({ data: [] }),
update: function (id, data) {
updateCalledWith = data;
return Promise.resolve({ data });
},
delete: () => Promise.resolve({ data: [] }),
list: (params) => mockPagedData(params, 'resource_servers', [existingResourceServer]),
},
pool,
};

const handler = new resourceServers.default({ client: pageClient(auth0), config });
const stageFn = Object.getPrototypeOf(handler).processChanges;

await stageFn.apply(handler, [
{
resourceServers: [
{
name: 'Auth0 My Account API',
identifier: 'https://auth0.com/my-account/me/',
authorization_policy: { policy_id: '019b76da-a800-73c9-b656-b349ae415c17' },
},
],
},
]);

expect(updateCalledWith).to.not.equal(null);
expect(updateCalledWith.authorization_policy).to.deep.equal({
policy_id: '019b76da-a800-73c9-b656-b349ae415c17',
});
});

it('should include authorization_policy: null in update payload for Auth0 My Account API (clearing the policy)', async () => {
let updateCalledWith = null;
const existingResourceServer = {
id: 'rs_my_account',
identifier: 'https://auth0.com/my-account/me/',
name: 'Auth0 My Account API',
is_system: true,
authorization_policy: { policy_id: '019b76da-a800-73c9-b656-b349ae415c17' },
};

const auth0 = {
resourceServers: {
create: () => Promise.resolve({ data: [] }),
update: function (id, data) {
updateCalledWith = data;
return Promise.resolve({ data });
},
delete: () => Promise.resolve({ data: [] }),
list: (params) => mockPagedData(params, 'resource_servers', [existingResourceServer]),
},
pool,
};

const handler = new resourceServers.default({ client: pageClient(auth0), config });
const stageFn = Object.getPrototypeOf(handler).processChanges;

await stageFn.apply(handler, [
{
resourceServers: [
{
name: 'Auth0 My Account API',
identifier: 'https://auth0.com/my-account/me/',
authorization_policy: null,
},
],
},
]);

expect(updateCalledWith).to.not.equal(null);
expect(updateCalledWith.authorization_policy).to.equal(null);
});

it('should update "Auth0 My Account API" without name and is_system', async () => {
let updateCalled = false;
const existingResourceServer = {
Expand Down