OAuthV2 policy

This page applies to Apigee and Apigee hybrid.

View Apigee Edge documentation.

policy icon

What

OAuthV2 is a multi-faceted policy for performing OAuth 2.0 grant type operations. This is the primary policy used to configure OAuth 2.0 endpoints on Apigee.

This policy is an Extensible policy and use of this policy might have cost or utilization implications, depending on your Apigee license. For information on policy types and usage implications, see Policy types.

To learn more about OAuth on Apigee, see the OAuth home page. It provides links to resources, samples, videos, and more.

Samples

VerifyAccessToken

VerifyAccessToken

This OAuthV2 policy configuration (with the VerifyAccessToken operation) verifies that an access token submitted to Apigee is valid. When this policy operation is triggered, Apigee looks for a valid access token in the request. If the access token is valid, the request is allowed to proceed. If invalid, all processing stops and an error is returned in the response.

<OAuthV2 name="OAuthV2-Verify-Access-Token">
    <Operation>VerifyAccessToken</Operation>
</OAuthV2>

A client application would need to send in a request with a token. For example using curl it might be:

$ curl https://API_ENDPOINT/weather/forecastrss?w=12797282 \
  -H "Authorization: Bearer ylSkZIjbdWybfsUQe9BqP0LH5Z"

Where API_ENDPOINT is the domain used to access your APIs, as configured in your Apigee system.

By default, the OAuthV2 policy extracts the access token from Authorization header, stripping the Bearer prefix. You can change this default behavior with the AccessToken configuration element.

GenerateAccessToken

Generating access tokens

For examples showing how to request access tokens for each of the supported grant types, see Get OAuth 2.0 tokens. The topic includes examples of these operations:

GenerateAuthorizationCode

Generate authorization code

For examples showing how to request authorization codes, see Requesting an authorization code.

RefreshAccessToken

Refresh an access token

For examples showing how to request access tokens using a refresh token, see Refreshing an access token.

JWT access tokens

JWT access tokens

For examples showing how to generate, verify, and refresh JWT access tokens, see Using JWT access tokens.

Response flow token

Generate an access token on the response flow

Sometimes you may need to generate an access token in the response flow. For example, you may do this in response to some custom validation done in a backend service. In this example, the use case requires both an access token and a refresh token, ruling out the implicit grant type. In this case, we'll use the password grant type to generate the token. As you'll see, the trick to making this work is to pass in an Authorization request header with a JavaScript policy.

First, let's look at the sample policy:

<OAuthV2 enabled="true" continueOnError="false" async="false" name="generateAccessToken">
    <Operation>GenerateAccessToken</Operation>
    <AppEndUser>Doe</AppEndUser>
    <UserName>jdoe</UserName>
    <PassWord>jdoe</PassWord>
    <GrantType>grant_type</GrantType>
    <ClientId>a_valid_client_id</ClientId>
    <SupportedGrantTypes>
        <GrantType>password</GrantType>
    </SupportedGrantTypes>
</OAuthV2>

If you put this policy on the response flow, it will fail with a 401 UnAuthorized error even though the correct login parameters are specified in the policy. To solve this problem, you need to set an Authorization request header.

The Authorization header must contain a Basic access scheme with the Base64-encoded client_id:client_secret.

You can add this header with a JavaScript policy placed just before the OAuthV2 policy, like this. The "local_clientid" and "local_secret" context variables must be previously set and available in the flow:

var clientId = context.getVariable("local_clientid");
var clientSecret = context.getVariable("local_secret");
context.setVariable("request.header.Authorization","Basic "+ CryptoJS.enc.Base64.stringify(CryptoJS.enc.Latin1
                                      .parse(clientId + ':' + clientSecret)));

See also Encoding basic authentication credentials.

Element reference

The policy reference describes the elements and attributes of the OAuthV2 policy.

The sample policy shown below is one of many possible configurations. This sample shows an OAuthV2 policy configured for the GenerateAccessToken operation. It includes required and optional elements. Refer to the element descriptions in this section for details.

<OAuthV2 name="GenerateAccessToken">
  <!-- This policy generates an OAuth 2.0 access token using the client_credentials grant type -->
  <Operation>GenerateAccessToken</Operation>
  <!-- This is in millseconds, so expire in an hour -->
  <ExpiresIn>3600000</ExpiresIn>
  <SupportedGrantTypes>
    <GrantType>client_credentials</GrantType>
  </SupportedGrantTypes>
  <GrantType>request.queryparam.grant_type</GrantType>
  <GenerateResponse/>
</OAuthV2>

<OAuthV2> attributes

<OAuthV2 async="false" continueOnError="false" enabled="true" name="MyOAuthPolicy">

The following table describes attributes that are common to all policy parent elements:

Attribute Description Default Presence
name

The internal name of the policy. The value of the name attribute can contain letters, numbers, spaces, hyphens, underscores, and periods. This value cannot exceed 255 characters.

Optionally, use the <DisplayName> element to label the policy in the management UI proxy editor with a different, natural-language name.

N/A Required
continueOnError

Set to false to return an error when a policy fails. This is expected behavior for most policies.

Set to true to have flow execution continue even after a policy fails. See also:

false Optional
enabled

Set to true to enforce the policy.

Set to false to turn off the policy. The policy will not be enforced even if it remains attached to a flow.

true Optional
async

This attribute is deprecated.

false Deprecated

<DisplayName> element

Use in addition to the name attribute to label the policy in the management UI proxy editor with a different, natural-language name.

<DisplayName>Policy Display Name</DisplayName>
Default

N/A

If you omit this element, the value of the policy's name attribute is used.

Presence Optional
Type String

<AccessToken> element

<AccessToken>request.header.access_token</AccessToken>

By default, when Operation is VerifyAccessToken, the policy expects the access token to be sent in the Authorization header as a bearer token; that is to say, with a prefix of "Bearer", followed by one blank space. You can change that default using this element, specifying the name of a variable that contains the access token to verify. When you use this element, the policy by default does not look for a prefix in the contents of the variable. If you want to specify that the policy should look for a prefix, use the AccessTokenPrefix element as well.

Examples:

  • When the policy configuration is:

      <OAuthV2 name="OAuthV2-Verify-Access-Token-in-Header">
          <Operation>VerifyAccessToken</Operation>
          <AccessToken>request.header.access_token</AccessToken>
      </OAuthV2>

    To pass the token using curl, you might use:

      curl https://API_ENDPOINT/oauth2/validate -H "access_token:Rft3dqrs56Blirls56a"
  • When the policy configuration is:

      <OAuthV2 name="OAuthV2-Verify-Access-Token-in-QueryParam">
          <Operation>VerifyAccessToken</Operation>
          <AccessToken>request.queryparam.token</AccessToken>
      </OAuthV2>

    To pass the token using curl, you might use:

      curl "https://API_ENDPOINT/oauth2/validate?token=Rft3dqrs56Blirls56a"

Where API_ENDPOINT is the domain used to access your APIs, as configured in your Apigee system.

Default:

N/A

Presence:

Optional

Type: String
Valid values:

any variable name

