Skip to main content

Restricting access tokens to an audience

An access token that contains an audience (aud) claim names the resource servers that are allowed to accept it. A resource server must verify that its own identifier is contained in the aud claim and reject the token if it is not.

Use the audience claim to make sure that an access token issued for one API cannot be replayed against a different, more sensitive API. This attack is known as the confused deputy problem.

nevisAuth builds the audience claim from the resource request parameter and from the resource servers that you configure in nevisMeta, in accordance with RFC 8707 and RFC 9068.

info

The audience claim is available as of nevisAuth 9.2605.0.16.

The following diagram shows what the audience claim prevents. The client receives a token for the orders API and sends it to the payments API.

note

nevisAuth adds the aud claim to the access token. Enforcing the claim is the task of the resource server: each resource server must compare the aud value of an incoming token with its own identifier and reject the token if the values do not match. nevisAuth does not reject the call to the payments API on behalf of that API.

Preconditions for the audience claim

  • nevisMeta is set up, see Setting up a nevisMeta Instance.
  • An OAuth 2.0 Authorization Server is set up, see Setting up an OAuth 2.0 Authorization Server.
  • nevisMeta is the data source of the authorization server. The audience claim is not available with other data sources.
  • Every resource server that you want to use as an audience has a value in the URL field in nevisMeta. RFC 8707 requires an absolute URI, and a resource server without a URL value can never become an audience. For more information on the resource server entity, see Entities.

Configuring the audience claim

To add the audience claim to the issued access tokens, perform the following steps:

  1. In the nevisMeta Web Console, open each resource server that you want to use as an audience, and set URL to the absolute URI of the API, for example https://api.example.com/orders.
  2. In nevisAdmin 4, open the OAuth 2.0 Authorization Server / OpenID Provider pattern.
  3. On the Token tab, set Audience Field Strategy to resource.
  4. Deploy the configuration.

For the field description, see Audience Field Strategy in the patterns reference.

If you configure the authorization server without nevisAdmin 4 patterns, set the property oauth2.audienceField.strategy to resource on the AuthorizationServer AuthState, see AuthorizationServer.

caution

The default value is disabled. When you change the value to resource, nevisAuth rejects every authorization request that contains neither a resource parameter nor scopes of exactly one resource server that has a URL value. Verify the requests of all clients before you enable the strategy in a production setup.

How nevisAuth determines the audience

nevisAuth determines the audience at the authorization endpoint. There are two paths: the client names the resource explicitly, or nevisAuth derives the resource from the requested scopes.

Audience from the resource parameter

Send the resource parameter on the request to the authorization endpoint. To name a resource server, send its URL value. Such a value must meet the following conditions:

  • The value is an absolute URI.
  • The value does not contain a fragment.
  • The value matches the URL value of a resource server in nevisMeta.

nevisAuth compares the value with the URL values as an exact string comparison. For this reason, https://api.example.com/orders and https://api.example.com/orders/ are two different values, and only the configured one is accepted.

To request several audiences, send the resource parameter one time for each value. Do not send several values as one space-separated list.

GET /oauth2/authorize?response_type=code
&client_id=example-client
&scope=orders:read payments:read
&resource=https://api.example.com/orders
&resource=https://api.example.com/payments

The aud claim of the issued access token then contains both values.

Audience from the requested scopes

If the request contains no resource parameter, nevisAuth derives the audience from the requested scopes. nevisAuth matches the requested scopes against the scopes of the resource servers in nevisMeta. Exactly one resource server must match, and that resource server must have a URL value. The aud claim then contains that URL value.

nevisAuth excludes the standard OpenID Connect scopes from this match, because these scopes belong to no single resource server:

  • openid
  • profile
  • email
  • address
  • phone
  • offline_access

As a result, a request that contains only standard OpenID Connect scopes has no scope left to derive a resource server from, and nevisAuth rejects it. When the resource strategy is active, such requests must contain a resource parameter.

The following table shows the outcome for each combination of the resource parameter and the requested scopes.

resource parameterRequested scopesOutcome
One or more values, all knownAnyAccess token with the resource values as audience
One or more values, one unknownAnyError invalid_target
NoneScopes of exactly one resource server that has a URL valueAccess token with that URL value as audience
NoneScopes of exactly one resource server that has no URL valueError invalid_scope
NoneScopes of several resource serversError invalid_scope
NoneOnly standard OpenID Connect scopesError invalid_scope

Scopes are not restricted to the audience

The audience claim restricts which resource servers can accept the access token. It does not restrict the scopes in the access token.

An access token contains every scope that the client is authorized to request and that the request asks for, independently of which resource server owns each scope. A request that names one resource in the resource parameter and asks for scopes of three resource servers produces an access token with the scopes of all three.

Take this into account when you plan the scopes of your resource servers.

Audience of refreshed access tokens

An access token that a client obtains with a refresh token keeps the audience of the original access token. The client cannot change the audience through the refresh, and a resource parameter on the refresh request has no effect.

Flows that support the audience claim

nevisAuth adds the audience claim in the Authorization Code, Implicit, and Hybrid flows.

The Client Credentials flow and the JWT Bearer flow do not add an audience claim to the access token.

Troubleshooting the audience claim

The OAuth 2.0 error codes that nevisAuth returns to the client are the ones the standards define, and several conditions share one code. To find the cause, read the nevisAuth log. The following table maps each condition to the log message that identifies it.

Error returned to the clientConditionnevisAuth log message
invalid_targetA resource value is not an absolute URI, contains a fragment, or matches no resource serverInvalid or unknown resource parameter: '...'
invalid_scopeThe requested scopes match at least one resource server that has no URL valueRequested scopes [...] map to at least one resource without URL.
invalid_scopeThe requested scopes match no resource serverRequested scopes [...] do not map to any resource server.
invalid_scopeThe requested scopes match several resource servers that all have a URL valueRequested scopes [...] map to multiple resource servers, which is not allowed without an explicit resource parameter.

nevisAuth verifies the three scope conditions in the order of the table. If the requested scopes match several resource servers and one of them has no URL value, the log contains the message about the missing URL, not the message about the several resource servers.

If the access token contains no aud claim at all, verify the following:

  • Audience Field Strategy is set to resource, and the configuration is deployed.
  • The flow is Authorization Code, Implicit, or Hybrid.
  • The resource parameter is sent to the authorization endpoint. The token endpoint ignores it.