Validating Tokens to Add Authentication and Authorization to API Deployments

You can add authentication and authorization functionality to an API gateway by having the API gateway itself validate the tokens included in a request (as described in this topic). Alternatively, you can have the API gateway pass a multi-argument or single-argument access token included in a request to an authorizer function deployed on OCI Functions for validation (as described in Passing Tokens to Authorizer Functions to Add Authentication and Authorization to API Deployments).

To have the API gateway itself validate the token included in a request, you create an authentication request policy of type TOKEN_AUTHENTICATION. The tokens you use to control access to APIs are often, but not always, JSON Web Tokens (JWTs).

When using a TOKEN_AUTHENTICATION policy, you enable an API deployment to use tokens for authentication and authorization by including two different kinds of request policy in the API deployment specification:

  • An authentication request policy for the entire API deployment that specifies the use of tokens, including how to validate them and whether unauthenticated end users can access routes in the API deployment.
  • An authorization request policy for each route that specifies the operations an end user is allowed to perform, optionally based on values specified for the scope claim of a JWT.

You can add authentication and authorization request policies to an API deployment specification by:

  • Using the Console.
  • Editing a JSON file.
Note

In earlier releases, you created authentication request policies of type JWT_AUTHENTICATION to use JWTs for authentication. Existing JWT_AUTHENTICATION authentication request policies are still supported (see Notes about the use of JWT_AUTHENTICATION request policies). However, if you are creating new authentication request policies to authenticate JWTs, we recommend you create authentication request policies as TOKEN_AUTHENTICATION policies. Using TOKEN_AUTHENTICATION policies enables you to:

  • Validate both JWT tokens and non-JWT tokens.
  • Validate tokens using an identity provider to obtain an introspection endpoint.
  • Specify validation failure policies, including the generation of a new JWT token in the event of an invalid or missing JWT token in the original request.

What happens during token authentication?

When an API gateway receives a request from an API client and you have specified a token authentication policy, the API gateway locates a token (for example, in a token header) and uses that token.

You specify how the API gateway validates the token it has obtained by defining the token authentication policy's validation policy to be one of the following types:

  • OAuth 2.0 introspection endpoint: Specify this type of validation policy if you want the API gateway to validate a JWT or non-JWT token with the introspection endpoint of an identity provider. You have to specify the Discovery URL of the identity provider from which to obtain the introspection endpoint. In this case, the API gateway passes the client credentials (the client id, along with the client secret retrieved from the Vault service) to the identity provider to validate the token. The token is validated without the use of public keys. To make future validation faster, you can specify that you want the API gateway to cache the response from the introspection endpoint, for between 1 hour (the default) and 24 hours. If you're defining the API deployment specification in a JSON file and you want this behavior, include a validation policy of type REMOTE_DISCOVERY.
  • Remote JWKS: Specify this type of validation policy if you want the API gateway to use public verification keys retrieved from an identity provider at runtime to verify a JWT. In this case, the API gateway contacts the identity provider to verify the JWT. The identity provider acts as the authorization server. If you're defining the API deployment specification in a JSON file and you want this behavior, include a validation policy of type REMOTE_JWKS.
  • Static keys: Specify this type of validation policy if you want the API gateway to use public verification keys already issued by an identity provider (referred to as 'static keys') to verify a JWT. In this case, the API gateway can verify the JWT locally at runtime without having to contact the identity provider. The result is faster token validation. If you're defining the API deployment specification in a JSON file and you want this behavior, include a validation policy of type STATIC_KEYS

If validation succeeds, the API gateway routes the request to the appropriate API endpoint.

If validation fails due to an invalid or missing token in the original request, you specify the API gateway behavior by defining the token authentication policy's validation failure policy to be one of the following types:

  • Default (HTTP 401 Unauthorized): Specify this type of validation failure policy if you want the API gateway to return an HTTP-401 response to the API client. This is the default response. If you're defining the API deployment specification in a JSON file and you want this behavior, simply don't include a validation failure policy.
  • Custom response: Specify this type of validation failure policy if you want the API gateway to return an alternative response (a modified response) to the API client, instead of an HTTP-401 response. If you're defining the API deployment specification in a JSON file and you want this behavior, include a validation failure policy of type MODIFY_RESPONSE.
  • OAuth 2.0: Specify this type of validation failure policy if you want the API gateway to obtain a new and valid JWT token from the identity provider for GET requests (having first securely stored the original request query parameters). For PUT requests and POST requests, you can specify a relative path in the current API deployment to which to redirect API clients. Using this type of validation failure policy, you can also define a logout back end to remove any associated session cookies, revoke tokens by calling the identity provider's end session endpoint, and redirect to an allowed post-logout URL. If you're defining the API deployment specification in a JSON file and you want this behavior, include a validation failure policy of type OAUTH2.

    Note that validation failure policies of type OAuth 2.0 currently support only the OpenID Connect authorization flow, and only JWT token generation (see Notes about OAuth 2.0 and OpenID Connect). In the case of the OpenID Connect authorization flow, two tokens named id_token (always JWT-encoded) and access_token (can be JWT-encoded) are returned. The API gateway saves the token values in the request.auth[id_token] and request.auth[access_token] context variables, along with custom claims in the request.auth[id_token_claims][<claim-name>] and request.auth[access_token_claims][<claim-name>] context variables respectively (see Adding Context Variables to Policies and HTTP Back End Definitions). On receipt of the new id_token JWT token, the API gateway retrieves the request details and resumes request processing using the token.

The location from which the API gateway obtains a token depends on both the type of validation policy (one of OAuth 2.0 introspection endpoint, Remote JWKS, or Static keys) and the type of validation failure policy (one of Default (HTTP 401 Unauthorized), Custom response, or OAuth 2.0), as follows:

  • If you specify both a validation policy of type OAuth 2.0 introspection endpoint and a validation failure policy of type OAuth 2.0, the API gateway initially attempts to obtain the token from one or other of the following:
    • If you selected the Use cookies for session option in the validation failure policy, from a session cookie.
    • Otherwise, from the X-APIGW-TOKEN header in the request.

    If the API gateway cannot obtain a token from the initial location, the API gateway obtains the token from the request header or query parameter you specify in the token authentication policy.

    If token validation is subsequently successful and you selected the Use cookies for session option, the API gateway stores the generated token as a non-human-readable string in a session cookie. If the API client makes a subsequent request, the token is obtained from the session cookie. To prevent CSRF attacks, when the generated token is stored in a session cookie, the API gateway also returns a CSRF token in an X-CSRF-TOKEN response header (see Notes about Cross-Site Request Forgery (CSRF) Protection).

  • If you do not specify both a validation policy of type OAuth 2.0 introspection endpoint and a validation failure policy of type OAuth 2.0, the API gateway obtains the token from the request header or query parameter you specify in the token authentication policy.

Notes about JSON Web Tokens (JWTs)

The tokens you use to control access to APIs are typically JSON Web Tokens (JWTs). A JWT is a JSON-based access token sent in an HTTP request from an API client to a resource. JWTs are issued by identity providers. API Gateway supports the use of any OAuth2-compliant identity provider, such as OCI IAM with Identity Domains, Oracle Identity Cloud Service (IDCS), Auth0, and Okta. If a JWT is required to access a resource, the resource validates the JWT with an authorization server using a corresponding public verification key, either by invoking a validation end-point on the authorization server or by using a local verification key provided by the authorization server.

A JWT comprises:

  • A header, which identifies the type of token and the cryptographic algorithm used to generate the signature.
  • A payload, containing claims about the end user's identity, and the properties of the JWT itself. A claim is a key value pair, where the key is the name of the claim. A payload is recommended (although not required) to contain certain reserved claims with particular names, such as expiration time (exp), audience (aud), issuer (iss), and not before (nbf). A payload can also contain custom claims with user-defined names.
  • A signature, to validate the authenticity of the JWT (derived by base64 encoding the header and the payload).

When using JWTs to control access to APIs, you can specify that reserved claims in the JWT's payload must have particular values before the API gateway considers the JWT to be valid. By default, API gateways validate JWTs using the expiration (exp), audience (aud), and issuer (iss) claims, along with the not before (nbf) claim if present. You can also specify acceptable values for custom claims. See Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI.

When a JWT has been validated, the API gateway extracts claims from the JWT's payload as key value pairs and saves them as records in the request.auth context table for use by the API deployment.  For example, as context variables for use in an HTTP back end definition (see Adding Context Variables to Policies and HTTP Back End Definitions). If the JWT's payload contains the scope claim, you can use the claim's values in authorization request policies for individual routes to specify the operations an end user is allowed to perform.

Notes about OAuth 2.0 and OpenID Connect

The OAuth 2.0 protocol enables the safe retrieval of secure resources while protecting client credentials. OAuth 2.0 is a flexible and secure protocol that relies on SSL (Secure Sockets Layer) to ensure data between web servers and browsers remain private. Although OAuth 2.0 is different to JWT, and used for different purposes, OAuth 2.0 and JWT are compatible. Since the OAuth2 protocol does not specify the format of tokens, JWTs can be incorporated into the usage of OAuth2. For more information about OAuth 2.0, see the OAuth 2.0 documentation.

OpenID Connect is a simple identity layer on top of the OAuth 2.0 protocol. Using OpenID Connect enables API gateways to verify the identity of an API client based on authentication performed by an authorization server. OpenID Connect also enables API gateways to obtain basic profile information about the API client. For more information about OpenID Connect, see the OpenID Connect documentation.

Notes about Cross-Site Request Forgery (CSRF) Protection

An attacker can mount a CSRF attack by exploiting the existence of a browser cookie to cause a user to submit an unintended command to a web application, such as an API gateway. If the application determines the user has already been authenticated successfully because of the browser cookie's existence, the application executes the command with potentially damaging consequences.