Used with operations:
  • VerifyAccessToken

<AccessTokenPrefix> element

<AccessTokenPrefix>Prefix</AccessTokenPrefix>

By default, when Operation is VerifyAccessToken, the policy expects the access token to be sent in the Authorization header as a bearer token; that is to say, with a prefix of "Bearer", followed by one blank space. If you use the AccessToken element to specify a different location for the incoming access token, then you can also use this element, AccessTokenPrefix, to specify a different, non-standard prefix.

For example, if you specify:

<OAuthV2 name="OAuthV2-Verify-Access-Token-Alternative-Header">
    <Operation>VerifyAccessToken</Operation>
    <AccessToken>request.header.token</AccessToken>
    <AccessTokenPrefix>KEY</AccessTokenPrefix>
</OAuthV2>

Then the policy will extract the inbound access token in from token request header, in this way: if the header begins with the word "KEY" followed by a space, the policy will strip that prefix and space and interpret the remaining value as the access token. If the specified prefix is not present in the header, the policy will throw a fault.

If you specify the AccessToken element, and do not specify the AccessTokenPrefix element, the policy will interpret the entire value of the variable specified within the AccessToken element as the access token.

This element is effective only when the AccessToken element is also used.

Default:

-none-

Presence:

Optional

Type: String
Valid values:

any string

Used with operations:
  • VerifyAccessToken

<Algorithm>

<Algorithm>algorithm-here</Algorithm>

Specifies the encryption algorithm used to sign a JWT access token. RSA (RS*) algorithms employ a public/secret key pair while HMAC (HS*) algorithms employ a shared secret. This element is required for the GenerateJWTAccessToken, VerifyJWTAccessToken, and RefreshJWTAccessToken operations.

Default N/A
Presence Required when using the GenerateJWTAccessToken, VerifyJWTAccessToken, and RefreshJWTAccessToken operations.
Type String
Valid values HS256, HS384, HS512, RS256, RS384, RS512

<AppEndUser> element

<AppEndUser>request.queryparam.app_enduser</AppEndUser>

In cases where the app end user ID must be sent to the authorization server, this element lets you specify where Apigee should look for the end user ID. For example, it could be sent as a query parameter or in an HTTP header.

For example request.queryparam.app_enduser indicates that the AppEndUser should be present as a query parameter, as, for example, [email protected]. To require the AppEndUser in an HTTP header, for example, set this value to request.header.app_enduser.

Providing this setting enables you to include an app end user ID in the access token. This feature is useful if you want to be able to retrieve or revoke OAuth 2.0 access tokens by end user ID. For more information, see Enable retrieval and revocation of OAuth 2.0 access tokens by end user ID, app id, or both.

Default:

N/A

Presence:

Optional

Type: String
Valid values:

Any flow variable accessible to the policy at runtime.

Used with grant types:
  • authorization_code
  • implicit
  • password
  • client_credentials

<Attributes/Attribute>

<Attributes>
    <Attribute name="attr_name1" ref="flow.variable" display="true|false">value1</Attribute>
    <Attribute name="attr_name2" ref="flow.variable" display="true|false">value2</Attribute>
</Attributes>

Use this element to add custom attributes to an access token or authorization code. For example, you may wish to embed a user ID or session identifier in an access token that can be extracted and checked at runtime.

This element lets you specify a value in a flow variable or from a literal string. If you specify both a variable and a string, the value specified in the flow variable is used. If the variable cannot be resolved, then the string is the default.

For more information on using this element, see Customizing Tokens and Authorization Codes.

Displaying or hiding custom attributes in the response

Remember that if you set the GenerateResponse element of this policy to true, the full JSON representation of the token is returned in the response, including any custom attributes that you set. In some cases, you might want to hide some or all of your custom attributes in the response so that they are not visible to client apps.

By default, custom attributes do appear in the response. If you want to hide them, you can set the display parameter to false. For example:

<Attributes>
    <Attribute name="employee_id" ref="employee.id" display="false"/>
    <Attribute name="employee_name" ref="employee.name" display="false"/>
</Attributes>

The value of the display attribute is not persisted. Let's say you generate an access token with custom attributes that you want to hide in the generated response. Setting display=false accomplishes that goal. However, if a new access token is generated later using a refresh token, the original custom attributes from the access token will show up in the refresh token response. This is because Apigee does not remember that the display attribute was originally set to false in the generate access token policy--the custom attribute is simply part of the access token's metadata.

You will see the same behavior if you add custom attributes to an authorization code--when an access token is generated using that code, those custom attributes will show up in the access token response. Again, this may not be the behavior you intend.

To hide custom attributes in these cases, you have these choices:

  • Explicitly reset the custom attributes in the refresh token policy and set their display to false. In this case, you may need to retrieve the original custom values from the original access token using the GetOAuthV2Info policy.
  • Use a postprocessing JavaScript policy to manually extract any custom attributes that you do not want to see in the response.

See also Customizing Tokens and Authorization Codes.

Default:

N/A

Presence:

Optional

Valid values:
  • name -The attribute name
  • ref - The value of the attribute. Can come from a flow variable.
  • display - (Optional) Lets you specify whether or not custom attributes appear in the response. If true, custom attributes appear in the response (If GenerateResponse is also enabled). If false, custom attributes are not included in the response. Default value is true. See Displaying or hiding custom attributes in the response.
Used with grant types:
  • authorization_code
  • implicit
  • password
  • client_credentials
  • refresh_token
  • Can also be used with the GenerateAuthorizationCode operation.

<CacheExpiryInSeconds> element

<CacheExpiryInSeconds ref="request.queryparam.cache_expiry">Value 1</CacheExpiryInSeconds>

This element enforces TTL on the cache, which enables customization of the time period for cached access token expiry. The supported range is between 1 and 180 seconds. You can provide a flow variable and a default variable. If provided, the flow variable value takes precedence over the specified default value.

This element can be used with the VerifyAccessToken operation only.

Default N/A

If you omit this element, the default expiration period for the cached access token is 180 seconds.

Presence Optional
Type Integer
Valid values Any positive, nonzero integer. Specifies the expiration time in seconds.

Attributes

The following table describes the attributes of the <CacheExpiryInSeconds> element

Attribute Description Default Presence
ref

A reference to the flow variable containing the value for the cache expiration, expressed in seconds.

If provided, the flow variable value takes precedence over the specified default value.

N/A Optional

<ClientId> element

<ClientId>request.formparam.client_id</ClientId>

In several cases, the client app must send the client ID to the authorization server. This element specifies that Apigee should look for the client ID in the flow variable request.formparam.client_id. Setting ClientId to any other variable is not supported. See also Get OAuth 2.0 tokens.

Default:

request.formparam.client_id (a x-www-form-urlencoded and specified in the request body)

Presence:

Optional

Type: String
Valid values: The flow variable: request.formparam.client_id
Used with grant types:
  • authorization_code
  • password
  • implicit
  • client_credentials

Can also be used with the GenerateAuthorizationCode operation.

<Code> element

<Code>request.queryparam.code</Code>

