Skip to main content
Version: 10.5.0

Obtaining an OAuth Access Token

This process assumes you have already created OAuth credentials as described under Create an Access Token.

Understanding the OAuth Client Credentials Flow

The OAuth 2.0 Client Credentials flow enables secure server-to-server authentication. In this flow:

  1. A client application (server) authenticates itself to the authorization server
  2. The client receives an access token
  3. The access token is used to access protected resources

This flow is designed for machine-to-machine (M2M) communication where no user interaction is required.

OAuth Client Credentials in HYPR

HYPR's implementation uses JWT (JSON Web Token) for client assertion in the OAuth 2.0 Client Credentials flow. The client uses its private key to sign a JWT and then exchanges this JWT for an access token.

Key features:

  • Security: Uses asymmetric cryptography for authentication
  • Replay protection: Each JWT has a unique ID (jti) and short lifespan
  • Throttling: Limits the number of active access tokens per client
  • Scoped access: Tokens are limited to specific API operations
info

HYPR has provided a JWT creation signing tool for your convenience.

Step 1: Generate JWT Assertion

  1. Download JWTCreator.java (right-click the link and select Save link as...). This vanilla Java code is all you need to generate and sign a JWT token

    ℹ️ Needs Java 17+

    $ java JWTCreator.java -help

    Usage: java JWTCreator [options]
    Options:
    -help Show this help message and exit
    -sub <subject> MANDATORY subject claim. `Client Id` from CC UI token creation screen
    -keybase64 <key> MANDATORY base64 private key. `Client key` from the CC UI token creation screen
    -exp <expiration> OPTIONAL expiration time of the JWT token created. In seconds since epoch. Default: now() + 1 hour
    -out <file> OPTIONAL output file to write the JWT token
  2. Run the following command to generate the assertion, substituting the Client ID and Client Key values obtained in Create an Access Token:

    Example command, for a JWT expiring in 6 hours:

    java JWTCreator.java \
    -sub "hypap-0a2c1e47c4b9dummy" \
    -keybase64 "MEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCCRAVkCsog/IXLcUxrMrlaijsSQhzZTEZzagSivhmpw5A==" \
    -exp $(($(date +%s) + 21600))
  3. The resulting JWT will be created in the same folder where JWTCreator.java is stored. The contents will be similar to the following example. For reference, see Microsoft identity platform application authentication certificate credentials.

    Example output:

    Use this JWT to exchange for an access token, which lets you authenticate with the API.

    eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImZjYzYyMGNjLWVjYjYtNDdmOS05N2ExLWRkMTMwZjRhM2ZiNiJ9.eyAiaXNzIjogImh0dHBzOi8vaHlwci5jb20iLCJzdWIiOiAiaHlwYXAtMGEyYzFlNDdjNGI5ZHVtbXkiLCJhdWQiOiAiaHR0cHM6Ly9oeXByLmNvbSIsImp0aSI6ICJjNjgxOWM2Zi0zODRlLTRiMjEtOTk0YS01NWNjM2UyNWZmY2EiLCJleHAiOiAxNzU4NDMyNDI1LCJpYXQiOiAxNzU4NDI4ODI1LCJuYmYiOiAxNzU4NDI4ODI1IH0.MQaayVLr4N7mXHBlnk7eEVlma8JjWu5hBzDBNXwbq9MsnVpNk6LqWlZHGugFBEu9rf2gOfiGrRsFkkJTOJOuPg

    Decoded JWT token

    {
    "alg": "ES256",
    "typ": "JWT",
    "kid": "04a04a2c-5440-4cb8-bd3f-3c24af60924a"
    }
    .
    {
    "iss": "https://hypr.com",
    "sub": "hypap-0a2c1e47c4b9dummy",
    "aud": "https://hypr.com",
    "jti": "214cf44c-1123-4dbd-a7ec-387b1ee2baa9",
    "exp": 1758428668,
    "iat": 1758425068,
    "nbf": 1758425068
    }
    .
    "eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJoeXBh{...}7GFa8A"

The JWT header contains the following important claims:

ClaimSample valueDescription
algES256The algorithm used to sign the JWT
typJWTThe media type of this complete JWT
kid04a04a2c-5440-4cb8-bd3f-3c24af60924aThe "kid" (key ID) Header Parameter is a hint indicating which key was used to secure the JWS. When used with a JWK, the "kid" value is used to match a JWK "kid" parameter value.

The JWT body contains the following important claims:

