---
title: Dynamic OAuth 2.0 authorization
description: Grant OAuth 2.0 scopes dynamically based on policies rather than static client configuration
component: pingoneaic
page_id: pingoneaic:am-authorization:oauth2-authorization
canonical_url: https://docs.pingidentity.com/pingoneaic/am-authorization/oauth2-authorization.html
llms_txt: https://docs.pingidentity.com/pingoneaic/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
keywords: ["Authorization", "OAuth 2.0", "Scope", "Policy"]
page_aliases: ["authorization-guide:oauth2-authorization.adoc"]
section_ids:
  example_use_case: Example use case
  how_it_works: How it works
  validate_oauth_2_0_scope_policies: Validate OAuth 2.0 scope policies
  prepare_a_demonstration: Prepare a demonstration
  oauth2-authz-oath2-provider: OAuth 2.0 provider
  oauth2-authz-scope-policy: OAuth 2.0 scope policy
  oauth2-authz-client: OAuth 2.0 client
  oauth2-authz-resource-owner: Resource owner
  test_the_demonstration: Test the demonstration
  non_interactive: Non-interactive
  interactive: Interactive
  implied_consent: Implied consent
---

# Dynamic OAuth 2.0 authorization

Advanced Identity Cloud can grant OAuth 2.0 scopes statically or dynamically:

* Static scopes (default)

  OAuth 2.0 client configurations specify the allowed and, optionally, default scopes.

  When the client requests allowed scopes and the resource owner consents to grant the client access, Advanced Identity Cloud issues the token with the scopes requested.

  When different users use the same client that requests scopes `A` and `B`, the access token always includes scopes `A` and `B`.

* Dynamic scopes

  OAuth 2.0 client configurations specify the allowed and, optionally, default scopes.

  1. You configure policies for OAuth 2.0 scope decisions.

  2. You configure the client or the OAuth 2.0 provider service to use the policy engine for scope decisions.

  Advanced Identity Cloud checks each scope against the applicable OAuth 2.0 scope policies and grants or denies access to scopes dynamically.

  When different users use the same client that requests scopes `A` and `B`, the access token scopes can differ.

## Example use case

A company supports custom OAuth 2.0 clients for internal applications. The use of the internal applications is bound by the terms and conditions in the contracts of those who work for the company. The terms and conditions grant the internal applications access to profile information the company maintains. It would be redundant to prompt employees and contractors for consent to access their profile information.

An Advanced Identity Cloud administrative user creates policies to grant the `profile` scope for all internal client tokens.

## How it works

![How policies determine whether to grant or deny an OAuth 2.0 scope](_images/oauth2-realm-app-policy-overview.png)Figure 1. Policies for dynamic scopes

Advanced Identity Cloud processes consent based on the policy decision:

* If a policy grants access to a scope (`GRANT=true`), consent is automatic.

  Advanced Identity Cloud does not prompt the user to grant access.

* If a policy denies access to a scope (`GRANT=false`), Advanced Identity Cloud omits the scope from any resulting token.

  Advanced Identity Cloud does not prompt the user to grant access.

* If no policy grants or denies access, then the result depends on the flow.

  When the flow is interactive as in authorization or device code flows, Advanced Identity Cloud prompts the user to grant access or uses the saved consent state if available.

  If the flow is not interactive as in resource owner password or client credentials flows, Advanced Identity Cloud omits the scope from any resulting token.

  For details about which flows are interactive, refer to the examples in [OAuth 2.0 grant flows](../am-oauth2/oauth2-implementing-flows.html) and [OIDC grant flows](../am-oidc1/oidc-implementing-flows.html).

The default scopes behavior doesn't change for dynamic authorization. Advanced Identity Cloud only evaluates default scopes from the OAuth 2.0 client profile when the client doesn't request a scope. Advanced Identity Cloud follows the same rules to deduce consent for both default and requested scopes.

When issuing refresh tokens, Advanced Identity Cloud issues the same scopes as for the access token, unless a policy explicitly denies one of the scopes.

## Validate OAuth 2.0 scope policies

Writing policies for OAuth 2.0 might not be straightforward if your environment requires complex conditions. The easiest way to validate OAuth 2.0 policies is to configure a client to use the policies and request some tokens.

## Prepare a demonstration

Start by preparing the demonstration:

1. [Configure the OAuth 2.0 provider](#oauth2-authz-oath2-provider).

2. [Create a sample policy](#oauth2-authz-scope-policy).

3. [Create an OAuth 2.0 client](#oauth2-authz-client).

4. [Create a resource owner account](#oauth2-authz-resource-owner).

### OAuth 2.0 provider

Configure the OAuth 2.0 provider service to use the policy engine for scope decisions:

1. In the Advanced Identity Cloud admin console, go to [icon: vpn_key, set=material, size=inline] Authorization > OAuth2 Provider.

2. Enable Use Policy Engine for Scope decisions.

### OAuth 2.0 scope policy

The sample scope policy denies access to the `email` scope.

1. Under Native Consoles > Access Management, go to Realms > alpha > Authorization > Policy Sets and select Default OAuth2 Scopes Policy Set to edit the policy set.

   This is the `oauth2Scopes` policy.

2. Click + Add a Policy, use the following settings, and create the policy:

   * Name

     `Dynamic OAuth 2.0 Scopes`

   * Resource Type

     `OAuth2 Scope`

   * Resources

     Select `*` as the pattern and add `email` as the scope.

3. Click the Actions tab, set `GRANT` to `Deny`, and save your changes.

4. Click the Subjects tab, set the subject type to `Authenticated Users`, and save your changes.

The resulting policy reflects your work:

![OAuth 2.0 policy denying the email scope for all authenticated users](_images/oauth2-scope-policy.png)Figure 2. OAuth 2.0 scopes policy

### OAuth 2.0 client

The OAuth 2.0 client profile in this example overrides the OAuth 2.0 provider settings. This lets you test the scope policy without affecting other clients.

1. Create a confidential OAuth 2.0 client account.

   In the Advanced Identity Cloud admin console, select Applications > Applications > + Custom Application, and create a new Web application with the following settings:

   * Client ID: `myClient`

   * Client Secret: `mySecret`

2. Add the following settings in the client profile and save your work:

   * Name

     `Dynamic scopes client`

   * Sign-in URLs

     `https://www.example.com:443/callback`

   * Grant Types

     `Authorization Code`\
     `Client Credentials`\
     `Implicit`\
     `Refresh Token`\
     `Resource Owner Password Credentials`

   * Scopes

     `openid`\
     `profile`\
     `email`

3. Override the OAuth 2.0 provider settings for this client:

   Under Native Consoles > Access Management, select Realms > alpha > Applications > OAuth 2.0 > Clients > myClient. On the OAuth2 Provider Overrides tab, update the following settings and save your work:

   * Enable OAuth2 Provider Overrides: Enabled

   * Use Policy Engine for Scope decisions: Enabled

   * Scopes Policy Set: `oauth2Scopes`

### Resource owner

Create the OAuth 2.0 resource owner account:

1. In the Advanced Identity Cloud admin console, select Identities > + Add Identity and complete the required fields. For example:

   1. Username: `bjensen`

   2. Password: `Secret12!`

   3. Email address: `bjensen@example.com`

2. Record the username and password.

## Test the demonstration

Test the feature with non-interactive and interactive flows.

The sample policy denies the `email` scope for all authenticated users. The `profile` scope has no policy - it's a *no-policy-match* case. The tests show how Advanced Identity Cloud handles each case depending on the flow type.

### Non-interactive

This test uses the [resource owner password credentials](../am-oauth2/oauth2-ropc-grant.html) (ROPC) flow:

* The OAuth 2.0 client credentials are `myClient:mySecret`.

* The resource owner credentials are the username and password you recorded: `bjensen:Secret12!`.

* The requested scopes are `openid`, `profile`, and `email`.

```bash
$ curl \
--request POST \
--user 'myClient:mySecret' \
--data 'scope=openid profile email' \
--data 'grant_type=password' \
--data 'username=bjensen' \
--data 'password=Secret12!' \
"https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/access_token"
{
  "access_token": "...",
  "refresh_token": "...",
  "scope": "openid",
  "id_token": "...",
  "token_type": "Bearer",
  "expires_in": 3599
}
```

Notice the access token has `"scope": "openid"`. Advanced Identity Cloud removed both `email` and `profile` from the scopes:

* `email`: a policy explicitly denies it (`GRANT=false`), so Advanced Identity Cloud omits it.

* `profile`: no policy matches this scope, so Advanced Identity Cloud also omits it.

In non-interactive flows, Advanced Identity Cloud treats no-policy-match scopes the same as explicitly denied scopes.

### Interactive

This test uses the [implicit](../am-oauth2/oauth2-implicit-grant.html) flow. It stops after demonstrating the user consent phase of the process.

1. In a web browser, go to the `/authorize` endpoint to initiate the implicit flow.

   ```none
   https://<tenant-env-fqdn>/am/oauth2/realms/root/realms/alpha/authorize?scope=openid+profile+email&response_type=id_token&client_id=myClient&nonce=123&state=456&redirect_uri=https://www.example.com:443/callback
   ```

2. Sign in with the resource owner's credentials.

3. Observe the prompt for consent that doesn't include the `email` scope:

   ![Advanced Identity Cloud prompts for consent to access the profile scope.](_images/oauth2-example-oidc.png)Figure 3. Consent for the profile scope

The consent page shows `profile` but not `email`:

* `email`: the policy explicitly denies it (`GRANT=false`), so Advanced Identity Cloud omits it from the consent page entirely.

* `profile`: no policy matches this scope, so Advanced Identity Cloud presents it for the user to grant or deny.

In interactive flows, Advanced Identity Cloud doesn't treat no-policy-match scopes the same as explicitly denied scopes. Instead, it presents them for user consent.

|   |                                                                                                                                                                                                                                                                                                                                                           |
| - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | To explicitly deny a scope in interactive flows, you must create a policy that sets `GRANT` to `Deny` for that scope and the relevant condition. Without an explicit deny policy, a scope that fails a policy condition (for example, a user who doesn't meet a group membership requirement) is still presented for consent rather than denied outright. |

### Implied consent

If you enable Implied consent on the client application, Advanced Identity Cloud auto-grants no-policy-match scopes, in both interactive and non-interactive flows.