In the authorization grant type flow, the client must submit an authorization code to the authorization server (Apigee). This element lets you specify where Apigee should look for the authorization code. For example, it could be sent as a query parameter, HTTP header, or form parameter (the default).

The variable, request.queryparam.auth_code indicates that the authorization code should be present as a query parameter, as, for example, ?auth_code=AfGlvs9. To require the authorization code in an HTTP header, for example, set this value to request.header.auth_code. See also Get OAuth 2.0 tokens.

Default:

request.formparam.code (a x-www-form-urlencoded and specified in the request body)

Presence:

optional

Type: String
Valid values: Any flow variable accessible to the policy at runtime
Used with grant types: authorization_code

<ExpiresIn> element

<ExpiresIn>10000</ExpiresIn>

Enforces the expiry time of access tokens and authorization codes in milliseconds. (For refresh tokens, use <RefreshTokenExpiresIn>.) The expiry time value is a system generated value plus the <ExpiresIn> value. If <ExpiresIn> is set to -1, the token or code expires as per the maximum OAuth access token expiration. If <ExpiresIn> is not specified, the system applies a default value configured at the system level.

The expiry time can also be set at runtime using either a hard-coded, default value or by referencing a flow variable. For example, you can store a token expiration value in a key value map, retrieve it, assign it to a variable, and reference it in the policy. For example, kvm.oauth.expires_in.

Apigee keeps the following entities in cache for a minimum of 180 seconds after the entities are accessed.

  • OAuth access tokens. This means the ExpiresIn element on the OAuth v2 policy won't be able to expire an access token in less than 180 seconds.
  • Key Management Service (KMS) entities (Apps, Developers, API Products).
  • Custom attributes on OAuth tokens and KMS entities.

The following stanza specifies a flow variable and a default value as well. Note that the flow variable value takes precedence over the specified default value.

<ExpiresIn ref="kvm.oauth.expires_in">
    3600000 <!--default value in milliseconds-->
</ExpiresIn>

Apigee does not support a way to force the expiration of a token after it has been created. If you need to force token expiration (for example, based on a condition), a possible solution is described in this Apigee Community post.

By default, expired access tokens are purged from the Apigee Apigee system automatically 3 days after expiration. See also Purging access tokens

Default:

If not specified, the system applies a default value configured at the system level.

Presence:

Optional

Type: Integer
Valid values:
  • Any positive, nozero integer. Specify the expiry time in milliseconds. Although the value of this element is in milliseconds, the value set in the token's expires_in property and in the expires_in flow variable is expressed in seconds.
  • -1 will expire as per the maximum OAuth access token expiration.

    Note: Specifying any other negative integer or zero causes a deployment error.
Used with grant types:
  • authorization_code
  • implicit
  • password
  • client_credentials
  • refresh_token

Also used with GenerateAuthorizationCode operation.

<ExternalAccessToken> element

<ExternalAccessToken>request.queryparam.external_access_token</ExternalAccessToken>

Tells Apigee where to find an external access token (an access token not generated by Apigee).

The variable request.queryparam.external_access_token indicates that the external access token should be present as a query parameter, as, for example, ?external_access_token=12345678. To require the external access token in an HTTP header, for example, set this value to request.header.external_access_token. See also Using Third-Party OAuth Tokens.

<ExternalAuthorization> element

<ExternalAuthorization>true</ExternalAuthorization>

If this element is false or not present, then Apigee validates the client_id and client_secret normally against the Apigee authorization store. Use this element when you want to work with third-party OAuth tokens. For details on using this element, see Using Third-Party OAuth Tokens.

Default:

false

Presence:

Optional

Type: Boolean
Valid values: true or false
Used with grant types:
  • authorization_code
  • password
  • client_credentials

<ExternalAuthorizationCode> element

<ExternalAuthorizationCode>request.queryparam.external_auth_code</ExternalAuthorizationCode>

Tells Apigee where to find an external auth code (an auth code not generated by Apigee).

The variable request.queryparam.external_auth_code indicates that the external auth code should be present as a query parameter, as, for example, ?external_auth_code=12345678. To require the external auth code in an HTTP header, for example, set this value to request.header.external_auth_code. See also Using Third-Party OAuth Tokens.

<ExternalRefreshToken> element

<ExternalRefreshToken>request.queryparam.external_refresh_token</ExternalRefreshToken>

Tells Apigee where to find an external refresh token (a refresh token not generated by Apigee).

The variable request.queryparam.external_refresh_token indicates that the external refresh token should be present as a query parameter, as, for example, ?external_refresh_token=12345678. To require the external refresh token in an HTTP header, for example, set this value to request.header.external_refresh_token. See also Using Third-Party OAuth Tokens.

<GenerateResponse> element

<GenerateResponse enabled='true'/>

If set to true or if the enabled attribute is omitted, the policy generates and returns a response. For example, for GenerateAccessToken, the response might be like:

{
  "issued_at" : "1467841035013",
  "scope" : "read",
  "application_name" : "e31b8d06-d538-4f6b-9fe3-8796c11dc930",
  "refresh_token_issued_at" : "1467841035013",
  "status" : "approved",
  "refresh_token_status" : "approved",
  "api_product_list" : "[Product1, nhl_product]",
  "expires_in" : "1799",
  "developer.email" : "[email protected]",
  "token_type" : "BearerToken",
  "refresh_token" : "rVSmm3QaNa0xBVFbUISz1NZI15akvgLJ",
  "client_id" : "Adfsdvoc7KX5Gezz9le745UEql5dDmj",
  "access_token" : "AnoHsh2oZ6EFWF4h0KrA0gC5og3a",
  "organization_name" : "cerruti",
  "refresh_token_expires_in" : "0",
  "refresh_count" : "0"
}

If set to false or if the <GenerateResponse> element is omitted, no response is sent. Instead, a set of flow variables are populated with values related to the policy's function. For example, a flow variable called oauthv2authcode.OAuthV2-GenerateAuthorizationCode.code gets populated with the newly minted auth code. Note that expires_in is expressed in seconds in the response.

Default:

true

Presence:

Optional

Type: string
Valid values: true or false
Used with grant types:
  • implicit
  • password
  • client_credentials
  • refresh_token
  • Also can be used with the GenerateAuthorizationCode operation.

<GenerateErrorResponse> element

<GenerateErrorResponse enabled='true'/>

If set to true, the policy generates and returns a response if the ContinueOnError attribute is set to true. If false (the default), no response is sent. Instead, a set of flow variables are populated with values related to the policy's function.

Default:

false

Presence:

Optional

Type: string
Valid values: true or false
Used with grant types:
  • implicit
  • password
  • client_credentials
  • refresh_token
  • Also can be used with the GenerateAuthorizationCode operation.

<GrantType>

<GrantType>request.queryparam.grant_type</GrantType>

Tells the policy where to find the grant type parameter that is passed in a request. Per the OAuth 2.0 specification, the grant type must be supplied with requests for access tokens and authorization codes. The variable can be a header, query parameter, or form parameter (default).

