Skip to main content

OAuth Server

Learn how to configure the Authorization Server in AuthN to manage access to your APIs

You can use AuthN's OAuth 2 Authorization Server (AS) to define and manage access to your online resources, such as services and APIs. During authorization flows, a client application requests an access token from the AS. Permissions associated with the access token can be expressed via its scope . The client application can then use the access token to authorize requests to your Resource Server (RS).

Token values can be either an opaque string or a signed JSON Web Token (JWT). You can choose the type of active tokens in your Pangea project in AuthN Session Settings within the General section in the Pangea User Console. The RS can introspect an opaque access token to verify its issuer, audience, scopes, expiration, and other details, or read it from the signed JWT before granting access to a protected resource.

To set up the OAuth Server, Enable AuthN and navigate to the OAuth Server settings page in the Pangea User Console.

Audience

You can specify the intended audience for the access tokens issued by the AS. A list of the audience values you defined will be included in the token introspection results.

For example, an access token audience may contain an identifier of the RS or an API. In this case, permissions associated with the access token only apply at the RS or API matching the audience value. If there is no match, it may indicate a misrouting issue or a malicious access attempt, and access should be denied.

To manage audience values, click the pencil button next to the Audience label. In the edit dialog, type in an audience identifier and click Add to add a new value. Click the x button next to an existing audience value to remove it. Click Save to apply your changes.

note

You can also update the name of your OAuth Server in this dialog.

Set audience on the AuthN OAuth Server settings page in the Pangea User Console
OAuth Server Audience

Configuration Details

In the Configuration Details section, you can find reference to the OAuth Server endpoints and copy them by clicking the corresponding tiles:

Clients

note

If you plan to support granular access to your services and APIs, you might want to start by setting up custom scopes on the Scopes tab.

Click the Clients tab to display existing OAuth 2 client registrations. To register a new client app, click the + OAuth Client button on the right.

In the Create OAuth Client dialog, use the following inputs to provide details about your client:

  • Name - Assign a recognizable name to your client as it will appear in the list of clients in the OAuth Server settings. You can update this name at any time.
  • Grant Types - Select the grant types your client application will use. Currently, only the Client Credentials grant is supported, but the Authorization Code grant with OpenID Connect (OIDC) extension will become available soon.
  • Client secret expires in - Specify the lifespan for the new client secret. After it expires, you must generate a new secret for your client application.
  • Access token expires in - Specify the lifespan for access tokens issued by the AS to this client.
  • Allowed Scopes - Place the cursor in the input, select a scope value, and add it using the + button. This will enable the OAuth Server to add the scope to the tokens it issues to the client application. You can manage available scope values on the Scopes screen.
  • Default Scopes - The scope values you add to the client registration are automatically included in the default scope. This default scope is added to the access token when no specific scope is requested during the authorization flow. You can remove the default values by clicking the x button.
    Create OAuth Client dialog on the AuthN OAuth Server settings page in the Pangea User Console
    Register OAuth Client in AuthN's OAuth Server
  • Click the Create client button.
  • After registering the client, copy its secret from the Your OAuth Client Secret dialog by clicking on the Client Secret tile. Once you close the dialog, you will not be able to access the secret value again. However, you can add new secrets to the client later, with the option to copy them.
    Copy the secret value from the Your OAuth Client Secret dialog on the AuthN OAuth Server settings page in the Pangea User Console
    Copy Client Secret
  • Select a client record from the list to view and edit its Details. To access client-specific actions, click the triple-dot button in the client's row. This menu lets you delete the client registration or add a new client secret. You can also manage the client’s secrets on the Secrets tab.
    Client Details on the AuthN OAuth Server settings page and client-specific actions in the client context menu in the Pangea User Console

    OAuth Client Registration Details and Client-specific Actions

    Create secret dialog on the AuthN OAuth Server settings page in the Pangea User Console
    Create a New Client Secret

Scopes

Custom scopes

In OAuth 2 authorization flows, the optional scope parameter requests specific permissions to be included in a token. On the Scopes tab, you can add, modify, and delete custom scope values that your resource server recognizes.

