Skip to main content

Access token scopes

Scopes govern what an application can ask for in relation to a service. The service must be part of an OAuth 2.0 resource server. When the user grants consent, the requested scopes are included in the access token, which authorizes the client to access the corresponding data.

Scopes overview

Scopes let you authorize a specific slice of a resource server rather than the whole thing (every OAuth 2.0 service in a workspace is part of a single resource server). Define scopes around the specific features, functions, or APIs the user needs to consent to explicitly.

Scope governance

You can attach four types of policies to a scope. Each policy controls a different path through which the scope can be requested or granted:

ParameterDescription
Human UsersControls whether or not the Authorization Code flow can be used with this service. If enabled, you can configure the policy for such flow.
Machine UsersControls whether or not the Client Credentials flow can be used with this service. If enabled, you can configure the policy for such flow.
3rd Party DevelopersControls whether or not third party developers can subscribe to this service . If enabled, you can configure the policy for such flow.
Dynamic Client RegistrationControls whether or not dynamically registered clients can subscribe to this service. Define conditions dynamically registered clients need to meet to subscribe to a protected scope using a policy.

Subscribing apps to scopes

Subscribed client applications request scopes as part of the token request. If the user grants consent, the access token contains those scopes.

Limiting scopes in access tokens

Limit the scopes a client application can request by passing the specific scopes in the scope parameter on the token request. If the client does not pass the scope parameter, it receives access to all subscribed scopes.

Dynamic scopes

Scope names typically use dot notation to describe an action on a resource type, for example:

  • accounts.list

  • transactions.manage

  • users.delete

Static scopes work well for coarse access. They fall short when the client needs to authorize an action against a specific object, such as a particular account or user. In that case, you can embed the object identifier inside the scope value:

  • account.list.05542

  • transaction.manage.433212

  • user.delete.2321

Dynamic scopes let you define the scope with a wildcard once, rather than enumerating every instance.

When to use dynamic scopes

Use dynamic scopes when the authorization decision is per-object. Embedding the object in the scope lets you attach one policy that evaluates the specific resource at token issuance, rather than pushing the check into application code.

How it works

Here's a basic authorization flow using dynamic scopes:

  1. As an administrator, you define a dynamic scope in wildcard form account.* as part of the protected service/resource.

  2. Client asks for scope account.1234.

  3. SecureAuth matches the requested scope to the wildcard (dynamic) one defined by the administrator.

  4. SecureAuth applies the scope governance policies attached to the account.*.

  5. Optionally consent screen displays account.1234 to the users so that they know what account the client requested access to.

Dynamic scope syntax

The syntax for dynamic-scope names uses dot notation with generic form templates including scope parameters, for example account.*, where * represents a wildcard allowing multiple scope-name interpretations.

There are two elements in the scope name template:

  1. Scope root, which is a fixed core of the dynamic scope name, for example account or users

  2. Scope wildcard (*), which is an adjustable extension to the scope root allowing to retrieve a specific requested scope.

    note

    scopes[user.*].params[1] returns the first parameter matched by the user.* scope that comes in the access token.

Dynamic scopes matching

See the logic behind the dynamic scopes matching:

accounts.* matches accounts.read.

accounts.* matches accounts.read.foo.

accounts.read matches accounts.read.

accounts does not match accounts.read.

accounts.read.* does not match accounts.read.

accounts.*.* does not match accounts.read.

accounts.*.* matches accounts.read.own.

accounts.*.* matches accounts.read.own.other.

accounts.read.* matches accounts.read.own.

accounts.read.* matches accounts.read.own.other.

accounts.write.* does not match accounts.read.own.

accounts.*.bar matches accounts.baz.bar.

accounts.*.bar does not accounts.baz.baz.bar.

Scope validators in policies

Scope parameters that match wildcard parameters in the scope name are available in policy validators.

For example, if the administrator defines scope account.*.* and the client requests account.read.1234, the scope policy has access to wildcard-matched scope properties read and 1234, as well as the whole scope name.

Dynamic scope validators have at least three attributes:

  • Parameters available in policy validators

    note

    The number of parameters matches the number of wildcards in the scope name, for example, {{users..}} has two parameters available: {{params.0}} and {{params.1}}.

  • Requested scope name, for example, {{users.1234}}

  • Scope name, for example, {{users.\*}}