For example request.queryparam.grant_type indicates that the Password should be present as a query parameter, as, for example, ?grant_type=password. To require the grant type in an HTTP header, for example, set this value to request.header.grant_type. See also Get OAuth 2.0 tokens.

Default:

request.formparam.grant_type (a x-www-form-urlencoded and specified in the request body)

Presence:

Optional

Type: string
Valid values: A variable, as explained above.
Used with grant types:
  • authorization_code
  • password
  • implicit
  • client_credentials
  • refresh_token

<Operation> element

<Operation>GenerateAuthorizationCode</Operation>

The OAuth 2.0 operation executed by the policy.

Default:

If <Operation> is not specified, Apigee looks at the list of <SupportedGrantTypes>. Only operations on those grant types will be successful. In other words, you can omit <Operation> if you specify a <GrantType> in the <SupportedGrantTypes> list. If neither <Operation> nor <SupportedGrantTypes> are specified, the default grant type is authorization_code. That is, authorization_code grant type requests will succeed, but all others will fail.

Presence:

Optional

Type: String
Valid values:
  • GenerateAccessToken - Generates an access token. See also Get OAuth 2.0 tokens.
  • GenerateAccessTokenImplicitGrant - Generates an access token for the implicit grant type. See also Get OAuth 2.0 tokens.
  • GenerateAuthorizationCode - Generates an auth code. Used with the authorization code grant type. See also Get OAuth 2.0 tokens.
  • RefreshAccessToken - Exchange a refresh token for a new access token. See also Get OAuth 2.0 tokens.
  • VerifyAccessToken - Verifies that an access token sent in a request is valid. See the VerifyAccessToken sample above and Verifying access tokens.
  • InvalidateToken - Revokes an access token. After a token has been revoked, clients cannot use that token to call a protected API. See also Approving and revoking access tokens.
  • ValidateToken - Reinstates or "approves" an access token that was previously revoked. See also Approving and revoking access tokens.

Additional JWT access token operations

If you prefer to use JWT access tokens instead of opaque string tokens, the following operations are also available for generating and validating JWT tokens. For details, see Using JWT OAuth token operations:

<PassWord> element

<PassWord>request.queryparam.password</PassWord>

This element is used with the password grant type only. With the password grant type, user credentials (password and username) must be made available to the OAuthV2 policy. The <PassWord> and <UserName> elements are used to specify variables where Apigee can find these values. If these elements are not specified, the policy expects to find the values (by default) in form parameters named username and password. If the values are not found, the policy throws an error. You can use the <PassWord> and <UserName> elements to reference any flow variable containing the credentials.

For example, you can pass the password in a token request using a query parameter and set the element like this: <PassWord>request.queryparam.password</PassWord>. To require the password in an HTTP header, set this value to request.header.password.

The OAuthV2 policy doesn't do anything else with these credential values; Apigee is simply verifying that they are present. It is up to the API developer to retrieve the values request and send them to an identity provider before the token generation policy executes.

See also Get OAuth 2.0 tokens.

Default:

request.formparam.password (a x-www-form-urlencoded and specified in the request body)

Presence:

Optional

Type: String
Valid values: Any flow variable available to the policy at runtime.
Used with grant types: password

<PrivateKey>/<Value>

<PrivateKey>
  <Value ref="variable-name-here"/>
</PrivateKey>

Provides the private key used to verify or sign JWT-formatted access tokens with an RSA algorithm. Use the ref attribute to pass the key in a flow variable. Use only when the Algorithm element value is one of RS256, RS384, or RS512. For more information, see Using JWT OAuth token operations.

Default N/A
Presence Required when the Algorithm element value is one of HS256, HS384, or HS512.
Type String
Valid values A flow variable containing a string representing a PEM-encoded RSA private key value.

<PublicKey>/<Value>

<PublicKey>
   <Value ref="variable-name-here"/>
</PublicKey>

Specifies the public key or public cert used to verify the signature on a JWT-formatted access token signed with an RSA algorithm. Use the ref attribute to pass the key/cert in a flow variable. Use only when the Algorithm element value is one of RS256, RS384, or RS512.

Default N/A
Presence To verify a JWT signed with an RSA algorithm, you must either use the Certificate, JWKS, or Value elements.
Type String
Valid values A flow variable or string.

<RedirectUri> element

<RedirectUri>request.queryparam.redirect_uri</RedirectUri>

Specifies where Apigee should look for the redirect_uri parameter in the request.

About redirection URIs

Redirection URIs are used with the authorization code and implicit grant types. The redirect URI tells the authorization server (Apigee) where to send an authorization code (for the auth code grant type) or access token (for the implicit grant type). It's important to understand when this parameter is required, when it is optional, and how it is used:

  • (required) If a Callback URL is registered with the developer app that is associated with the request's client keys, and if the redirect_uri is present in the request, then the two must match exactly. If they do not match, an error is returned. For information on registering developer apps on Apigee and specifying a Callback URL, see Register apps and manage API keys.

  • (optional) If a Callback URL is registered, and the redirect_uri is missing from the request, then Apigee redirects to the registered Callback URL.
  • (required) If a Callback URL is not registered, then the redirect_uri is required. Note that in this case, Apigee will accept ANY URL. This case can present a security issue, and therefore should only be used with trusted client apps. If client apps are not trusted, then the best practice is to always require the registration of a Callback URL.

You can send this parameter in a query parameter or in a header. The variable request.queryparam.redirect_uri indicates that the RedirectUri should be present as a query parameter, as, for example, ?redirect_uri=login.myapp.com. To require the RedirectUri in an HTTP header, for example, set this value to request.header.redirect_uri. See also Get OAuth 2.0 tokens.

Default:

request.formparam.redirect_uri (a x-www-form-urlencoded and specified in the request body)

Presence:

Optional

Type: String
Valid values: Any flow variable accessible in the policy at runtime
Used with grant types:
  • authorization_code
  • implicit

Also used with the GenerateAuthorizationCode operation.

<RefreshToken> element

<RefreshToken>request.queryparam.refreshtoken</RefreshToken>

When requesting an access token using a refresh token, you must supply the refresh token in the request. This element lets you specify where Apigee should look for the refresh token. For example, it could be sent as a query parameter, HTTP header, or form parameter (the default).

The variable request.queryparam.refreshtoken indicates that the refresh token should be present as a query parameter, as, for example, ?refresh_token=login.myapp.com. To require the RefreshToken in an HTTP header, for example, set this value to request.header.refresh_token. See also Get OAuth 2.0 tokens.

Default:

request.formparam.refresh_token (a x-www-form-urlencoded and specified in the request body)

Presence:

Optional

Type: String
Valid values: Any flow variable accessible in the policy at runtime
Used with grant types:
  • refresh_token

<RefreshTokenExpiresIn> element

<RefreshTokenExpiresIn>1000</RefreshTokenExpiresIn>

Enforces the expiry time of refresh tokens in milliseconds. The expiry time value is a system-generated value plus the <RefreshTokenExpiresIn> value. If <RefreshTokenExpiresIn> is set to -1, the refresh token expires as per the maximum OAuth refresh token expiration. If <RefreshTokenExpiresIn> is not specified, the system applies the default value.