When you define a validation policy of type OAuth 2.0 introspection endpoint and a validation failure policy of type OAuth 2.0, you specify how an API gateway stores a new JWT token it has obtained using the OpenID Connect authorization flow:

  • Select the Use cookies for session option if you want to store the new JWT token in a session cookie. To prevent potential CSRF attacks, when the API gateway stores the token in a session cookie, it also returns a CSRF token in an X-CSRF-TOKEN response header. Subsequent mutation requests to the API gateway (such as POST, PUT, and DELETE requests, but not GET requests) must include the CSRF token in an X-CSRF-TOKEN request header, in addition to the JWT token in the session cookie that is included automatically.

    Note that the API gateway also stores the CSRF token in the request.auth[apigw_csrf_token] context variable. If the API client is unable to read the initial X-CSRF-TOKEN response header for some reason, you can include the request.auth[apigw_csrf_token] context variable in a header transformation response policy to add a response header containing the CSRF token to every response returned to the API client. This approach ensures the API client can successfully extract the CSRF token from the response header for inclusion in subsequent X-CSRF-TOKEN mutation request headers it sends to the API gateway. Here's an example of a suitable header transformation response policy:

    "responsePolicies": {
            "headerTransformations": {
              "setHeaders": {
                "items": [
                  {
                    "name": "MY-CSRF-TOKEN",
                    "values": ["${request.auth[apigw_csrf_token]}"],
                    "ifExists": "OVERWRITE"              }
                ]
              }
            }
          }

    For more information about header transformation response policies, see Adding Header Transformation Response Policies.

  • Do not select the Use cookies for session option if you do not want to store the new JWT token in a session cookie. Instead, the API gateway returns a non-human-readable token in an X-APIGW-TOKEN response header. Subsequent requests to the API gateway must include the same token in an X-APIGW-TOKEN request header.

For more information about CSRF, search online.

Notes about the use of JWT_AUTHENTICATION request policies

In earlier releases, you might have created authentication request policies of type JWT_AUTHENTICATION to use JWTs for authentication.

If you are creating new authentication request policies to use JWTs, we now recommend you create authentication request policies of type TOKEN_AUTHENTICATION instead (see Using the Console to Add Token Authentication and Authorization Request Policies and Editing a JSON File to Add Token Authentication and Authorization Request Policies). We also recommend you migrate existing JWT_AUTHENTICATION request policies to TOKEN_AUTHENTICATION policies.

Note that existing JWT_AUTHENTICATION request policies are currently still supported. Also note that although you can create new JWT_AUTHENTICATION request policies (as described in the original instructions in the section Using a JWT_AUTHENTICATION Authentication Request Policy (no longer recommended)), we recommend you create authentication request policies of type TOKEN_AUTHENTICATION instead.

Prerequisites for Token Authentication

Before you can enable authentication and authorization for API deployments using JWTs:

  • An OAuth2-compliant identity provider (for example, OCI IAM with Identity Domains, Oracle Identity Cloud Service (IDCS), Auth0) must have already been set up to issue JWTs for users allowed to access the API deployment.
  • If you want to use custom claims in authorization policies, the identity provider must be set up to add the custom claims to the JWTs it issues.

See the identity provider documentation for more information (for example, the OCI IAM with Identity Domains documentation, the Oracle Identity Cloud Service (IDCS) documentation, the Auth0 documentation).

To validate a JWT using a corresponding public verification key provided by the issuing identity provider:

  • the signing algorithm used to generate the JWT's signature must be one of RS256, RS384, or RS512
  • the public verification key must have a minimum length of 2048 bits and must not exceed 4096 bits

To validate tokens using an authorization server's introspection endpoint:

Using the Console to Add Token Authentication and Authorization Request Policies

To add authentication and authorization request policies to an API deployment specification using the Console:

  1. Create or update an API deployment using the Console, select the From Scratch option, and enter details on the Basic Information page.

    For more information, see Deploying an API on an API Gateway by Creating an API Deployment and Updating an API Gateway or an API Deployment.

  2. Click Next to display the Authentication page.
  3. Select Single Authentication to specify that you want to use a single authentication server for all requests.

    These instructions assume you want to use a single authentication server. Alternatively, if you want to use multiple authentication servers, select Multi-Authentication and follow the instructions in Using the Console to Add Multiple Authentication Servers to the same API Deployment.

  4. Select or deselect the Enable Anonymous Access: checkbox to specify whether unauthenticated (that is, anonymous) end users can access routes in the API deployment.

    By default, this option is not selected. If you never want anonymous users to be able to access routes, don't select this option. Note that if you do select this option, you also have to explicitly specify every route to which anonymous access is allowed by selecting Anonymous as the Authorization Type in each route's authorization policy.

  5. Select OAuth 2.0 / OpenID Connect from the Authentication type option list and specify:
    • Token location: Whether tokens are contained in a request header or a query parameter.
    • Authentication token details: Depending on whether tokens are contained in a request header or a query parameter, specify:

      • Token header name: and Authentication scheme: If tokens are contained in a request header, enter the name of the header (for example Authorization), and the HTTP authentication scheme (only Bearer is currently supported).
      • Token parameter name: If tokens are contained in a query parameter, enter the name of the query parameter.
  6. Specify how you want the API gateway to validate tokens:
    1. If you want the API gateway to validate both JWT tokens and non-JWT tokens with an OAuth 2.0 authorization server's introspection endpoint using client credentials (including a client secret retrieved from a vault in the Vault service), select OAuth 2.0 introspection endpoint from the Type list and specify:

      • Client ID: The client ID to send to the introspection endpoint. You obtain a client ID by creating and registering a client application with the authorization server. For example, 5hsti38yhy5j2a4tas455rsu6ru8yui3wrst4n1 . See Prerequisites for Token Authentication.
      • Vault in <compartment-name>: The name of a vault in the Vault service that contains the client secret to send to the introspection endpoint. You obtain a client secret by creating and registering a client application with the authorization server. See Prerequisites for Token Authentication.
      • Vault secret in <compartment name>: The name of a vault secret that contains the client secret to send to the introspection endpoint.
      • Vault secret version number: The version of the vault secret that contains the client secret to send to the introspection endpoint.
      • Discovery URL: The well-known URL of the authorization server from which the API gateway is to obtain authorization metadata endpoints. For example, https://my-idp/oauth2/default/.well-known/openid-configuration.

        Note the URL must be routable from the subnet containing the API gateway on which the API is deployed.

      • Maximum cache duration in hours: The number of hours (between 1 and 24) the API gateway is to cache the response from the introspection endpoint.
      • Max clock skew in seconds: (Optional) The maximum time difference between the system clocks of the authorization server that issued a token and the API gateway. The value you enter here is taken into account when the API gateway validates a JWT to determine whether it is still valid, using the not before (nbf) claim (if present) and the expiration (exp) claim in the JWT. The minimum (and default) is 0, the maximum is 120.
      • Disable SSL verification: Whether to disable SSL verification when communicating with the authorization server. By default, this option is not selected. Oracle recommends not selecting this option because it can compromise token validation. API Gateway trusts certificates from multiple Certificate Authorities issued for OCI IAM with Identity Domains, Oracle Identity Cloud Service (IDCS), Auth0, and Okta.
    2. If you want the API gateway to validate JWTs by retrieving public verification keys from the identity provider at runtime, select Remote JWKS from the Type list and specify:

      • JWKS URI: The URI from which to retrieve the JSON Web Key Set (JWKS) to use to verify the signature on JWTs. For example, https://www.somejwksprovider.com/oauth2/v3/certs. For more information about the URI to specify, see Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI.

        Note the following:

        • The URI must be routable from the subnet containing the API gateway on which the API is deployed.

        • If the API gateway fails to retrieve the JWKS, all requests to the API deployment will return an HTTP 500 response code. Refer to the API gateway's execution log for more information about the error (see Adding Logging to API Deployments).
        • Certain key parameters must be present in the JWKS to verify the JWT's signature (see Key Parameters Required to Verify JWT Signatures).
        • The JWKS can contain up to ten keys.
      • Maximum cache duration in hours: The number of hours (between 1 and 24) the API gateway is to cache the JWKS after retrieving it.
      • Disable SSL verification: Whether to disable SSL verification when communicating with the identity provider. By default, this option is not selected. Oracle recommends not selecting this option because it can compromise JWT validation. API Gateway trusts certificates from multiple Certificate Authorities issued for OCI IAM with Identity Domains, Oracle Identity Cloud Service (IDCS), Auth0, and Okta.
    3. If you want the API gateway to validate JWTs with public verification keys already issued by an identity provider (enabling the API gateway to verify JWTs locally without having to contact the identity provider), select Static keys from the Type list and specify up to ten static keys:

      • Key ID: The identifier of the static key used to sign the JWT. The value must match the kid claim in the JWT header. For example, master_key.
      • Key format: The format of the static key, as either a JSON Web Key or a PEM-encoded Public Key.

        • JSON web key: If the static key is a JSON Web Key, paste the key into this field.

          For example:

          {
            "kty": "RSA",
            "n": "0vx7agoebGc...KnqDKgw",
            "e": "AQAB",
            "alg": "RS256",
            "use": "sig"
          }
          

          Note that certain parameters must be present in the static key to verify the JWT's signature (see Key Parameters Required to Verify JWT Signatures). Also note that RSA is currently the only supported key type (kty).

        • PEM-encoded public key: If the static key is a PEM-encoded public key, paste the key into this field. For example:

          -----BEGIN PUBLIC KEY-----
          XsEiCeYgglwW/KAhSSNRVdD60QlXYMWHOhXzSFDZCLf1WXxKMZCiMvVrsBIzmFEXnFmcsO2mxwlL5/8qQudomoP+yycJ2gWPIgqsZcQRheJWxVC5ep0MeEHlvLnEvCi9utpAnjrsZCQ7plfZVPX7XORvezwqQhBfYzwA27M2FgOOs8DOIYfqQ1Ki3DMqEppFnjLcjgQtknbTlT7YgG6tzobwig8M2KIrPjJ0BmbJAFH
          -----END PUBLIC KEY-----
          

          Note that the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- markers are required.

      • Another key: Click to add additional keys (up to a maximum of ten).
  7. (Optional) Specify additional details for JWT token validation:
    1. In the Issuers section, specify values that are allowed in the issuer (iss) claim of a JWT being used to access the API deployment:

      • Allowed Issuers: Specify the URL (or a text string) for an identity provider that is allowed in the issuer (iss) claim of a JWT to be used to access the API deployment. For example, to enable a JWT issued by OCI IAM with Identity Domains to be used to access the API deployment, enter https://identity.oraclecloud.com/ . See Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI.
      • Another Issuer: Click to add additional identity providers (up to a maximum of five).
    2. In the Audiences section, specify values that are allowed in the audience (aud) claim of a JWT being used to access the API deployment :

    3. Claims validation: (Optional) In addition to the values for the audience aud and issuer iss claims that you already specified, you can specify names and values for one or more additional claims to validate in a JWT. Note that any key names and values you enter are simply handled as strings, and must match exactly with names and values in the JWT. Pattern matching and other datatypes are not supported.

      • Claim is required: Specify whether the claim in the Claim key field must be included in the JWT.
      • Claim key: (Optional) Specify the name of a claim that can be, or must be, included in a JWT. If the claim must be included in the JWT, select Required. The claim name you specify can be a reserved claim name such as the subject (sub) claim, or a custom claim name issued by a particular identity provider.
      • Claim values: (Optional) Specify an acceptable value for the claim in the Claim key field. Click the plus sign (+) to enter another acceptable value. If you specify one or more acceptable values for the claim, the API gateway validates that the claim has one of the values you specify.

      Note that you can specify a claim in a JWT without specifying a value for it. To do so, enter the claim's name in the Claim key field, leave the Claim values field blank, and set Claim is required as appropriate.

  8. Specify how you want the API gateway to handle a failed authentication response (returned after an unsuccessful attempt to validate a missing or invalid token) by setting up a validation failure policy:
    1. If you want the API gateway to send an HTTP 401 status code and the WWW-Authenticate header in the response (the default response to a missing or invalid token), select Default (HTTP 401 Unauthorized).
    2. If you want the API gateway to use an OpenID Connect authorization flow to obtain a new JWT access token, select OAuth 2.0. Note that this option is only available if you selected OAuth 2.0 introspection endpoint from the Validation Type list earlier. Specify:

      • Scopes: One or more access scopes to include in a scope claim sent to the authorization server. To use the OpenID Connect authorization flow, you must include openid as one of the scopes. For example, openid, email:read, profile.
      • Response type: The type of response required from the authorization flow. Enter code as the response type.
      • Fallback redirect path: (optional) A relative path in the current API deployment to which to redirect API clients if the original request was a PUT request or a POST request. For example, /home

        If the original request was a GET request, request processing resumes with a new JWT access token, so a fallback path is not used.

      • Logout path: (optional) A relative path to a logout back end in the current API deployment. The path you specify must match the route path defined for the logout back end. For example, /revoke

        An API client can call the logout back end to revoke tokens. A call to the logout back end can include a post-logout URL as a query parameter named postLogoutUrl. See Adding Logout as an API Gateway Back End.

      • Response expiry in seconds: (optional) The length of time to cache the JWT token generated by the authorization flow. The default is 3600 seconds.
      • Use OAuth2 introspection endpoint client credentials: Specify whether to use the same client details that you previously specified for the OAuth 2.0 introspection endpoint to obtain a new JWT access token (which is usually the case). If you do not want to use the details you previously specified, enter different client details to use to obtain a new JWT access token from the authorization server, as follows:
        • Client ID: The client ID to send to the introspection endpoint. For example, 5hsti38yhy5j2a4tas455rsu6ru8yui3wrst4n1
        • Vault in <compartment-name>: The name of a vault in the Vault service that contains the client secret to send to the introspection endpoint.
        • Vault secret in <compartment name>: The name of the vault secret that contains the client secret to send to the introspection endpoint.
        • Vault secret version number: The version of the vault secret that contains the client secret to send to the introspection endpoint.

      You can optionally choose to store in cookies the tokens and values obtained during OpenID authorization flows, by selecting Show advanced options and selecting:

      • Use cookies for session: (optional) Specify how to store newly generated JWT tokens as non-human-readable strings at the end of an OpenID Connect authorization flow:
        • Select this option if you want to store the new JWT token in a session cookie. To prevent potential CSRF attacks, when the API gateway stores the token in a session cookie, it also returns a CSRF token in an X-CSRF-TOKEN response header. Subsequent requests to the API gateway (apart from GET requests) must include the CSRF token in an X-CSRF-TOKEN request header, in addition to the JWT token in the session cookie that is included automatically.
        • Do not select this option if you do not want to store the new JWT token in a session cookie. Instead, the API gateway returns a non-human-readable token in an X-APIGW-TOKEN response header. Subsequent requests to the API gateway must include the same token in an X-APIGW-TOKEN request header.

        See Notes about Cross-Site Request Forgery (CSRF) Protection

      • Use cookies for intermediate steps: (optional) Specify how to store authorization flow intermediate step values (for example, request parameters). Select this option to store the values in browser cookies. Deselect this option to store the values with the API gateway.
      • Use PKCE: (optional) Specify whether to use PKCE (Proof Key for Code Exchange) for additional security. PKCE is an OAuth 2.0 security extension to prevent CSRF (Cross-Site Request Forgery) and authorization code injection attacks. PKCE is not a replacement for a client secret, and PKCE is recommended even if a client secret is used. For more information about PKCE, see the OAuth 2.0 documentation.
    3. If you want to customize the response to an unsuccessful attempt to validate a missing or invalid token, select Custom response, and specify a status code (and an optional message body) to return to the API client:
      • HTTP status code: Enter an alternative HTTP status code. For example, 500.
      • Message body: Enter a message body. For example, Unfortunately, authentication failed.The message body can include any context variable (except for request.body).
      • Optionally, modify the headers of the response that the API gateway returns to the API client by specifying a header transformation response policy. For more information about header transformation policies, see Adding Header Transformation Response Policies.
  9. Click Next to enter details for individual routes in the API deployment on the Routes page.

  10. In the Route 1 section, specify the first route in the API deployment that maps a path and one or more methods to a back-end service:

    • Path: A path for API calls using the listed methods to the back-end service. Note that the route path you specify:

      • is relative to the deployment path prefix
      • must be preceded by a forward slash ( / ), and can be just that single forward slash
      • can contain multiple forward slashes (provided they are not adjacent), and can end with a forward slash
      • can include alphanumeric uppercase and lowercase characters
      • can include the special characters $ - _ . + ! * ' ( ) , % ; : @ & =
      • can include parameters and wildcards (see Adding Path Parameters and Wildcards to Route Paths)
    • Methods: One or more methods accepted by the back-end service, separated by commas. For example, GET, PUT.
    • Add a single backend or Add multiple backends: Whether to route all requests to the same back end, or to route requests to different back ends according to context variable and rules you enter.

      These instructions assume you want to use a single back end, so select Add a single backend. Alternatively, if you want to use different back ends, select Add multiple backends and follow the instructions in Using the Console to Add Dynamic Back End Selection to an API Deployment Specification.

    • Backend type: The type of the back-end service, as one of:
  11. To specify an authorization policy that applies to an individual route, click Show Route Request Policies, click the Add button beside Authorization, and specify:

    • Authorization Type: How to grant access to the route. Specify:

      • Any: Only grant access to end users that have been successfully authenticated, provided the JWT has a scope claim that includes at least one of the access scopes you specify in the Allowed Scope field. In this case, the authentication policy's Enable Anonymous Access option has no effect.
      • Anonymous: Grant access to all end users, even if they have not been successfully authenticated using the JWT. In this case, you must have selected the authentication policy's Enable Anonymous Access option.
      • Authentication only: Only grant access to end users that have been successfully authenticated using the JWT. In this case, the authentication policy's Enable Anonymous Access option has no effect.
    • Allowed Scope: If you selected Any as the Authorization Type, enter a comma-delimited list of one or more strings that correspond to access scopes in the JWT. Access will only be granted to end users that have been successfully authenticated if the JWT has a scope claim that includes one of the access scopes you specify. For example, read:hello
    Note

    If you don't include an authorization policy for a particular route, access is granted as if such a policy does exist and Authorization Type is set to Authentication only. In other words, regardless of the setting of the authentication policy's Enable Anonymous Access option:

    • only authenticated end users can access the route
    • all authenticated end users can access the route regardless of access scopes in the JWT's scope claim
    • anonymous end users cannot access the route
  12. Click Apply Changes, and then click Next to review the details you entered for the API deployment.
  13. Click Create or Save Changes to create or update the API deployment.
  14. (Optional) Confirm the API has been deployed successfully by calling it (see Calling an API Deployed on an API Gateway).