To add a custom scope value, click the + Scope button on the right. In the Create Scope dialog, provide the new scope value details in the following fields:

  • Name - Define the scope value. This value will be included in the scope parameter during the authorization flow, and if granted, added to the access token's scope.

  • Display Name - Provide a recognizable name that will appear in the Display Name column in the scopes list.

  • Description - Explain what this scope value represents. For example, describe the permissions granted with this scope value.

  • Consent Required - Check this option to require explicit user approval for adding this scope value to the access token. This setting applies only to the Authorization Code grant.

Create custom scope the AuthN OAuth Server settings page in the Pangea User Console
Create custom scope

Predefined scopes

note

The predefined scopes apply only to the Authorization Code grant.

To edit a scope value, click a row in the list, and the scope value details will be displayed on the right. You can update all scope value properties except for its name. Click Save to apply your changes.

In the Clients section on the scope value details screen, you can see which client applications can request this scope to be added to the access tokens issued by the AS.

To delete a custom scope, click the triple-dot menu in the selected scope's row.

Scope Details on the AuthN OAuth Server settings page in the Pangea User Console
Scope Details

Client credentials grant

Diagram

The OAuth Server supports the Client Credentials grant . Your client application can use this grant to exchange its client ID and secret for access tokens.

Request access token

  1. Exchange the client credentials for an access token at the token endpoint.

    Send your access token request to the OAuth Server domain, which you can find in the OAuth Server Configuration Details.

    For example, save the domain into an environment variable. You will also need the client ID and its secret to authorize the request.

    Set environment variables
    export PANGEA_AUTHN_OAUTH_SERVER_DOMAIN="pdn-pgcrrev76s3d3bpj6bfwzol4g4wv4jft.login.staging.aws.pangea.cloud"
    export PANGEA_CLIENT_ID="psa_7phb65qiigumuv4rrahqk3gnahwvij7c"
    export PANGEA_CLIENT_SECRET="pck_tv67r5kxkilq6slsvpryu4k5svpm7vpf"
    note

    Alternatively, your application can GET it from the authorization server metadata:

    GET: /.well-known/oauth-authorization-server
    curl --location "https://$PANGEA_AUTHN_OAUTH_SERVER_DOMAIN/.well-known/oauth-authorization-server"
    response
    {
    "grant_types_supported": [
    "client_credentials"
    ],
    "introspection_endpoint": "https://pdn-bz2qkqu75erqiry7ubuy5b5t462tswyj.login.dev.aws.pangea.cloud/v1beta/oauth/token/introspect",
    "scopes_supported": [
    "openid",
    "email",
    "address",
    "phone",
    "profile",
    "files:upload"
    ],
    "token_endpoint": "https://pdn-bz2qkqu75erqiry7ubuy5b5t462tswyj.login.staging.aws.pangea.cloud/v1beta/oauth/token",
    "token_endpoint_auth_methods_supported": [
    "client_secret_basic"
    ],
    ...
    }

    Authorize your request with the client credentials using the Basic authentication scheme . For example, on a Unix-like system, including macOS, you can use the base64 utility:

    Create client credentials for the Authorization header
    echo -n "$PANGEA_CLIENT_ID:$PANGEA_CLIENT_SECRET" | base64
    Basic authentication value
    cHNhXzdwaGI2NXFpaWd1bXV2NHJyYWhxazNnbmFod3ZpajdjOnBja190djY3cjVreGtpbHE2c2xzdnByeXU0azVzdnBtN3ZwZg==

    Use the credential in your request to the token endpoint. Provide the following parameters:

    • grant_type - Use "client_credentials" as the value.
    • (optional) scope - Add space-delimited values that your resource server can understand before making the authorization decision.

    For example:

    POST: /v1beta/oauth/token
    curl --location "https://$PANGEA_AUTHN_OAUTH_SERVER_DOMAIN/v1beta/oauth/token" \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --header 'Authorization: Basic cHNhXzdwaGI2NXFpaWd1bXV2NHJyYWhxazNnbmFod3ZpajdjOnBja190djY3cjVreGtpbHE2c2xzdnByeXU0azVzdnBtN3ZwZg==' \
    --data-urlencode 'grant_type=client_credentials' \
    --data-urlencode 'scope=files:upload'
  2. The OAuth Server validates the client credentials.

  3. The OAuth Server responds with an access token . In the response, you receive a token value, either opaque or a signed JWT. The token type is always "Bearer", and the token lifespan is expressed in seconds in the expires_in field.

    Depending on the Session Configuration option selected on the AuthN Session Settings page within the General section, the access token value could be an opaque string or a signed JWT:

    /v1beta/oauth/token response: opaque (stateful) access token
    {
    "access_token": "pts_hpbc3klkkq54tigu4osc5eygthxps6vf",
    "token_type": "Bearer",
    "expires_in": 86399
    }
    /v1beta/oauth/token response: signed JWT (stateless) access token
    {
    "access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6InB2aV91Zmw0cnlkcTNpdnZrZTU0dzNzb2twZXllaWxud2Q1eXwxIiwia3R5IjoiSldUIn0.eyJpc3MiOiJodHRwczovL3Bkbi1wZ2NycmV2NzZzM2QzYnBqNmJmd3pvbDRnNHd2NGpmdC5sb2dpbi5zdGFnaW5nLmF3cy5wYW5nZWEuY2xvdWQiLCJzdWIiOiJwc2FfYWV5dmJvbWR3Mmw1d3Zqb203d210MnRtZnNzN3BwcGsiLCJleHAiOjE3MjYwMjYxNzYsIm5iZiI6MTcyNTkzOTc3NiwiaWF0IjoxNzI1OTM5Nzc2LCJqdGkiOiJwbXRfeXN0cXB5eG42c3d5aGd1Zm9iZmFmanFxN2xhNXBkZWIiLCJ0b2tlbl90eXBlIjoiY2xpZW50X2FjY291bnQiLCJvd25lciI6Ik15IEFwcCIsInNjb3BlcyI6WyJmaWxlczp1cGxvYWQiXX0.KXoklx3F0QGdMAUgT8g-Pm5n_FwPaQPpqjs4_LMS17eqNZDYn3FzG3Q7rRMnqnZPbmDvdwbZFu31ErYMbXXLSQ",
    "token_type": "Bearer",
    "expires_in": 86399
    }
  4. Your application authorizes a request to the resource server by adding the bearer token to the Authorization header.

    For example:

    curl --location 'https://api.example.com/resource' \
    --header 'Authorization: Bearer pts_hpbc3klkkq54tigu4osc5eygthxps6vf' \
    --header 'Content-Type: application/json' \
    --data '{
    "resource-id": "resource-1"
    }'