The expiry time can also be set at runtime using either a hard-coded, default value or by referencing a flow variable. For example, you can store a token expiration value in a key value map, retrieve it, assign it to a variable, and reference it in the policy. For example, kvm.oauth.expires_in.

The following stanza specifies a flow variable and a default value as well. Note that the flow variable value takes precedence over the specified default value.

<RefreshTokenExpiresIn ref="kvm.oauth.expires_in">
    86400000 <!--value in milliseconds-->
</RefreshTokenExpiresIn>

Default:

2592000000 ms (30 days) (effective May 31, 2023)

Presence:

Optional

Type: Integer
Valid values:
  • Any positive, nozero integer. Specifies the expiry time in milliseconds.
  • -1 will expire as per the maximum OAuth refresh token expiration.

    Note: Specifying any other negative integer or zero causes a deployment error.
Used with grant types:
  • authorization_code
  • password
  • refresh_token

<ResponseType> element

<ResponseType>request.queryparam.response_type</ResponseType>

This element informs Apigee which grant type the client app is requesting. It is used only with the authorization code and implicit grant type flows.

By default, Apigee looks for the response type value in a response_type query parameter. If you wish to override this default behavior, use the <ResponseType> element to configure a flow variable containing the response type value. For example, if you set this element to request.header.response_type, Apigee looks for the response type to be passed in the request header. See also Get OAuth 2.0 tokens.

Default:

request.formparam.response_type (a x-www-form-urlencoded and specified in the request body)

Presence:

Optional. Use this element if you wish to override the default behavior.

Type: String
Valid values: Either code (for the authorization code grant type) or token (for the implicit grant type)
Used with grant types:
  • implicit
  • Also used with the GenerateAuthorizationCode operation.

<ReuseRefreshToken> element

<ReuseRefreshToken>true</ReuseRefreshToken>

When set to true, the existing refresh token is reused until it expires. If false, a new refresh token is issued by Apigee when a valid refresh token is presented.

Default:

false

Presence:

optional

Type: boolean
Valid values:

true or false

Used with grant type:
  • refresh_token

<RFCCompliantRequestResponse> element

<RFCCompliantRequestResponse>[true | false]</RFCCompliantRequestResponse>

When true, the policy complies to RFC6749 standards and enables the following compliant behaviors:

  • Error and non-error responses will include the HTTP Cache-Control response header field to comply with RFC2616 (Hypertext Transfer Protocol -- HTTP/1.1), with a value of no-store in any response containing tokens, credentials, or other sensitive information, as well as the Pragma response header field with a value of no-cache.
  • The expires_in property will be in alpha-numeric format. For consistency, the refresh_token_expires_in will also be alpha-numeric.
  • OAuthV2 responses for token generation, will include the RFC-compliant Bearer header field instead of BearerToken.
  • Error messages in response payloads will be of the format: {"error" : "xxx", "error_description" :"yyy"} for refresh token errors.

Default:

false: By default, the policy allows certain non-RFC-compliant behaviors. For details, see Non-RFC-compliant behavior. Set this element to true to enable RFC compliance.

Presence:

Optional

Type: Boolean
Valid values: true or false
Used with grant types: All

<SecretKey>/<Value>

<SecretKey>
  <Value ref="your-variable-name"/>
</SecretKey>

Provides the secret key used to verify or sign JWT-formatted access tokens with an HMAC algorithm. Use only when the algorithm is one of HS256, HS384, or HS512. Use the ref attribute to pass the key in a flow variable. For more information, see Using JWT OAuth token operations.

Apigee enforces a minimum key strength for the HS256/HS384/HS512 algorithms. The minimum key length for HS256 is 32 bytes, for HS384 it is 48 bytes, and for HS512 it is 64 bytes. Using a lower-strength key causes a runtime error.

Default N/A
Presence Required for HMAC algorithms.
Type String
Valid values A flow variable

<Scope> element

<Scope>request.queryparam.scope</Scope>

If this element is present in one of the GenerateAccessToken or GenerateAuthorizationCode policies, it is used to specify which scopes to grant the token or code. These values are typically passed to the policy in the request from a client app. You can configure the element to take a flow variable, giving you the option to choose how the scopes are passed in a request. In the following example, request.queryparam.scope indicates that the scope should be present as a query parameter, as, for example, ?scope=READ. To require the scope in an HTTP header, for example, set this value to request.header.scope.

If this element appears in a "VerifyAccessToken" policy, then it is used to specify which scopes the policy should enforce. In this type of policy, the value must be a "hard coded" scope name -- you can't use variables. For example:

<Scope>A B</Scope>

See also Working with OAuth2 scopes and Get OAuth 2.0 tokens.

Default:

No scope

Presence:

Optional

Type: String
Valid values:

If used with Generate* policies, a flow variable.

If used with VerifyAccessToken, a space-separated list of scope names (strings).

Used with grant types:
  • authorization_code
  • implicit
  • password
  • client_credentials
  • Can also be used with the GenerateAuthorizationCode and VerifyAccessToken operations.

<State> element

<State>request.queryparam.state</State>

In cases where the client app must send the state information to the authorization server, this element lets you specify where Apigee should look for the state values. For example, it could be sent as a query parameter or in an HTTP header. The state value is typically used as a security measure to prevent CSRF attacks.

For example request.queryparam.state indicates that the state should be present as a query parameter, as, for example, ?state=HjoiuKJH32. To require the state in an HTTP header, for example, set this value to request.header.state. See also See also Get OAuth 2.0 tokens.

Default:

No state

Presence:

Optional

Type: String
Valid values: Any flow variable accessible to the policy at runtime
Used with grant types:
  • All
  • Can also be used with the GenerateAuthorizationCode operation

<StoreToken> element

 <StoreToken>true</StoreToken>

Set this element to true when the <ExternalAuthorization> element is true. The <StoreToken> element tells Apigee to store the external access token. Otherwise, it will not be persisted.

Default:

false

Presence:

Optional

Type: Boolean
Valid values: true or false
Used with grant types:
  • authorization_code
  • password
  • client_credentials

<SupportedGrantTypes>/<GrantType> element

<SupportedGrantTypes>
    <GrantType>authorization_code</GrantType>
    <GrantType>client_credentials</GrantType>
    <GrantType>implicit</GrantType>
    <GrantType>password</GrantType>
</SupportedGrantTypes>

Specifies the grant types supported by an OAuth token endpoint on Apigee. An endpoint may support multiple grant types (that is, a single endpoint can be configured to distribute access tokens for multiple grant types.) For more on endpoints, see Understanding OAuth endpoints. The grant type is passed in token requests in a grant_type parameter.

If no supported grant types are specified, then the only allowed grant types are authorization_code and implicit. See also the <GrantType> element (which is a higher-level element that is used to specify where Apigee should look for the grant_type parameter that is passed in a client request. Apigee will make sure that the value of the grant_type parameter matches one of the supported grant types).

Default:

authorization _code and implicit

Presence:

Required

Type: String
Valid values:
  • client_credentials
  • authorization_code
  • password
  • implicit