ClaimSample valueDescription
subhypap-0a2c1e47c4b9dummyThe subject of the JWT (the user). Client Id from CC UI token creation screen
isshttps://hypr.comThe issuer of the JWT. Must be https://hypr.com
audhttps://hypr.comThe recipients that the JWT is intended for. Must be https://hypr.com
jti214cf44c-1123-4dbd-a7ec-387b1ee2baa9The unique identifier for the JWT. UUID.
exp1758428668The expiration time on or after which the JWT MUST NOT be accepted for processing. Time since epoch, in seconds. This is from the -exp param to the JWTCreator.java. Defaults to 1 hour from now.
iat1758425068The time at which the JWT was issued. Time since epoch, in seconds. Defaults to now
nbf1758425068The time before which the JWT MUST NOT be accepted for processing. Time since epoch, in seconds. Defaults to now

Step 2: Exchange JWT for Access Token

Take the generated JWT assertion and use it to request an access token from the server:

  1. Copy the client_assertion (the long string at the end; in this example, eyJhbG...OfiGrRsFkkJTOJOuPg) and use it to issue a cURL command using the following format:

    ParameterValue
    client_assertion_typeurn:ietf:params:oauth:client-assertion-type:jwt-bearer
    client_assertionThe JWT assertion string generated in Step 1; in our example, it is eyJhbG...OfiGrRsFkkJTOJOuPg.
    grant_typeauthorization_code
  2. Make the token request:

    Sample cURL Command
    curl --location 'https://highlandsbank.hypr.com/rp/token/endpoint/exchange/clientcredentials' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer' \
    --data-urlencode 'client_assertion=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjMyMDU0YmFjLWZmMzktNGYwZi05MDg5LTIyNWRmODFiZDQxMyJ9.eyAiaXNzIjogImh0dHBzOi8vaHlwci5jb20iLCJzdWIiOiAiaHlwYXAtZjZmN2RjNzZiMTBlNDkyOThiNWVkZjNmOWQ3ZTQ5NjUiLCJhdWQiOiAiaHR0cHM6Ly9oeXByLmNvbSIsImp0aSI6ICJhZDE2YzZlYy1kYTU5LTQyM2ItOTQzNi1iMjY1NWMwMTI1ODAiLCJleHAiOiAxNzQ1MDk5NjUxLCJpYXQiOiAxNzQ1MDk2MDUxLCJuYmYiOiAxNzQ1MDk2MDUxIH0.C6Z8dTJKmu030iU3XbuqjWp3EN3TOTI5i_rvR-cxHC2rEhi44uJYzpbpZPAtJE419tgeU4jJuxeNHN0JSwwlFw' \
    --data-urlencode 'grant_type=authorization_code'
  3. The server validates the JWT assertion by:

    • Verifying the JWT signature using your client's public key
    • Checking that the JWT is not expired
    • Ensuring the JWT has not been used before (replay protection)
    • Validating the audience, issuer, and subject claims
  4. If successful, the server responds with an access token:

    This token can be used to make API calls, until it expires

    {
    "token_type": "Bearer",
    "expires_in": 3599,
    "access_token": "hypap-f24ae508-356e-4b5b-bc71-dummy",
    "scope":"hypr:rp:report hypr:cc:applications"
    }
    PropertyDescription
    token_typeThe type of token. In this case, it will always be Bearer.
    expires_inThe number of seconds before this token expires, as determined by the value of Expires during Create an Access Token. The access token may be used any number of times before it expires. An expired token will receive a 401/403 response.
    access_tokenThe access token value. Copy and save it for later use.
    scopeA space-separated list of scopes (permissions) granted to this token.
  5. If the request fails, you'll receive an error response:

    {
    "error": "invalid_scope",
    "error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid",
    }

Step 3: Make API call

Include the access token in the Authorization header Example:

   GET http://localhost:8009/rp/api/bulk/HYPRDefaultApplication/introspect
Authorization: Bearer hypap-f24ae508-356e-4b5b-bc71-dummy

Common Errors and Troubleshooting

Error CodeDescriptionPossible CausesRecommended Solutions
1201023Invalid request parameters during token creationOAuth client credentials used with incorrect scopes • TTL less than 60 secondsUse OAuth client credentials only for API scopes • Set TTL to minimum 60 seconds
1201046Endpoint API token invalid or expiredToken not found, expired, wrong type, invalid scope, or rpAppId mismatchVerify token exists • Generate new token • Use CLIENT_CREDENTIALS type • Check scope and rpAppId
1201047Invalid token exchange requestMissing JWKS URL, signature verification failed, expired JWT, invalid claims, missing keyID headerProvide valid JWKS URL • Ensure proper JWT signing • Check expiration and claims • Include keyID header
1201093OAuth request throttledExcessive requests for JWT token exchangesReduce request frequency • Review implementation for proper reuse. Once a JWT token is exchanged, use it until expiry. Similarly, re-use the access token until it expires.

Security Best Practices

  1. Protect private keys: Store your private key securely
  2. Short-lived JWTs: Use short expiration times for JWTs (typically 5-10 minutes)
  3. Minimize scopes: Request only the scopes needed for your application

Use the Access Token