Validate access token

Opaque access token

  1. The resource server introspects the access token.

    Authorize your request with the client ID using the Basic authentication scheme. For example, on macOS, you can use the base64 utility:

    Create client credentials for the Authorization header
    echo -n "$PANGEA_CLIENT_ID:" | base64
    note

    You must add a colon after the client ID to indicate the separation between the username (client ID) and password, even though the latter is not required.

    Basic authentication value
    cHNhXzdwaGI2NXFpaWd1bXV2NHJyYWhxazNnbmFod3ZpajdjOg==

    Provide the access token value as the token parameter:

    POST: /v1beta/oauth/token/introspect
    curl --location "https://$PANGEA_AUTHN_OAUTH_SERVER_DOMAIN/v1beta/oauth/token/introspect" \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --header 'Authorization: Basic cHNhXzdwaGI2NXFpaWd1bXV2NHJyYWhxazNnbmFod3ZpajdjOg==' \
    --data-urlencode 'token=pts_hpbc3klkkq54tigu4osc5eygthxps6vf'
  2. The OAuth Server returns a standard Introspection Response :

    response
    {
    "client_id": "psa_aeyvbomdw2l5wvjom7wmt2tmfss7pppk",
    "scope": "files:upload",
    "aud": [
    "api.example.com",
    "api2.example.com"
    ],
    "iss": "https://pdn-pgcrrev76s3d3bpj6bfwzol4g4wv4jft.login.staging.aws.pangea.cloud",
    "exp": 1726025937,
    "iat": 1725939537,
    "nbf": 1725939537,
    "jti": "pmt_ygi5fdri4rqlnhvr7hypwoima3age35p",
    "token_type": "Bearer",
    "active": true
    }
    note

    Currently, only opaque access tokens issued by the AuthN OAuth Server can be introspected.