<Tokens>/<Token> element

Used with the ValidateToken and InvalidateToken operations. See also Approving and revoking access tokens. The <Token> element identifies the flow variable that defines the source of the token to be revoked. If developers are expected to submit access tokens as query parameters named access_token, for example, use request.queryparam.access_token.

<UserName> element

<UserName>request.queryparam.user_name</UserName>

This element is used with the password grant type only. With the password grant type, user credentials (password and username) must be made available to the OAuthV2 policy. The <PassWord> and <UserName> elements are used to specify variables where Apigee can find these values. If these elements are not specified, the policy expects to find the values (by default) in form parameters named username and password. If the values are not found, the policy throws an error. You can use the <PassWord> and <UserName> elements to reference any flow variable containing the credentials.

For example, you can pass the username in a query parameter and set the <UserName> element like this: <UserName>request.queryparam.username</UserName>.To require the username in an HTTP header, set this value to request.header.username.

The OAuthV2 policy doesn't do anything else with these credential values; Apigee is simply verifying that they are present. It is up to the API developer to retrieve the values request and send them to an identity provider before the token generation policy executes.

See also Get OAuth 2.0 tokens.

Default:

request.formparam.username (a x-www-form-urlencoded and specified in the request body)

Presence:

Optional

Type: String
Valid values: Any variable setting.
Used with grant types: password

Verifying access tokens

Once a token endpoint is set up for an API proxy, a corresponding OAuthV2 policy that specifies the VerifyAccessToken operation is attached to the Flow that exposes the protected resource.

For example, to ensure that all requests to an API are authorized, the following policy enforces access token verification:

<OAuthV2 name="VerifyOAuthAccessToken">
  <Operation>VerifyAccessToken</Operation>
</OAuthV2>

The policy is attached to the API resource to be protected. To ensure that all requests to an API are verified, attach the policy to the ProxyEndpoint request PreFlow, as follows:

<PreFlow>
  <Request>
    <Step><Name>VerifyOAuthAccessToken</Name></Step>
  </Request>
</PreFlow>

The following optional elements can be used to override the default settings for the VerifyAccessToken operation.

Name Description
Scope

A space-delimited list of scopes. Verification will succeed if at least one of the scopes listed is present in the access token. For example, the following policy will check the access token to ensure that it contains at least one of the scopes listed. If READ or WRITE is present, verification will succeed.

<OAuthV2 name="ValidateOauthScopePolicy">
  <Operation>VerifyAccessToken</Operation>
  <Scope>READ WRITE</Scope>
</OAuthV2>
AccessToken The variable where the access token is expected to be located. For example request.queryparam.accesstoken. By default, the access token is expected to be presented by the app in the Authorization HTTP header, according to the OAuth 2.0 specification. Use this setting if the access token is expected to be presented in a non-standard location, such as a query parameter, or an HTTP header with a name other than Authorization.

See also Verifying access tokens and Get OAuth 2.0 tokens.

Specifying request variable locations

For each grant type, the policy makes assumptions about the location or required information in request messages. These assumptions are based on the OAuth 2.0 specification. If your apps need to deviate from the OAuth 2.0 specification, then you can specify the expected locations for each parameter. For example, when handling an authorization code, you can specify the location of the authorization code, the client ID, the redirect URI, and the scope. These can be specified as HTTP headers, query parameters, or form parameters.

The example below demonstrates how you can specify the location of required authorization code parameters as HTTP headers:

  ...
  <GrantType>request.header.grant_type</GrantType>
  <Code>request.header.code</Code>
  <ClientId>request.header.client_id</ClientId>
  <RedirectUri>request.header.redirect_uri</RedirectUri>
  <Scope>request.header.scope</Scope>
  ...

Or, if necessary to support your client app base, you can mix and match headers and query parameters:

  ...
  <GrantType>request.header.grant_type</GrantType>
  <Code>request.header.code</Code>
  <ClientId>request.queryparam.client_id</ClientId>
  <RedirectUri>request.queryparam.redirect_uri</RedirectUri>
  <Scope>request.queryparam.scope</Scope>
  ...

Only one location can be configured per parameter.

Flow variables

The flow variables defined in this table are populated when the respective OAuth policies are executed, and hence are available to other policies or applications executing in the API proxy flow.

VerifyAccessToken operation

When the VerifyAccessToken operation executes, a large number of flow variables are populated in the proxy's execution context. These variables give you properties related to the access token, developer app, and developer. You can use an AssignMessage or JavaScript policy, for example, to read any of these variables and use them as needed later in the flow. These variables can also be useful for debugging purposes.

Token-specific variables

Variables Description
organization_name The name of the organization where the proxy is executing.
developer.id The ID of either the developer or AppGroup associated with the registered client app.
developer.app.name The name of the developer or AppGroup app associated with the registered client app.
client_id The client ID of the registered client app.
grant_type The grant type associated with the request. Not supported for the VerifyJWTAccessToken operation.
token_type The token type associated with the request.
access_token The access token that is being verified.
accesstoken.{custom_attribute} A named custom attribute in the access token.
issued_at The date the access token was issued expressed in Unix epoch time in milliseconds.
expires_in The expiration time for the access token. Expressed in seconds. Although the ExpiresIn element sets the expiration in milliseconds, in the token response and flow variables, the value is expresed in seconds.
status The status of the access token (e.g., approved or revoked).
scope The scope (if any) associated with the access token.
apiproduct.<custom_attribute_name> A named custom attribute of the API product associated with the registered client app.
apiproduct.name The name of the API product associated with the registered client app.
revoke_reason

(Apigee hybrid only) Indicates why the access token is revoked. Not supported for the VerifyJWTAccessToken operation.

Value can be REVOKED_BY_APP, REVOKED_BY_ENDUSER, REVOKED_BY_APP_ENDUSER, or TOKEN_REVOKED.

App-specific variables

These variables are related to the Developer App that is associated with the token.

Variables Description
app.name
app.id
app.accessType
app.callbackUrl
app.status approved or revoked
app.scopes
app.appFamily
app.apiproducts
app.appParentStatus
app.appType For example: Developer
app.appParentId
app.created_by
app.created_at
app.last_modified_at
app.last_modified_by
app.{custom_attributes} A named custom attribute of the registered client app.

AppGroup-specific variables

The following flow variables containing information about the AppGroup for the token and are populated by the policy. These AppGroup attributes populate only if verifyapikey.{policy_name}.app.appType is "AppGroup".

Variables Description
appgroup.displayName The AppGroup display name.
appgroup.name Name of the AppGroup.
appgroup.id The AppGroup ID.
appOwnerStatus The status of the app owner: 'active', 'inactive', or 'login_lock'.
created_at The date/time stamp when the AppGroup was created.
created_by The email address of the developer who created the AppGroup.
last_modified_at The date/time stamp when the AppGroup was last modified.
last_modified_by The email address of the developer who last modified the AppGroup.
{appgroup_custom_attributes} Any custom AppGroup attribute. Specify the name of the custom attribute.

Developer-specific variables