Editing a JSON File to Add Token Authentication and Authorization Request Policies

To add authentication and authorization request policies to an API deployment specification in a JSON file:

  1. Using your preferred JSON editor, edit the existing API deployment specification to which you want to add authentication and authorization functionality, or create a new API deployment specification (see Creating an API Deployment Specification).

    At a minimum, the API deployment specification will include a routes section containing:

    • A path. For example, /hello
    • One or more methods. For example, GET
    • A definition of a back end. For example, a URL, or the OCID of a function in OCI Functions.

    For example, the following basic API deployment specification defines a simple Hello World serverless function in OCI Functions as a single back end:

    {
      "routes": [
        {
          "path": "/hello",
          "methods": ["GET"],
          "backend": {
            "type": "ORACLE_FUNCTIONS_BACKEND",
            "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
          }
        }
      ]
    }
  2. Insert a requestPolicies section before the routes section (if one doesn't exist already) to create an authentication request policy that applies to all routes in the API deployment specification. For example:

    
    {
      "requestPolicies": {},
      "routes": [
        {
          "path": "/hello",
          "methods": ["GET"],
          "backend": {
             "type": "ORACLE_FUNCTIONS_BACKEND",
             "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
          }
        }
      ]
    }
  3. Add the authentication request policy as follows

    
    {
      "requestPolicies": {
        "authentication": {
          "type": "TOKEN_AUTHENTICATION",
          <"tokenHeader"|"tokenQueryParam">: <"<token-header-name>"|"<token-query-param-name>">,
          "tokenAuthScheme": "<authentication-scheme>",
          "isAnonymousAccessAllowed": <true|false>,
          "maxClockSkewInSeconds": <seconds-difference>,
          "validationPolicy": {<validation-policy-config>},
        }
      "routes": [
        {
          "path": "/hello",
          "methods": ["GET"],
          "backend": {
             "type": "ORACLE_FUNCTIONS_BACKEND",
             "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
          }
        }
      ]
    }

    where:

    • "authentication": {"type": "TOKEN_AUTHENTICATION"... specifies that you want to use tokens for authentication.
    • <"tokenHeader"|"tokenQueryParam">: <"<token-header-name>"|"<token-query-param-name>"> indicates whether it is a request header that contains the token (and if so, the name of the header), or a query parameter that contains the token (and if so, the name of the query parameter). Note that you can specify either "tokenHeader": "<token-header-name>" or "tokenQueryParam": "<token-query-param-name>">, but not both. For example, "tokenHeader": "Authorization"
    • <tokenAuthScheme> is the name of the authentication scheme to use if the token is contained in a request header. For example, "Bearer".
    • "isAnonymousAccessAllowed": <true|false> optionally indicates whether unauthenticated (that is, anonymous) end users can access routes in the API deployment specification. If you never want anonymous end users to be able to access routes, set this property to false. If you don't include this property in the authentication policy, the default of false is used. Note that if you do include this property and set it to true, you also have to explicitly specify every route to which anonymous access is allowed by setting the type property to "ANONYMOUS" in each route's authorization policy.
    • maxClockSkewInSeconds: <seconds-difference> optionally specifies the maximum time difference between the system clocks of the identity provider that issued a JWT and the API gateway. The value you specify is taken into account when the API gateway validates the JWT to determine whether it is still valid, using the not before (nbf) claim (if present) and the expiration (exp) claim in the JWT. The minimum (and default) is 0, the maximum is 120.
    • "validationPolicy": {<validation-policy-config>} specifies a validation policy to validate tokens, as described in the following steps.
  4. If you want the API gateway to validate both JWT tokens and non-JWT tokens with an OAuth 2.0 authorization server's introspection endpoint using client credentials (including a client secret retrieved from a vault in the Vault service), add the following validation policy to the empty validationPolicy section:
          "validationPolicy": {
            "type": "REMOTE_DISCOVERY",          
            "clientDetails": {
              "type": "CUSTOM",
              "clientId": "<client-id>",
              "clientSecretId": "<secret-ocid>",
              "clientSecretVersionNumber": <secret-version-number>
            },          
            "sourceUriDetails": {
              "type": "DISCOVERY_URI",
              "uri": "<well-known-uri>"
            },
            "isSslVerifyDisabled": <true|false>,
            "maxCacheDurationInHours": <cache-time>,
            "additionalValidationPolicy": {
              "issuers": ["<issuer-url>", "<issuer-url>"],
              "audiences": ["<intended-audience>"],
              "verifyClaims": [{
                "key": "<claim-name>",
                "values": ["<acceptable-value>", "<acceptable-value>"],
                "isRequired": <true|false>
              }]
            }
          }

    where:

    • "validationPolicy": {"type": "REMOTE_DISCOVERY"...} specifies that you want to validate tokens with an OAuth 2.0 authorization server's introspection endpoint using client credentials (including a client secret retrieved from a vault in the Vault service).
    • clientDetails": {"type": "CUSTOM"...} specifies details of the client secret to retrieve from a vault in the Vault service:
      • "clientId": "<client-id>" specifies the client ID to send to the introspection endpoint. You obtain a client ID by creating and registering a client application with the authorization server. For example, 5hsti38yhy5j2a4tas455rsu6ru8yui3wrst4n1 . See Prerequisites for Token Authentication.
      • "clientSecretId": "<secret-ocid>" specifies the OCID of the vault secret that contains the client secret to send to the introspection endpoint. For example, ocid1.vaultsecret.oc1.iad.amaaaaaa______cggit3q
      • "clientSecretVersionNumber": <secret-version-number> specifies the version of the vault secret that contains the client secret to send to the introspection endpoint. For example, 1
    • "uri": "<well-known-uri>" specifies the well-known URL of an authorization server from which the API gateway is to obtain authorization metadata endpoints. For example, https://my-idp/oauth2/default/.well-known/openid-configuration. Note the URL must be routable from the subnet containing the API gateway on which the API is deployed.
    • "isSslVerifyDisabled": <true|false> indicates whether to disable SSL verification when communicating with the authorization server. Oracle recommends not setting this option to true because it can compromise JWT validation. API Gateway trusts certificates from multiple Certificate Authorities issued for OCI IAM with Identity Domains, Oracle Identity Cloud Service (IDCS), Auth0, and Okta.
    • "maxCacheDurationInHours": <cache-time> specifies the number of hours (between 1 and 24) the API gateway is to cache the response from the introspection endpoint.
    • "additionalValidationPolicy": {"issuers": ...} specifies additional details for token validation:
      • <issuer-url> is the URL (or a text string) for an authorization server that is allowed in the issuer (iss) claim of a JWT to be used to access the API deployment. For example, to enable a JWT issued by OCI IAM with Identity Domains to be used to access the API deployment, specify https://identity.oraclecloud.com/ . You can specify one or multiple authorization servers (up to a maximum of five). See Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI.
      • <intended-audience> is a value that is allowed in the audience (aud) claim of a JWT to identify the intended recipient of the token. For example, the audience could be, but need not be, the API gateway's hostname. You can specify one audience or multiple audiences (up to a maximum of five). See Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI.
      • "verifyClaims": {...} optionally specifies additional claim names and values for one or more additional claims to validate in a JWT (up to a maximum of ten):
        • "key": "<claim-name>" is the name of a claim that can be, or must be, included in a JWT. The claim name you specify can be a reserved claim name such as the subject (sub) claim, or a custom claim name issued by a particular authorization server.
        • "values": ["<acceptable-value>", "<acceptable-value>"] (optionally) indicates one or more acceptable values for the claim.
        • "isRequired": <true|false> indicates whether the claim must be included in the JWT.

        Note that any key names and values you enter are simply handled as strings, and must match exactly with names and values in the JWT. Pattern matching and other datatypes are not supported

    For example, the following authentication policy configures the API gateway to validate a token in the Authorization request header using client credentials (including a client secret retrieved from a vault in the Vault service) passed to an OAuth 2.0 introspection endpoint):

    {
      "requestPolicies": {
        "authentication": {
          "type": "TOKEN_AUTHENTICATION",
          "tokenHeader": "Authorization",
          "tokenAuthScheme": "Bearer",
          "isAnonymousAccessAllowed": false,
          "maxClockSkewInSeconds": 10,
          "validationPolicy": {
            "type": "REMOTE_DISCOVERY",
            "clientDetails": {
              "type": "CUSTOM",
              "clientId": "5hsti38yhy5j2a4tas455rsu6ru8yui3wrst4n1",
              "clientSecretId": "ocid1.vaultsecret.oc1.iad.amaaaaaa______cggit3q",
              "clientSecretVersionNumber": 1
            },          
            "sourceUriDetails": {
              "type": "DISCOVERY_URI",
              "uri": "https://my-idp/oauth2/default/.well-known/openid-configuration"
            },
            "isSslVerifyDisabled": false,
            "maxCacheDurationInHours": 2,
            "additionalValidationPolicy": {
              "issuers": ["https://identity.oraclecloud.com/"],
              "audiences": ["api.dev.io"],
              "verifyClaims": [{
                "key": "is_admin",
                "values": ["service:app", "read:hello"],
                "isRequired": true
              }]
            }
          }
        }
      },
      "routes": [
        {
          "path": "/hello",
          "methods": ["GET"],
          "backend": {
            "type": "ORACLE_FUNCTIONS_BACKEND",
            "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
          }
        }
      ]
    }
  5. If you want the API gateway to validate JWTs by retrieving public verification keys from the identity provider at runtime, add the following validation policy to the empty validationPolicy section:

          "validationPolicy": {
            "type": "REMOTE_JWKS",
            "uri": "<uri-for-jwks>",
            "isSslVerifyDisabled": <true|false>,
            "maxCacheDurationInHours": <cache-time>,
            "additionalValidationPolicy": {
              "issuers": ["<issuer-url>", "<issuer-url>"],
              "audiences": ["<intended-audience>"],
              "verifyClaims": [{
                "key": "<claim-name>",
                "values": ["<acceptable-value>", "<acceptable-value>"],
                "isRequired": <true|false>
              }]
            }
          }
    

    where:

    • "validationPolicy": {"type": "REMOTE_JWKS"... specifies that you want to configure the API gateway to retrieve up to ten public verification keys from the identity provider at runtime.
    • "uri": "<uri-for-jwks>" specifies the URI from which to retrieve the JSON Web Key Set (JWKS) to use to verify the signature on JWTs. For more information about the URI to specify, see Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI. Note the following:
      • The URI must be routable from the subnet containing the API gateway on which the API is deployed.
      • If the API gateway fails to retrieve the JWKS, all requests to the API deployment will return an HTTP 500 response code. Refer to the API gateway's execution log for more information about the error (see Adding Logging to API Deployments).
      • Certain key parameters must be present in the JWKS to verify the JWT's signature (see Key Parameters Required to Verify JWT Signatures).
      • The JWKS can contain up to ten keys.
    • "isSslVerifyDisabled": <true|false> indicates whether to disable SSL verification when communicating with the identity provider. Oracle recommends not setting this option to true because it can compromise JWT validation. API Gateway trusts certificates from multiple Certificate Authorities issued for OCI IAM with Identity Domains, Oracle Identity Cloud Service (IDCS), Auth0, and Okta.
    • "maxCacheDurationInHours": <cache-time> specifies the number of hours (between 1 and 24) the API gateway is to cache the JWKS after retrieving it.
    • "additionalValidationPolicy": {"issuers": ...} specifies additional details for token validation:
      • <issuer-url> is the URL (or a text string) for an identity provider that is allowed in the issuer (iss) claim of a JWT to be used to access the API deployment. For example, to enable a JWT issued by OCI IAM with Identity Domains to be used to access the API deployment, enter https://identity.oraclecloud.com/ . You can specify one or multiple identity providers (up to a maximum of five). See Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI.
      • <intended-audience> is a value that is allowed in the audience (aud) claim of a JWT to identify the intended recipient of the token. For example, the audience could be, but need not be, the API gateway's hostname. You can specify one audience or multiple audiences (up to a maximum of five). See Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI.
      • verifyClaims optionally specifies additional claim names and values for one or more additional claims to validate in a JWT (up to a maximum of ten).
        • "key": "<claim-name>" is the name of a claim that can be, or must be, included in a JWT. The claim name you specify can be a reserved claim name such as the subject (sub) claim, or a custom claim name issued by a particular identity provider.
        • "values": ["<acceptable-value>", "<acceptable-value>"] (optionally) indicates one or more acceptable values for the claim.
        • "isRequired": <true|false> indicates whether the claim must be included in the JWT.

        Note that any key names and values you enter are simply handled as strings, and must match exactly with names and values in the JWT. Pattern matching and other datatypes are not supported

    For example, the following authentication policy configures the API gateway to validate the JWT in the Authorization request header by retrieving public verification keys from the identity provider at runtime:

    {
      "requestPolicies": {
        "authentication": {
          "type": "TOKEN_AUTHENTICATION",
          "tokenHeader": "Authorization",
          "tokenAuthScheme": "Bearer",
          "isAnonymousAccessAllowed": false,
          "validationPolicy": {
            "type": "REMOTE_JWKS",
            "uri": "https://my-tenant-id.identity.oraclecloud.com/admin/v1/SigningCert/jwk",
            "isSslVerifyDisabled": false,
            "maxCacheDurationInHours": 2,
            "additionalValidationPolicy": {
              "issuers": ["https://identity.oraclecloud.com/"],
              "audiences": ["api.dev.io"],
              "verifyClaims": [{
                "key": "is_admin",
                "values": ["service:app", "read:hello"],
                "isRequired": true
              }]
            }
          }
        }
      },
      "routes": [
        {
          "path": "/hello",
          "methods": ["GET"],
          "backend": {
            "type": "ORACLE_FUNCTIONS_BACKEND",
            "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
          }
        }
      ]
    }
  6. If you want the API gateway to validate JWTs with public verification keys already issued by an identity provider (enabling the API gateway to verify JWTs locally without having to contact the identity provider), add the following validation policy to the empty validationPolicy section:

          "validationPolicy": {
            "type": "STATIC_KEYS",
            "keys": [{<key-config>}],
            "isSslVerifyDisabled": <true|false>,
            "maxCacheDurationInHours": <cache-time>,
            "additionalValidationPolicy": {
              "issuers": ["<issuer-url>", "<issuer-url>"],
              "audiences": ["<intended-audience>"],
              "verifyClaims": [{
                "key": "<claim-name>",
                "values": ["<acceptable-value>", "<acceptable-value>"],
                "isRequired": <true|false>
              }]
            }
          }

    where:

    • "validationPolicy": {"type": "STATIC_KEYS"... specifies that you want to configure the API gateway with up to ten public verification keys already issued by an identity provider (enabling the API gateway to verify JWTs locally without having to contact the identity provider).
    • "keys": [{<key-config>}] specify the identifier of the static key used to sign the JWT. The details to provide depend on the format of the key already issued by the identity provider (regardless of format, you can specify up to ten keys):
      • If the static key is a JSON Web Key, specify "format": "JSON_WEB_KEY", specify the identifier of the static key used to sign the JWT as the value of the "kid" parameter, and provide values for other parameters to verify the JWT's signature.

        For example:

                "keys": [
                  {
                    "format": "JSON_WEB_KEY",
                    "kid": "master_key",
                    "kty": "RSA",
                    "n": "0vx7agoebGc...KnqDKgw",
                    "e": "AQAB",
                    "alg": "RS256",
                    "use": "sig"
                  }
                ]

        Note that certain parameters must be present in the static key to verify the JWT's signature (see Key Parameters Required to Verify JWT Signatures). Also note that RSA is currently the only supported key type (kty).

      • If the static key is a PEM-encoded public key, specify "format": "PEM", specify the identifier of the static key used to sign the JWT as the value of "kid", and provide the key as the value of "key".

        For example:

                "keys": [
                  {
                    "format": "PEM",
                    "kid": "master_key"
                    "key": -----BEGIN PUBLIC KEY-----XsEiCeYgglwW/KAhSSNRVdD60QlXYMWHOhXzSFDZCLf1WXxKMZCiMvVrsBIzmFEXnFmcsO2mxwlL5/8qQudomoP+yycJ2gWPIgqsZcQRheJWxVC5ep0MeEHlvLnEvCi9utpAnjrsZCQ7plfZVPX7XORvezwqQhBfYzwA27M2FgOOs8DOIYfqQ1Ki3DMqEppFnjLcjgQtknbTlT7YgG6tzobwig8M2KIrPjJ0BmbJAFH-----END PUBLIC KEY-----
                  }
                ]

        Note that the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- markers are required.

    • "isSslVerifyDisabled": <true|false> indicates whether to disable SSL verification when communicating with the identity provider. Oracle recommends not setting this option to true because it can compromise JWT validation. API Gateway trusts certificates from multiple Certificate Authorities issued for OCI IAM with Identity Domains, Oracle Identity Cloud Service (IDCS), Auth0, and Okta.
    • "maxCacheDurationInHours": <cache-time> specifies the number of hours (between 1 and 24) the API gateway is to cache the JWKS after retrieving it.
    • "additionalValidationPolicy": {"issuers": ...} specifies additional details for token validation:
      • <issuer-url> is the URL (or a text string) for an identity provider that is allowed in the issuer (iss) claim of a JWT to be used to access the API deployment. For example, to enable a JWT issued by OCI IAM with Identity Domains to be used to access the API deployment, enter https://identity.oraclecloud.com/ . You can specify one or multiple identity providers (up to a maximum of five). See Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI.
      • <intended-audience> is a value that is allowed in the audience (aud) claim of a JWT to identify the intended recipient of the token. For example, the audience could be, but need not be, the API gateway's hostname. You can specify one audience or multiple audiences (up to a maximum of five). See Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI.
      • verifyClaims optionally specifies additional claim names and values for one or more additional claims to validate in a JWT (up to a maximum of ten).
        • "key": "<claim-name>" is the name of a claim that can be, or must be, included in a JWT. The claim name you specify can be a reserved claim name such as the subject (sub) claim, or a custom claim name issued by a particular identity provider.
        • "values": ["<acceptable-value>", "<acceptable-value>"] (optionally) indicates one or more acceptable values for the claim.
        • "isRequired": <true|false> indicates whether the claim must be included in the JWT.

        Note that any key names and values you enter are simply handled as strings, and must match exactly with names and values in the JWT. Pattern matching and other datatypes are not supported

    For example, the following authentication policy configures the API gateway with a public verification key already issued by an identity provider to validate the JWT in the Authorization request header:

    {
      "requestPolicies": {
        "authentication": {
          "type": "TOKEN_AUTHENTICATION",
          "tokenHeader": "Authorization",
          "tokenAuthScheme": "Bearer",
          "isAnonymousAccessAllowed": false,
          "validationPolicy": {
            "type": "STATIC_KEYS",
            "keys": [
              {
                "format": "JSON_WEB_KEY",
                "kid": "master_key",
                "kty": "RSA",
                "n": "0vx7agoebGc...KnqDKgw",
                "e": "AQAB",
                "alg": "RS256",
                "use": "sig"
              }
            ],
            "isSslVerifyDisabled": false,
            "maxCacheDurationInHours": 2,
            "additionalValidationPolicy": {
              "issuers": ["https://identity.oraclecloud.com/"],
              "audiences": ["api.dev.io"],
              "verifyClaims": [{
                "key": "is_admin",
                "values": ["service:app", "read:hello"],
                "isRequired": true
              }]
            }
          }
        }
      },
      "routes": [
        {
          "path": "/hello",
          "methods": ["GET"],
          "backend": {
            "type": "ORACLE_FUNCTIONS_BACKEND",
            "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
          }
        }
      ]
    }
  7. (Optional) You can specify how you want the API gateway to handle a failed authentication response (returned after an unsuccessful attempt to validate a missing or invalid token) by setting up a validation failure policy:
    1. If you want the API gateway to send an HTTP 401 status code and the WWW-Authenticate header in the response (the default response to a missing or invalid token), do not define a validation failure policy.
    2. If you want the API gateway to use an OpenID Connect authorization flow to obtain a new JWT access token, define a validation failure policy of type OAUTH2. Note that this option is only available if you specified a validationPolicy of type REMOTE_DISCOVERY earlier. Specify:

      {
        "requestPolicies": {
          "authentication": {
            "type": "TOKEN_AUTHENTICATION",
            ...
            "validationPolicy": {
              "type": "REMOTE_DISCOVERY",
              ...
            },
            "validationFailurePolicy": {
              "type": "OAUTH2",
              "scopes": ["<scope>", "<scope"],
              "clientDetails": {
                "type": "<VALIDATION_BLOCK|CUSTOM>",
                "clientId": "<client-id>",
                "clientSecretId": "<secret-ocid>",
                "clientSecretVersionNumber": <secret-version-number>
                },
              "sourceUriDetails": {
                "type": "VALIDATION_BLOCK"
                },
              "maxExpiryDurationInHours": <number-of-hours>,
              "useCookiesForSession": <true|false>,
              "useCookiesForIntermediateSteps": <true|false>,
              "usePkce": <true|false>,
              "responseType": "code",
              "fallbackRedirectPath": "<redirect-path>",
              "logoutPath": "<logout-path>"
            }
          }
        },
        "routes": [
          ...
        ]
      }

      where:

      • "scopes": ["<scope>", "<scope"] specifies one or more access scopes to include in a scope claim sent to the authorization server. To use the OpenID Connect authorization flow, you must include openid as one of the scopes. For example, "scopes": ["openid", "email:read", "profile"]
      • clientDetails": {...} specifies the client details to use to obtain a new JWT access token from the authorization server, as follows:
        • "type": "<VALIDATION_BLOCK|CUSTOM>" specifies whether to use the same, or different, client details to those specified in the earlier validationPolicy. If you want to use the same client details as before (which is usually the case), specify "type": "VALIDATION_BLOCK" and do not provide additional details. If you want to use different client details, specify "type": "CUSTOM" and set values for "clientId", "clientSecretId", and "clientSecretVersionNumber".
        • "clientId": "<client-id>" specifies the client ID to send to the introspection endpoint. Only used if "type": "CUSTOM". For example, 5hsti38yhy5j2a4tas455rsu6ru8yui3wrst4n1
        • "clientSecretId": "<secret-ocid>" specifies the OCID of the vault secret that contains the client secret to send to the introspection endpoint. Only used if "type": "CUSTOM". For example, ocid1.vaultsecret.oc1.iad.amaaaaaa______cggit3q
        • "clientSecretVersionNumber": <secret-version-number> specifies the version of the vault secret that contains the client secret to send to the introspection endpoint. Only used if "type": "CUSTOM". For example, 1
      • "sourceUriDetails": {"type": "VALIDATION_BLOCK"} specifies that you want to use the same URL as that specified in the earlier validationPolicy as the well-known URL of an authorization server from which the API gateway is to obtain authorization metadata endpoints.
      • "maxExpiryDurationInHours": <number-of-hours> specifies the length of time to cache the JWT token generated by the authorization flow. The default is 1.
      • "useCookiesForSession": <true|false> specifies how to store newly generated JWT tokens as non-human-readable strings at the end of an OpenID Connect authorization flow:
        • Set this option to true if you want to store the new JWT token in a session cookie. To prevent potential CSRF attacks, when the API gateway stores the token in a session cookie, it also returns a CSRF token in an X-CSRF-TOKEN response header. Subsequent requests (apart from GET requests) must include the CSRF token in an X-CSRF-TOKEN request header, in addition to the JWT token in the session cookie that is included automatically.
        • Set this option to false if you do not want to store the new JWT token in a session cookie. Instead, the API gateway returns a non-human-readable token in an X-APIGW-TOKEN response header. Subsequent requests to the API gateway must include the same token in an X-APIGW-TOKEN request header.

        See Notes about Cross-Site Request Forgery (CSRF) Protection

      • "useCookiesForIntermediateSteps": <true|false> specifies how to store authorization flow intermediate step values (for example, request parameters). Set this option to true to store the values in browser cookies. Set this option to false to store the values with the API gateway.
      • "usePkce": <true|false> specifies whether to use PKCE (Proof Key for Code Exchange) for additional security. PKCE is an OAuth 2.0 security extension to prevent CSRF (Cross-Site Request Forgery) and authorization code injection attacks. PKCE is not a replacement for a client secret, and PKCE is recommended even if a client secret is used. For more information about PKCE, see the OAuth 2.0 documentation.
      • "responseType": "code" specifies the type of response required from the authorization flow. Specify code as the response type.
      • "fallbackRedirectPath": "/home" optionally specifies a relative path in the current API deployment to which to redirect API clients if the original request was a PUT request or a POST request. For example, /home.

        If the original request was a GET request, request processing resumes with a new JWT access token, so a fallback path is not used.

      • "logoutPath": "<revoke-path>"optionally specifies a relative path to a logout back end in the current API deployment. The path you specify must match the route path defined for the logout back end. For example, "logoutPath": "/revoke".

        An API client can call the logout back end to revoke tokens. A call to the logout back end can include a post-logout URL as a query parameter named postLogoutUrl. See Adding Logout as an API Gateway Back End.

      For example:

      {
        "requestPolicies": {
          "authentication": {
            "type": "TOKEN_AUTHENTICATION",
            ...
            "validationPolicy": {
              "type": "REMOTE_DISCOVERY",
              ...
            },
            "validationFailurePolicy": {
              "type": "OAUTH2",
              "scopes": ["openid", "email:read", "profile"],
              "clientDetails": {
                "type": "VALIDATION_BLOCK"
                },
              "sourceUriDetails": {
                "type": "VALIDATION_BLOCK"
              },
              "maxExpiryDurationInHours": 2,
              "useCookiesForSession": true,
              "useCookiesForIntermediateSteps": true,
              "usePkce": true,
              "responseType": "code",
              "fallbackRedirectPath": "/home",
              "logoutPath": "/revoke"
            }
          }
        },
        "routes": [
          ...
        ]
      }
    3. If you want to customize the response to an unsuccessful attempt to validate a missing or invalid token, define a validation failure policy of type MODIFY_RESPONSE, and specify a status code (and an optional message body) to return to the API client, as follows:
      {
        "requestPolicies": {
          "authentication": {
            "type": "TOKEN_AUTHENTICATION",
            ...
            "validationPolicy": {
              ...
            },
            "validationFailurePolicy": {
              "type": "MODIFY_RESPONSE",
              "responseCode": "<alternative-response-code>",
              "responseMessage": "<custom-message-body>",
              "responseTransformations": {
                "headerTransformations": {
                  <valid-header-transformation-response-policy>
                }
              }
            }
          }
        },
        "routes": [
          ...
        ]
      }

      where:

      • responseCode: specifies an alternative HTTP status code. For example, 500.
      • responseMessage: (optionally) specifies a message body. For example, Unfortunately, authentication failed. The message body can include any context variable (except for request.body).
      • responseTransformations: (optionally) modifies the headers of the response that the API gateway returns to the API client by specifying a header transformation response policy. For more information about header transformation policies, see Adding Header Transformation Response Policies.

      For example:

      {
        "requestPolicies": {
          "authentication": {
            "type": "TOKEN_AUTHENTICATION",
            ...
            "validationPolicy": {
              ...
            },
            "validationFailurePolicy": {
              "type": "MODIFY_RESPONSE",
              "responseCode": "500",
              "responseMessage": "Unfortunately, authentication failed.",
            }
          }
        },
        "routes": [
          ...
        ]
      }
  8. Add an authorization request policy for each route in the API deployment specification:

    1. Insert a requestPolicies section after the first route's backend section, if one doesn't exist already. For example:

      {
        "requestPolicies": {
          "authentication": {
            "type": "TOKEN_AUTHENTICATION",
            "tokenHeader": "Authorization",
            "tokenAuthScheme": "Bearer",
            "isAnonymousAccessAllowed": false,
            "validationPolicy": {
              "type": "STATIC_KEYS",
              "keys": [
                {
                  "format": "JSON_WEB_KEY",
                  "kid": "master_key",
                  "kty": "RSA",
                  "n": "0vx7agoebGc...KnqDKgw",
                  "e": "AQAB",
                  "alg": "RS256",
                  "use": "sig"
                }
              ],
              "isSslVerifyDisabled": false,
              "maxCacheDurationInHours": 2,
              "additionalValidationPolicy": {
                "issuers": ["https://identity.oraclecloud.com/"],
                "audiences": ["api.dev.io"],
                "verifyClaims": [{
                  "key": "is_admin",
                  "values": ["service:app", "read:hello"],
                  "isRequired": true
                }]
              }
            }
          }
        },
        "routes": [
          {
            "path": "/hello",
            "methods": ["GET"],
            "backend": {
              "type": "ORACLE_FUNCTIONS_BACKEND",
              "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
            },
            "requestPolicies": {}
          }
        ]
      }
    2. Add the following authorization policy to the new requestPolicies section:

            "requestPolicies": {
              "authorization": {
                "type": <"AUTHENTICATION_ONLY"|"ANY_OF"|"ANONYMOUS">, 
                "allowedScope": [ "<scope>" ]
              }
            }

      where:

      • "type": <"AUTHENTICATION_ONLY"|"ANY_OF"|"ANONYMOUS"> indicates how to grant access to the route:

        • "AUTHENTICATION_ONLY": Only grant access to end users that have been successfully authenticated. In this case, the "isAnonymousAccessAllowed" property in the API deployment specification's authentication policy has no effect.
        • "ANY_OF": Only grant access to end users that have been successfully authenticated, provided the JWT's scope claim includes one of the access scopes you specify in the allowedScope property. In this case, the "isAnonymousAccessAllowed" property in the API deployment specification's authentication policy has no effect.
        • "ANONYMOUS": Grant access to all end users, even if they have not been successfully authenticated. In this case, you must explicitly set the "isAnonymousAccessAllowed" property to true in the API deployment specification's authentication policy.
      • "allowedScope": [ "<scope>" ] is a comma-delimited list of one or more strings that correspond to access scopes included in the JWT's scope claim. In this case, you must set the type property to "ANY_OF" (the "allowedScope" property is ignored if the type property is set to "AUTHENTICATION_ONLY" or "ANONYMOUS"). Also note that if you specify more than one scope, access to the route is granted if any of the scopes you specify is included in the JWT's scope claim.

      For example, the following request policy defines a /hello route that only allows authenticated end users with the read:hello scope to access it:

      {
        "requestPolicies": {
          "authentication": {
            "type": "TOKEN_AUTHENTICATION",
            "tokenHeader": "Authorization",
            "tokenAuthScheme": "Bearer",
            "isAnonymousAccessAllowed": false,
            "validationPolicy": {
              "type": "STATIC_KEYS",
              "keys": [
                {
                  "format": "JSON_WEB_KEY",
                  "kid": "master_key",
                  "kty": "RSA",
                  "n": "0vx7agoebGc...KnqDKgw",
                  "e": "AQAB",
                  "alg": "RS256",
                  "use": "sig"
                }
              ],
              "isSslVerifyDisabled": false,
              "maxCacheDurationInHours": 2,
              "additionalValidationPolicy": {
                "issuers": ["https://identity.oraclecloud.com/"],
                "audiences": ["api.dev.io"],
                "verifyClaims": [{
                  "key": "is_admin",
                  "values": ["service:app", "read:hello"],
                  "isRequired": true
                }]
              }
            }
          }
        },
        "routes": [
          {
            "path": "/hello",
            "methods": ["GET"],
            "backend": {
              "type": "ORACLE_FUNCTIONS_BACKEND",
              "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
            },
            "requestPolicies": {
              "authorization": {
                "type": "ANY_OF",
                "allowedScope": [ "read:hello" ]
              }
            }
          }
        ]
      }
    3. Add an authorization request policy for all remaining routes in the API deployment specification.
    Note

    If you don't include an authorization policy for a particular route, access is granted as if such a policy does exist and the type property is set to "AUTHENTICATION_ONLY". In other words, regardless of the setting of the isAnonymousAccessAllowed property in the API deployment specification's authentication policy:

    • only authenticated end users can access the route
    • all authenticated end users can access the route regardless of access scopes in the JWT's scope claim
    • anonymous end users cannot access the route
  9. Save the JSON file containing the API deployment specification.
  10. Use the API deployment specification when you create or update an API deployment in the following ways:

    • by specifying the JSON file in the Console when you select the Upload an existing API option
    • by specifying the JSON file in a request to the API Gateway REST API

    For more information, see Deploying an API on an API Gateway by Creating an API Deployment and Updating an API Gateway or an API Deployment.

  11. (Optional) Confirm the API has been deployed successfully by calling it (see Calling an API Deployed on an API Gateway).

Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI

The identity provider that issued the JWT determines the allowed values you have to specify for the issuer (iss) and the audience (aud) claims in the JWT. Which identity provider issued the JWT also determines the URI from which to retrieve the JSON Web Key Set (JWKS) to verify the signature on the JWT.

Note that regardless of identity provider, a JWKS can contain a maximum of ten keys.

Use the following table to find out what to specify for JWTs issued by the OCI IAM with Identity Domains, Oracle Identity Cloud Service (IDCS), Okta, and Auth0 identity providers.

Identity Provider

Issuer (iss) claim

Audience (aud) claim

Format of URI from which to retrieve the JWKS

OCI IAM with Identity Domains https://identity.oraclecloud.com

Customer-specific.

See Managing Applications in the OCI IAM with Identity Domains documentation.

https://<tenant-base-url>/admin/v1/SigningCert/jwk

IDCS https://identity.oraclecloud.com/

Customer-specific.

See Validating Access Tokens in the Oracle Identity Cloud Service documentation.

https://<tenant-base-url>/admin/v1/SigningCert/jwk

To obtain the JWKS without logging in to Oracle Identity Cloud Service, see Change Default Settings in the Oracle Identity Cloud Service documentation.

Okta https://<your-okta-tenant-name>.com

Customer-specific.

The audience configured for the Authorization Server in the Okta Developer Console. See Additional validation for access tokens in the Okta documentation.

https://<your-okta-tenant-name>.com/oauth2/<auth-server-id> /v1/keys

See the Okta documentation.

Auth0 https://<your-account-name>.auth0.com/

Customer-specific.

See Audience in the Auth0 documentation.

https://<your-account-name>.auth0.com/.well-known/jwks.json

Key Parameters Required to Verify JWT Signatures

To verify the signature on a JWT, API gateways require the following key parameters are present in either the JWKS returned from a URI or the static JSON Web Key you specify.

Key Parameter Notes
kid The identifier of the key used to sign the JWT. The value must match the kid claim in the JWT header. For example, master_key.
kty The type of the key used to sign the JWT. Note that RSA is currently the only supported key type.
use or key_ops

If the use parameter is present, then it must be set to sig. If the key-ops parameter is present, then verify must be one of the valid values.

n The public key modulus.
e The public key exponent.
alg The signing algorithm (if present) must be set to one of RS256, RS384 or RS512.

Using a JWT_AUTHENTICATION Authentication Request Policy (no longer recommended)

Note

In earlier releases, you might have created authentication request policies of type JWT_AUTHENTICATION to use JWTs for authentication.

If you are creating new authentication request policies to use JWTs, we now recommend you create authentication request policies of type TOKEN_AUTHENTICATION instead (see Using the Console to Add Token Authentication and Authorization Request Policies and Editing a JSON File to Add Token Authentication and Authorization Request Policies). We also recommend you migrate existing JWT_AUTHENTICATION request policies to TOKEN_AUTHENTICATION policies.

Note that existing JWT_AUTHENTICATION request policies are currently still supported. Also note that although you can create new JWT_AUTHENTICATION request policies by defining the API deployment specification in a JSON file (as described in the original instructions in this section), we recommend you create authentication request policies of type TOKEN_AUTHENTICATION instead.

When using an authentication request policy of type JWT_AUTHENTICATION, before an end user can access an API deployment that uses JWTs for authentication and authorization, they must obtain a JWT from an identity provider.

When calling an API deployed on an API gateway, the API client provides the JWT as a query parameter or in the header of the request. The API gateway validates the JWT using a corresponding public verification key provided by the issuing identity provider. Using the API deployment's JWT_AUTHENTICATION authentication request policy, you can configure how the API gateway validates JWTs:

  • You can configure the API gateway to retrieve public verification keys from the identity provider at runtime. In this case, the identity provider acts as the authorization server.
  • You can configure the API gateway in advance with public verification keys already issued by an identity provider (referred to as 'static keys'), enabling the API gateway to verify JWTs locally at runtime without having to contact the identity provider. The result is faster token validation.

To add a new JWT_AUTHENTICATION authentication and authorization request policy to an API deployment specification in a JSON file:

  1. Add an authentication request policy that applies to all routes in the API deployment specification:

    1. Insert a requestPolicies section before the routes section, if one doesn't exist already. For example:

      
      {
        "requestPolicies": {},
        "routes": [
          {
            "path": "/hello",
            "methods": ["GET"],
            "backend": {
               "type": "ORACLE_FUNCTIONS_BACKEND",
               "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
            }
          }
        ]
      }
    2. Add the following authentication policy to the new requestPolicies section.

      {
        "requestPolicies": {
          "authentication": {
            "type": "JWT_AUTHENTICATION",
            "isAnonymousAccessAllowed": <true|false>,
            "issuers": ["<issuer-url>", "<issuer-url>"],
            <"tokenHeader"|"tokenQueryParam">: <"<token-header-name>"|"<token-query-param-name>">,
            "tokenAuthScheme": "<authentication-scheme>",
            "audiences": ["<intended-audience>"],
            "publicKeys": {
              "type": <"REMOTE_JWKS"|"STATIC_KEYS">,
              <public-key-config>
            },
            "verifyClaims": [
              {"key": "<claim-name>",
               "values": ["<acceptable-value>", "<acceptable-value>"],
               "isRequired": <true|false>
              }
            ],
            "maxClockSkewInSeconds": <seconds-difference>
          }
        },
        "routes": [
          {
            "path": "/hello",
            "methods": ["GET"],
            "backend": {
              "type": "ORACLE_FUNCTIONS_BACKEND",
              "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
            }
          }
        ]
      }

      where:

      • "isAnonymousAccessAllowed": <true|false> optionally indicates whether unauthenticated (that is, anonymous) end users can access routes in the API deployment specification. If you never want anonymous end users to be able to access routes, set this property to false. If you don't include this property in the authentication policy, the default of false is used. Note that if you do include this property and set it to true, you also have to explicitly specify every route to which anonymous access is allowed by setting the type property to "ANONYMOUS" in each route's authorization policy.
      • <issuer-url> is the URL (or a text string) for an identity provider that is allowed in the issuer (iss) claim of a JWT to be used to access the API deployment. For example, to enable a JWT issued by OCI IAM with Identity Domains to be used to access the API deployment, enter https://identity.oraclecloud.com/ . You can specify one or multiple identity providers (up to a maximum of five). See Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI.
      • <"tokenHeader"|"tokenQueryParam">: <"<token-header-name>"|"<token-query-param-name>"> indicates whether it is a request header that contains the JWT (and if so, the name of the header), or a query parameter that contains the JWT (and if so, the name of the query parameter). Note that you can specify either "tokenHeader": "<token-header-name>" or "tokenQueryParam": "<token-query-param-name>">, but not both.
      • <tokenAuthScheme> is the name of the authentication scheme to use if the JWT is contained in a request header. For example, "Bearer".
      • <intended-audience> is a value that is allowed in the audience (aud) claim of a JWT to identify the intended recipient of the token. For example, the audience could be, but need not be, the API gateway's hostname. You can specify one audience or multiple audiences (up to a maximum of five). See Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI.
      • "type": <"REMOTE_JWKS"|"STATIC_KEYS"> indicates how you want the API gateway to validate JWTs using public verification keys. Specify REMOTE_JWKS to configure the API gateway to retrieve up to ten public verification keys from the identity provider at runtime. Specify STATIC_KEYS to configure the API gateway with up to ten public verification keys already issued by an identity provider (enabling the API gateway to verify JWTs locally without having to contact the identity provider).
      • <public-key-config> provides the details of JWT validation, according to whether you specified "REMOTE_JWKS" or "STATIC_KEYS" as the value of "type": as follows:

        • If you specified "type": "REMOTE_JWKS" to configure the API gateway to validate JWTs by retrieving public verification keys from the identity provider at runtime, provide details as follows:

                "publicKeys": {
                  "type": "REMOTE_JWKS",
                  "uri": "<uri-for-jwks>",
                  "maxCacheDurationInHours": <cache-time>,
                  "isSslVerifyDisabled": <true|false>
                }
          

          where:

          • "uri": "<uri-for-jwks>" specifies the URI from which to retrieve the JSON Web Key Set (JWKS) to use to verify the signature on JWTs. For more information about the URI to specify, see Identity Provider Details to Use for iss and aud Claims, and for the JWKS URI. Note the following:
            • The URI must be routable from the subnet containing the API gateway on which the API is deployed.
            • If the API gateway fails to retrieve the JWKS, all requests to the API deployment will return an HTTP 500 response code. Refer to the API gateway's execution log for more information about the error (see Adding Logging to API Deployments).
            • Certain key parameters must be present in the JWKS to verify the JWT's signature (see Key Parameters Required to Verify JWT Signatures).
            • The JWKS can contain up to ten keys.
          • "maxCacheDurationInHours": <cache-time> specifies the number of hours (between 1 and 24) the API gateway is to cache the JWKS after retrieving it.
          • "isSslVerifyDisabled": <true|false> indicates whether to disable SSL verification when communicating with the identity provider. Oracle recommends not setting this option to truebecause it can compromise JWT validation. API Gateway trusts certificates from multiple Certificate Authorities issued for OCI IAM with Identity Domains, Oracle Identity Cloud Service (IDCS), Auth0, and Okta.

          For example:

                "publicKeys": {
                  "type": "REMOTE_JWKS",
                  "uri": "https://www.somejwksprovider.com/oauth2/v3/certs",
                  "maxCacheDurationInHours": 3,
                  "isSslVerifyDisabled": false
                }
          
        • If you specified "type": "STATIC_KEYS", the details to provide depend on the format of the key already issued by the identity provider (regardless of format, you can specify up to ten keys):

          • If the static key is a JSON Web Key, specify "format": "JSON_WEB_KEY", specify the identifier of the static key used to sign the JWT as the value of the "kid" parameter, and provide values for other parameters to verify the JWT's signature.

            For example:

                            
                  "publicKeys": {
                    "type": "STATIC_KEYS",
                    "keys": [
                      {
                        "format": "JSON_WEB_KEY",
                        "kid": "master_key",
                        "kty": "RSA",
                        "n": "0vx7agoebGc...KnqDKgw",
                        "e": "AQAB",
                        "alg": "RS256",
                        "use": "sig"
                      }
                    ]

            Note that certain parameters must be present in the static key to verify the JWT's signature (see Key Parameters Required to Verify JWT Signatures). Also note that RSA is currently the only supported key type (kty).

          • If the static key is a PEM-encoded public key, specify "format": "PEM", specify the identifier of the static key used to sign the JWT as the value of "kid", and provide the key as the value of "key".

            For example:

                            
                  "publicKeys": {
                    "type": "STATIC_KEYS",
                    "keys": [
                      {
                        "format": "PEM",
                        "kid": "master_key"
                        "key": -----BEGIN PUBLIC KEY-----XsEiCeYgglwW/KAhSSNRVdD60QlXYMWHOhXzSFDZCLf1WXxKMZCiMvVrsBIzmFEXnFmcsO2mxwlL5/8qQudomoP+yycJ2gWPIgqsZcQRheJWxVC5ep0MeEHlvLnEvCi9utpAnjrsZCQ7plfZVPX7XORvezwqQhBfYzwA27M2FgOOs8DOIYfqQ1Ki3DMqEppFnjLcjgQtknbTlT7YgG6tzobwig8M2KIrPjJ0BmbJAFH-----END PUBLIC KEY-----
                      }
                    ]

            Note that the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- markers are required.

      • verifyClaims optionally specifies additional claim names and values for one or more additional claims to validate in a JWT (up to a maximum of ten).
        • "key": "<claim-name>" is the name of a claim that can be, or must be, included in a JWT. The claim name you specify can be a reserved claim name such as the subject (sub) claim, or a custom claim name issued by a particular identity provider.
        • "values": ["<acceptable-value>", "<acceptable-value>"] (optionally) indicates one or more acceptable values for the claim.
        • "isRequired": <true|false> indicates whether the claim must be included in the JWT.

        Note that any key names and values you enter are simply handled as strings, and must match exactly with names and values in the JWT. Pattern matching and other datatypes are not supported

      • maxClockSkewInSeconds: <seconds-difference> optionally specifies the maximum time difference between the system clocks of the identity provider that issued a JWT and the API gateway. The value you specify is taken into account when the API gateway validates the JWT to determine whether it is still valid, using the not before (nbf) claim (if present) and the expiration (exp) claim in the JWT. The minimum (and default) is 0, the maximum is 120.

      For example, the following authentication policy configures the API gateway with a public verification key already issued by an identity provider to validate the JWT in the Authorization request header:

      {
        "requestPolicies": {
          "authentication": {
            "type": "JWT_AUTHENTICATION",
            "isAnonymousAccessAllowed": false,
            "issuers": ["https://identity.oraclecloud.com/"],
            "tokenHeader": "Authorization",
            "tokenAuthScheme": "Bearer",
            "audiences": ["api.dev.io"],
            "publicKeys": {
              "type": "STATIC_KEYS",
              "keys": [
                {
                  "format": "JSON_WEB_KEY",
                  "kid": "master_key",
                  "kty": "RSA",
                  "n": "0vx7agoebGc...KnqDKgw",
                  "e": "AQAB",
                  "alg": "RS256",
                  "use": "sig"
                }
              ]
            },
            "verifyClaims": [
              {
                "key": "is_admin",
                "values": ["service:app", "read:hello"],
                "isRequired": true
              }
            ],
            "maxClockSkewInSeconds": 10
          }
        },
        "routes": [
          {
            "path": "/hello",
            "methods": ["GET"],
            "backend": {
              "type": "ORACLE_FUNCTIONS_BACKEND",
              "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
            }
          }
        ]
      }
  2. Add an authorization request policy for each route in the API deployment specification:

    1. Insert a requestPolicies section after the first route's backend section, if one doesn't exist already. For example:

      {
        "requestPolicies": {
          "authentication": {
            "type": "JWT_AUTHENTICATION",
            "isAnonymousAccessAllowed": false,
            "issuers": ["https://identity.oraclecloud.com/"],
            "tokenHeader": "Authorization",
            "tokenAuthScheme": "Bearer",
            "audiences": ["api.dev.io"],
            "publicKeys": {
              "type": "STATIC_KEYS",
              "keys": [
                {
                  "format": "JSON_WEB_KEY",
                  "kid": "master_key",
                  "kty": "RSA",
                  "n": "0vx7agoebGc...KnqDKgw",
                  "e": "AQAB",
                  "alg": "RS256",
                  "use": "sig"
                }
              ]
            },
            "verifyClaims": [
              {
                "key": "is_admin",
                "values": ["service:app", "read:hello"],
                "isRequired": true
              }
            ],
            "maxClockSkewInSeconds": 10
          }
        },
        "routes": [
          {
            "path": "/hello",
            "methods": ["GET"],
            "backend": {
               "type": "ORACLE_FUNCTIONS_BACKEND",
               "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
            },
            "requestPolicies": {}
          }
        ]
      }
    2. Add the following authorization policy to the requestPolicies section:

      {
        "requestPolicies": {
          "authentication": {
            "type": "JWT_AUTHENTICATION",
            "isAnonymousAccessAllowed": false,
            "issuers": ["https://identity.oraclecloud.com/"],
            "tokenHeader": "Authorization",
            "tokenAuthScheme": "Bearer",
            "audiences": ["api.dev.io"],
            "publicKeys": {
              "type": "STATIC_KEYS",
              "keys": [
                {
                  "format": "JSON_WEB_KEY",
                  "kid": "master_key",
                  "kty": "RSA",
                  "n": "0vx7agoebGc...KnqDKgw",
                  "e": "AQAB",
                  "alg": "RS256",
                  "use": "sig"
                }
              ]
            },
            "verifyClaims": [
              {
                "key": "is_admin",
                "values": ["service:app", "read:hello"],
                "isRequired": true
              }
            ],
            "maxClockSkewInSeconds": 10
          }
        },
        "routes": [
          {
            "path": "/hello",
            "methods": ["GET"],
            "backend": {
              "type": "ORACLE_FUNCTIONS_BACKEND",
              "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
            },
            "requestPolicies": {
              "authorization": {
                "type": <"AUTHENTICATION_ONLY"|"ANY_OF"|"ANONYMOUS">, 
                "allowedScope": [ "<scope>" ]
              }
            }
          }
        ]
      }

      where:

      • "type": <"AUTHENTICATION_ONLY"|"ANY_OF"|"ANONYMOUS"> indicates how to grant access to the route:

        • "AUTHENTICATION_ONLY": Only grant access to end users that have been successfully authenticated. In this case, the "isAnonymousAccessAllowed" property in the API deployment specification's authentication policy has no effect.
        • "ANY_OF": Only grant access to end users that have been successfully authenticated, provided the JWT's scope claim includes one of the access scopes you specify in the allowedScope property. In this case, the "isAnonymousAccessAllowed" property in the API deployment specification's authentication policy has no effect.
        • "ANONYMOUS": Grant access to all end users, even if they have not been successfully authenticated. In this case, you must explicitly set the "isAnonymousAccessAllowed" property to true in the API deployment specification's authentication policy.
      • "allowedScope": [ "<scope>" ] is a comma-delimited list of one or more strings that correspond to access scopes included in the JWT's scope claim. In this case, you must set the type property to "ANY_OF" (the "allowedScope" property is ignored if the type property is set to "AUTHENTICATION_ONLY" or "ANONYMOUS"). Also note that if you specify more than one scope, access to the route is granted if any of the scopes you specify is included in the JWT's scope claim.

      For example, the following request policy defines a /hello route that only allows authenticated end users with the read:hello scope to access it:

      {
        "requestPolicies": {
          "authentication": {
            "type": "JWT_AUTHENTICATION",
            "isAnonymousAccessAllowed": false,
            "issuers": ["https://identity.oraclecloud.com/"],
            "tokenHeader": "Authorization",
            "tokenAuthScheme": "Bearer",
            "audiences": ["api.dev.io"],
            "publicKeys": {
              "type": "STATIC_KEYS",
              "keys": [
                {
                  "format": "JSON_WEB_KEY",
                  "kid": "master_key",
                  "kty": "RSA",
                  "n": "0vx7agoebGc...KnqDKgw",
                  "e": "AQAB",
                  "alg": "RS256",
                  "use": "sig"
                }
              ]
            },
            "verifyClaims": [
              {
                "key": "is_admin",
                "values": ["service:app", "read:hello"],
                "isRequired": true
              }
            ],
            "maxClockSkewInSeconds": 10
          }
        },
        "routes": [
          {
            "path": "/hello",
            "methods": ["GET"],
            "backend": {
              "type": "ORACLE_FUNCTIONS_BACKEND",
              "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
            },
            "requestPolicies": {
              "authorization": {
                "type": "ANY_OF",
                "allowedScope": [ "read:hello" ]
              }
            }
          }
        ]
      }
    3. Add an authorization request policy for all remaining routes in the API deployment specification.
    Note

    If you don't include an authorization policy for a particular route, access is granted as if such a policy does exist and the type property is set to "AUTHENTICATION_ONLY". In other words, regardless of the setting of the isAnonymousAccessAllowed property in the API deployment specification's authentication policy:

    • only authenticated end users can access the route
    • all authenticated end users can access the route regardless of access scopes in the JWT's scope claim
    • anonymous end users cannot access the route
  3. Save the JSON file containing the API deployment specification.
  4. Use the API deployment specification when you create or update an API deployment in the following ways:

    • by specifying the JSON file in the Console when you select the Upload an existing API option
    • by specifying the JSON file in a request to the API Gateway REST API

    For more information, see Deploying an API on an API Gateway by Creating an API Deployment and Updating an API Gateway or an API Deployment.

  5. (Optional) Confirm the API has been deployed successfully by calling it (see Calling an API Deployed on an API Gateway).

Example: Migrating a JWT_AUTHENTICATION Request Policy to a TOKEN_AUTHENTICATION Request Policy

This section shows an example of an existing JWT_AUTHENTICATION request policy migrated to a TOKEN_AUTHENTICATION policy.

One way to approach the migration is to create an empty TOKEN_AUTHENTICATION request policy, and then populate it with values from the JWT_AUTHENTICATION request policy

Before Migration:

The original JWT_AUTHENTICATION request policy, before migration:

{
  "requestPolicies": {
    "authentication": {
      "type": "JWT_AUTHENTICATION",
      "isAnonymousAccessAllowed": false,
      "issuers": ["https://identity.oraclecloud.com/"],
      "tokenHeader": "Authorization",
      "tokenAuthScheme": "Bearer",
      "audiences": ["api.dev.io"],
      "publicKeys": {
        "type": "STATIC_KEYS",
        "keys": [
          {
            "format": "JSON_WEB_KEY",
            "kid": "master_key",
            "kty": "RSA",
            "n": "0vx7agoebGc...KnqDKgw",
            "e": "AQAB",
            "alg": "RS256",
            "use": "sig"
          }
        ]
      },
      "verifyClaims": [
        {
          "key": "is_admin",
          "values": ["service:app", "read:hello"],
          "isRequired": true
        }
      ],
      "maxClockSkewInSeconds": 10
    }
  },
  "routes": [
    {
      "path": "/hello",
      "methods": ["GET"],
      "backend": {
        "type": "ORACLE_FUNCTIONS_BACKEND",
        "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
      },
      "requestPolicies": {
        "authorization": {
          "type": "ANY_OF",
          "allowedScope": [ "read:hello" ]
        }
      }
    }
  ]
}

After Migration:

The new TOKEN_AUTHENTICATION request policy populated with values from the original JWT_AUTHENTICATION request policy:

{
  "requestPolicies": {
    "authentication": {
      "type": "TOKEN_AUTHENTICATION",
      "isAnonymousAccessAllowed": false,
      "tokenHeader": "Authorization",
      "tokenAuthScheme": "Bearer",
      "maxClockSkewInSeconds": 10,
      "validationPolicy": {
        "type": "STATIC_KEYS",
        "keys": [
          {
            "format": "JSON_WEB_KEY",
            "kid": "master_key",
            "kty": "RSA",
            "n": "0vx7agoebGc...KnqDKgw",
            "e": "AQAB",
            "alg": "RS256",
            "use": "sig"
          }
        ],
        "additionalValidationPolicy": {
          "audiences": [
            "api.dev.io"
          ],
          "verifyClaims": [
            {
              "key": "is_admin",
              "values": [
                "service:app",
                "read:hello"
              ],
              "isRequired": true
            }
          ],
          "issuers": [
            "https://identity.oraclecloud.com/"
          ]
        }
      }
    }
  },
  "routes": [
    {
      "path": "/hello",
      "methods": [
        "GET"
      ],
      "backend": {
        "type": "ORACLE_FUNCTIONS_BACKEND",
        "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaab______xmq"
      },
      "requestPolicies": {
        "authorization": {
          "type": "ANY_OF",
          "allowedScope": [
            "read:hello"
          ]
        }
      }
    }
  ]
}