Signed JWT

  1. The RS validates the stateless access token.

    The decoded JWT payload contains similar data to introspection results:

    Decoded JWT payload
    {
    "iss": "https://pdn-pgcrrev76s3d3bpj6bfwzol4g4wv4jft.login.staging.aws.pangea.cloud",
    "sub": "",
    "exp": 1726026176,
    "nbf": 1725939776,
    "iat": 1725939776,
    "jti": "pmt_ystqpyxn6swyhgufobfafjqq7la5pdeb",
    "client_id": "psa_aeyvbomdw2l5wvjom7wmt2tmfss7pppk",
    "token_type": "Bearer",
    "active": true
    }

    Verify JWT signature

    To verify the signature of a JWT received by your application, your application can retrieve the public key from the JSON Web Key Set (JWKS) available at the issuer's /v1beta/oauth/jwks.json path. Pangea issues standard JWTs that can be validated with JWKS using your favorite library. This approach to validate JWTs is widely supported.

    In protected environments, you could also retrieve the corresponding public key using Vault APIs.

    Use JWKS

    If your application, such as a mobile app, cannot safely store the Vault service token, you can instead use the publicly available JWKS to generate the public key. Append /v1beta/oauth/jwks.json path to the issuer URI in a decoded JWT and use it to retrieve the JWKS. For example:

    jwks.json
    {
    "keys" : [
    ...,
    {
    "alg" : "ES256",
    "crv" : "P-256",
    "kid" : "pvi_dzbpej6fegceveo66ofsjc6jq4nt5xwh|2",
    "kty" : "EC",
    "x" : "HNVhj_BFpDZWc5i-1TRR2dLmSgvzlLbKD6BUDsUKGeo",
    "y" : "laA5au3cuwoy78dwzi7E2urphJpk8tUF0RBHaavdQe8"
    },
    {
    "alg" : "ES256",
    "crv" : "P-256",
    "kid" : "pvi_dzbpej6fegceveo66ofsjc6jq4nt5xwh|1",
    "kty" : "EC",
    "x" : "kWqMYYDrxFLR0S88wxisf6ro7JaQwRZlDhSUiHPe9sc",
    "y" : "MFxmc5OF4cRaQ0dDakw6pAG3xIINFeyzuYqWeQs19yk"
    }
    ]
    }

    New versions of keys will be added to the set as the JWT key saved in Vault is rotated. The key version is shown in the "kid" value after the | delimiter.

    To automate the JWKS retrieval and application you can use one of the JWT Libraries for Token Signing/Verification .

    Example:

    pip install 'pyjwt[crypto]'
    Use JWKS
    import jwt
    from jwt import PyJWKClient

    token = "eyJhbGciOiJFUzI1NiIsImtpZCI6InB2aV9qZGp5amFudnZtb3hpMnB1N3RtcWFnY3B4enV2bnViZXw1Iiwia3R5IjoiSldUIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
    url = "<JWKS-path>"
    jwks_client = PyJWKClient(url)
    signing_key = jwks_client.get_signing_key_from_jwt(token)
    data = jwt.decode(
    token,
    signing_key.key,
    algorithms=["ES256"],
    options={"verify_exp": False},
    )

    print(data)
    Use public key from Vault

    To obtain the public key dynamically, you can request it from the Vault /v1/get endpoint by providing the JWT key ID and authorizing the request with a Vault service token. You can get the default service token for Vault from its Configuration Details under Vault Overview in the Pangea User Console, or you can create a service token in Project Settings >> Tokens and explicitly associate it with Vault.

    export PANGEA_DOMAIN="aws.us.pangea.cloud"
    export PANGEA_VAULT_TOKEN="pts_gqmqvvxk4yhirapuhw6bs7nswu"

    Note that the items in Vault can be versioned. Rotating the JWT signing key will require the use of an appropriate version of the public key in your application. In the request data, you can optionally provide the version number or request all versions of the public key via the "version" parameter. If you don't specify a version in your request, the latest will be returned.

    /v1/get JWT public key
    curl --location "https://vault.$PANGEA_DOMAIN/v1/get" \
    --header "Authorization: Bearer $PANGEA_VAULT_TOKEN" \
    --header 'Content-Type: application/json' \
    --data '{
    "id":"pvi_jdjyjanvvmoxi2pu7tmqagcpxzuvnube",
    "version":"all"
    }'

    The latest public key version for verifying the JWT signature will be included as result.current_version.public within the response. Older versions can be found in the "version" array. Including previous keys allows you to accept tokens minted just before the signing key has been rotated, either manually or on an automated schedule.

    /v1/get response
    {
    "result": {
    "current_version": {
    "public_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGY4p4VYSqOAh2yncQE31kJaWzgAr\n/fVvYAyf7hnkd6bhJmN24IiujCiYhKiRWA7QGwF7jmPvTDjxwd4/0RSt8Q==\n-----END PUBLIC KEY-----\n",
    "state": "active",
    "version": 1,
    ...
    },
    "id": "pvi_jdjyjanvvmoxi2pu7tmqagcpxzuvnube",
    "item_state": "enabled",
    "metadata": {
    "authn_config_id": "pro_jbxwlzvhyubldhe27fa57t234k52jda3"
    },
    "purpose": "jwt",
    "type": "asymmetric_key",
    ...
    "versions": [
    {
    "public_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGY4p4VYSqOAh2yncQE31kJaWzgAr\n/fVvYAyf7hnkd6bhJmN24IiujCiYhKiRWA7QGwF7jmPvTDjxwd4/0RSt8Q==\n-----END PUBLIC KEY-----\n",
    "state": "active",
    "version": 5,
    ...
    },
    ...,
    {
    "public_key": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEo4Y3Vh3dU2EaiFrPAZ1LKVukdHz5\n7wKJmEOMB4x8TyvIEuC/w61yr3fdU23rBpyPguAx/IWnVI2UV8TAjZ7HVQ==\n-----END PUBLIC KEY-----\n",
    "state": "deactivated",
    "version": 1,
    ...
    }
    ]
    },
    "status": "Success",
    "summary": "Key pair retrieved",
    ...
    }

    In the above example, the latest/current version is 5.

    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5kCKMlbs8eYSxV8JzGkpmy1CI9BO
    AJHqsQ2ubRr1dQkVwH183NFs6/8khtMUTtCzmtZ7F/hjAVG7QUxkzt/kLA==
    -----END PUBLIC KEY-----
    note

    For testing your JWT, for example on https://jwt.io/, you can get a public key from Vault Secrets & Keys in the Pangea User Console:

    1. Navigate to AuthN General >> Session Settings and click the Signing Key Vault ID link. This will take you to the JWT key saved in Vault.
    2. The JWT Key form for the selected Vault item should be opened on the right-hand side. If it is not, click on the row representing your JWT Key.
    3. In the JWT Key form, click the triple-dot menu button and select Copy public key.
    4. Save the key in a location accessible to your application.

Process claims, make authorization decision

  1. Your resource server is likely to base its authorization decisions on the following fields in the introspection response:

    • "active" - A value of true indicates that the token is valid and currently active. A value of false means the token is invalid, expired, revoked, or otherwise inactive.
    • "client_id" - Represents the client ID which initially requested the token.
    • "scope" - Space-delimited scope values that are included in the token.
    • "aud" - Represents the intended service(s) or API(s) for which this access token is issued.
    • "iss" - The origin of the OAuth Server.
    • "exp" - The token's expiration date.
    • "iat" - The token's issue date.
    • "nbf" - The token's effective date.

    Each date is expressed as the number of seconds since the Unix Epoch (January 1, 1970, UTC).

  2. The resource server returns data from the API or responds with an error .

Was this article helpful?

Contact us