If the app.appType is "Developer", then developer attributes are populated.

Variables Description
Developer-specific variables
developer.id
developer.userName
developer.firstName
developer.lastName
developer.email
developer.status active or inactive
developer.apps
developer.created_by
developer.created_at
developer.last_modified_at
developer.last_modified_by
developer.{custom_attributes} A named custom attribute of the developer.

GenerateAuthorizationCode operation

These variables are set when the GenerateAuthorizationCode operation executes successfully:

Prefix: oauthv2authcode.{policy_name}.{variable_name}

Example: oauthv2authcode.GenerateCodePolicy.code

Variable Description
code The authorization code generated when the policy executes.
redirect_uri The redirect URI associated with the registered client app.
scope The optional OAuth scope passed in the client request.
client_id The client ID passed in the client request.

GenerateAccessToken and RefreshAccessToken operations

These variables are set when the GenerateAccessToken and RefreshAccessToken operations execute successfully. Note that refresh token variables do not apply for the client credentials grant type flow.

Prefix: oauthv2accesstoken.{policy_name}.{variable_name}

Example: oauthv2accesstoken.GenerateTokenPolicy.access_token

Variable name Description
access_token The access token that was generated.
client_id The client ID of the developer app associated with this token.
expires_in The expiry value for the token. See the <ExpiresIn> element for details. Note that in the response, expires_in is expressed in seconds.
scope List of available scopes configured for the token. See Working with OAuth2 scopes.
status Either approved or revoked.
token_type Is set to BearerToken.
developer.email The email address of the registered developer who owns the developer app associated with the token.
organization_name The org where the proxy executes.
api_product_list A list of the products associated with the token's corresponding developer app.
refresh_count
refresh_token The refresh token that was generated. Note that refresh tokens are not generated for the client credentials grant type.
refresh_token_expires_in The lifespan of the refresh token, in seconds.
refresh_token_issued_at This time value is the string representation of the corresponding 32-bit timestamp quantity. For example, 'Wed, 21 Aug 2013 19:16:47 UTC' corresponds to the timestamp value of 1377112607413.
refresh_token_status Either approved or revoked.

GenerateAccessTokenImplicitGrant

These variables are set when the GenerateAccessTokenImplicit operation executes successfully for the implicit grant type flow.

Prefix: oauthv2accesstoken.{policy_name}.{variable_name}

Example: oauthv2accesstoken.RefreshTokenPolicy.access_token

Variable Description
oauthv2accesstoken.access_token The access token generated when the policy executes.
oauthv2accesstoken.{policy_name}.expires_in The expiry value for the token, in seconds. See the <ExpiresIn> element for details.

Error reference

This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, see What you need to know about policy errors and Handling faults.

Runtime errors

These errors can occur when the policy executes.

Fault code HTTP status Cause Thrown by operations
steps.oauth.v2.access_token_expired 401 The access token is expired.

VerifyAccessToken
InvalidateToken

steps.oauth.v2.access_token_not_approved 401 The access token was revoked. VerifyAccessToken
steps.oauth.v2.apiresource_doesnot_exist 401 The requested resource does not exist any of the API products associated with the access token. VerifyAccessToken
steps.oauth.v2.FailedToResolveAccessToken 500 The policy expected to find an access token in a variable specified in the <AccessToken> element, but the variable could not be resolved. GenerateAccessToken
steps.oauth.v2.FailedToResolveAuthorizationCode 500 The policy expected to find an authorization code in a variable specified in the <Code> element, but the variable could not be resolved. GenerateAuthorizationCode
steps.oauth.v2.FailedToResolveClientId 500 The policy expected to find the Client ID in a variable specified in the <ClientId> element, but the variable could not be resolved. GenerateAccessToken
GenerateAuthorizationCode
GenerateAccessTokenImplicitGrant
RefreshAccessToken
steps.oauth.v2.FailedToResolveRefreshToken 500 The policy expected to find a refresh token in a variable specified in the <RefreshToken> element, but the variable could not be resolved. RefreshAccessToken
steps.oauth.v2.FailedToResolveToken 500 The policy expected to find a token in a variable specified in the <Tokens> element, but the variable could not be resolved.

ValidateToken
InvalidateToken

steps.oauth.v2.InsufficientScope 403 The access token presented in the request has a scope that does not match the scope specified in the verify access token policy. To learn about scope, see Working with OAuth2 scopes. VerifyAccessToken
steps.oauth.v2.invalid_access_token 401 The access token sent from the client is invalid. VerifyAccessToken
steps.oauth.v2.invalid_client 401

This error name is returned when the <GenerateResponse> property of the policy is set to true and the client ID sent in the request is invalid. Check to be sure you are using the correct client key and secret values for the Developer App associated with your proxy. Typically, these values are sent as a Base64 encoded Basic Authorization header.

GenerateAccessToken
RefreshAccessToken
steps.oauth.v2.invalid_request 400 This error name is used for multiple different kinds of errors, typically for missing or incorrect parameters sent in the request. If <GenerateResponse> is set to false, use fault variables (described below) to retrieve details about the error, such as the fault name and cause. GenerateAccessToken
GenerateAuthorizationCode
GenerateAccessTokenImplicitGrant
RefreshAccessToken
steps.oauth.v2.InvalidAccessToken 401 The authorization header does not have the word Bearer, which is required. For example: Authorization: Bearer your_access_token VerifyAccessToken
steps.oauth.v2.InvalidAPICallAsNo\
ApiProductMatchFound
401

The currently executing API proxy or operation is not in the Product associated with the access token.

Tips: Be sure that the product associated with the access token is configured correctly. For example, if you use wildcards in resource paths, be sure the wildcards are being used correctly. See Managing API products for details.

See also Oauth2.0 Access Token Verification throws "Invalid API call as no apiproduct match found" error for more guidance on causes for this error.

VerifyAccessToken
steps.oauth.v2.InvalidClientIdentifier 500

This error name is returned when the <GenerateResponse> property of the policy is set to false and the client ID sent in the request is invalid. Check to be sure you are using the correct client key and secret values for the Developer App associated with your proxy. Typically, these values are sent as a Base64 encoded Basic Authorization header.

GenerateAccessToken
RefreshAccessToken

steps.oauth.v2.InvalidParameter 500 The policy must specify either an access token or an authorization code, but not both. GenerateAuthorizationCode
GenerateAccessTokenImplicitGrant
steps.oauth.v2.InvalidTokenType 500 The <Tokens>/<Token> element requires you to specify the token type (for example, refreshtoken). If the client passes the wrong type, this error is thrown. ValidateToken
InvalidateToken
steps.oauth.v2.MissingParameter 500 The response type is token, but no grant types are specified. GenerateAuthorizationCode
GenerateAccessTokenImplicitGrant
steps.oauth.v2.UnSupportedGrantType 500

The client specified a grant type that is unsupported by the policy (not listed in the <SupportedGrantTypes> element).

GenerateAccessToken
GenerateAuthorizationCode
GenerateAccessTokenImplicitGrant
RefreshAccessToken

JWT token-specific runtime errors

Runtime error codes and descriptions for JWT auth token flows depend on the OAuth2 flow context:

Error codes for JWT token generation and refresh flows

For OAuth2 flows that generate or refresh JWT tokens, error responses adhere to the error responses specified in RFC6749. For details, see Section 5.2 Error Response.

Error codes for the token verification flow

The error codes listed in the following table apply to VerifyAccessToken operation only.

Fault code HTTP status Cause Thrown by operations
oauth.v2.JWTSigningFailed 401 The policy was unable to sign the JWT.

GenerateJWTAccessToken

oauth.v2.InvalidValueForJWTAlgorithm 401 This occurs when the algorithm is not present in the JWT access token or when the value is not supported.

GenerateJWTAccessToken
VerifyJWTAccessToken

oauth.v2.InsufficientKeyLength 401 In Generation of JWT, for a key less than the minimum size for the HS384 or HS512 algorithms

GenerateJWTAccessToken
VerifyJWTAccessToken

oauth.v2.JWTAlgorithmMismatch 401 The algorithm specified in the Generate policy did not match the one expected in the Verify policy. The algorithms specified must match.

VerifyJWTAccessToken

oauth.v2.JWTDecodingFailed 401 The policy was unable to decode the JWT. The JWT is possibly corrupted.

VerifyJWTAccessToken

oauth.v2.MissingMandatoryClaimsInJWT 401 Occurs when the required claims are not present in the Jwt Access token

VerifyJWTAccessToken

oauth.v2.InvalidJWTSignature 401 This occurs when the signature of JWT access token could not be verified or when the signature is invalid.

VerifyJWTAccessToken

oauth.v2.InvalidTypeInJWTHeader 401 Occurs when the JWT's type is not at+Jwt

VerifyJWTAccessToken

Deployment errors

These errors can occur when you deploy a proxy containing this policy.

Error name Cause
InvalidValueForExpiresIn

For the <ExpiresIn> element, valid values are positive integers and -1.

InvalidValueForRefreshTokenExpiresIn For the <RefreshTokenExpiresIn> element, valid values are positive integers and -1.
InvalidGrantType An invalid grant type is specified in the <SupportedGrantTypes> element. See the policy reference for a list of valid types.
ExpiresInNotApplicableForOperation Be sure that the operations specified in the <Operations> element support expiration. For example, the VerifyToken operation does not.
RefreshTokenExpiresInNotApplicableForOperation Be sure that the operations specified in the <Operations> element support refresh token expiration. For example, the VerifyToken operation does not.
GrantTypesNotApplicableForOperation Be sure that the grant types specified in <SupportedGrantTypes> are supported for the specified operation.
OperationRequired

You must specify an operation in this policy using the <Operation> element.

InvalidOperation

You must specify a valid operation in this policy using the <Operation> element.

TokenValueRequired You must specify a token <Token> value in the <Tokens> element.

JWT token-specific deployment errors

These deployment errors are specific to policies that use JWT token operations.

Error name Cause
InvalidValueForAlgorithm The algorithm specified in the <Algorithm> element is not among the list of available algorithms or is not present.
MissingKeyConfiguration The required <SecretKey>, <PrivateKey>, or <PublicKey> elements are missing, depending on which algorithm is used.
EmptyValueElementForKeyConfiguration The required child element <Value> is not defined in the <PrivateKey>, <PublicKey>, or <SecretKey> elements
InvalidKeyConfiguration The <PrivateKey> element is not used with RSA family algorithms or the <SecretKey> element is not used with HS Family algorithms.
EmptyRefAttributeForKeyconfiguration The ref attribute of the child element <Value> of the <PrivateKey>, <PublicKey> or <SecretKey> elements is empty.
InvalidVariableNameForKey The flow variable name specified in the ref attribute of the child element <Value> of the <PrivateKey>, <PublicKey> or <SecretKey> elements does not contain the private prefix.

Fault variables

These variables are set when this policy triggers an error at runtime.

Variables Where Example
fault.name="fault_name" fault_name is the name of the fault, as listed in the Runtime errors table above. The fault name is the last part of the fault code. fault.name = "invalid_request"
oauthV2.policy_name.failed policy_name is the user-specified name of the policy that threw the fault. oauthV2.GenerateAccesstoken.failed = true
oauthV2.policy_name.fault.name policy_name is the user-specified name of the policy that threw the fault. oauthV2.GenerateAccesstoken.fault.name = invalid_request
oauthV2.policy_name.fault.cause policy_name is the user-specified name of the policy that threw the fault. oauthV2.GenerateAccesstoken.cause = Required param : grant_type

Example error response

These responses are sent back to the client if the <GenerateResponse> element is true.

If <GenerateResponse> is true, the policy returns errors in this format for operations that generate tokens and codes. For a complete list, see see OAuth HTTP error response reference.

{"ErrorCode" : "invalid_client", "Error" :"ClientId is Invalid"}

If <GenerateResponse> is true, the policy returns errors in this format for verify and validate operations. For a complete list, see see OAuth HTTP error response reference.

{  
   {  
      "fault":{  
         "faultstring":"Invalid Access Token",
         "detail":{  
            "errorcode":"keymanagement.service.invalid_access_token"
         }
      }
   }

Example fault rule

<FaultRule name="OAuthV2 Faults">
    <Step>
        <Name>AM-InvalidClientResponse</Name>
        <Condition>(fault.name = "invalid_client") OR (fault.name = "InvalidClientIdentifier")</Condition>
    </Step>
    <Step>
        <Name>AM-InvalidTokenResponse</Name>
        <Condition>(fault.name = "invalid_access_token")</Condition>
    </Step>
    <Condition>(oauthV2.failed = true) </Condition>
</FaultRule>

Tokens in Storage are Hashed

If you're using Apigee hybrid or Apigee, the OAuthV2 access tokens and refresh tokens are hashed by default when stored in the runtime Cassandra database. Hashing prevents the tokens from being used if the database were compromised.

Working with the default OAuth configuration

Each organization (even a free trial org) on Apigee is provisioned with an OAuth token endpoint. The endpoint is preconfigured with policies in the API proxy called oauth. You can begin using the token endpoint as soon as you create an account on Apigee. For details, see Understanding OAuth endpoints.

Purging access tokens

By default, OAuth2 tokens are purged from the Apigee system 3 days (259200 seconds) after both the access token and refresh token (if it exists) have expired.

Non-RFC-compliant behavior

By default, the OAuthV2 policy, with the GenerateAccessToken operation, returns a token response that contains certain non-RFC-compliant properties. The following table shows the non-compliant properties returned by the OAuthV2 policy and the corresponding compliant properties.

OAuthV2 returns: The RFC-compliant property is:
"token_type":"BearerToken" "token_type":"Bearer"
"expires_in":"3600" "expires_in":3600

(The compliant value is a number, not a string.)

Also, the error response for an expired refresh token when grant_type = refresh_token is:

{"ErrorCode" : "invalid_request", "Error" :"Refresh Token expired"}

However, the RFC-compliant response is:

{"error" : "invalid_grant", "error_description" :"refresh token expired"}

Related topics