OAuth Enhancements

Developer Implementation Guide

This guide describes how to implement the advanced OAuth security features available in the Intandem platform. These include:

Use this guide to integrate securely and efficiently with the Intandem authorization server.


📘

Implementation of these features is optional. The standard OAuth 2.0 flow with client_secret and opaque tokens remains fully supported. These enhancements are recommended for higher security and specific architectural needs.


1. PKCE (Proof Key for Code Exchange)

PKCE (RFC 7636) is fully supported for Authorization Code flows within the Intandem platform. It provides an additional layer of security by ensuring that the client exchanging the authorization code is the same client that initiated the authorization request.


Description

PKCE prevents authorization code interception attacks by binding the authorization request to the token exchange request. It is highly recommended for all client applications and required for public or mobile applications that cannot securely store a client secret.


Technical Info

PKCE is enabled automatically whenever the following parameters are included in the authorization request:

  • code_challenge
  • code_challenge_method (must be S256)

Usage

1. Generate a Code Verifier

Create a high-entropy random string (43–128 characters) using unreserved characters:

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789
- . _ ~

2. Generate a Code Challenge

Generate the code challenge by:

  1. Calculating the SHA-256 hash of your code_verifier
  2. Encoding the result using Base64URL (no padding)

3. Begin the Authorization Request

Redirect the user to:

/oauth/authorize?response_type=code&...&code_challenge=<challenge>&code_challenge_method=S256

Include the challenge in your authorization URL:

ParameterDescription
code_challengeThe hashed and encoded value from step 2
code_challenge_methodMust be S256

4. Receive the Authorization Code

After user authentication and consent, Intandem redirects back to your redirect_uri with:

code=<authorization_code>

5. Exchange the Authorization Code for Tokens

Make a POST request to:

/oauth/token

Include the original verifier when exchanging the code:

ParameterDescription
grant_typeauthorization_code
codeAuthorization code from step 4
redirect_uriMust match the initial request
client_idYour app’s client ID
code_verifierThe original string from step 1

6. Token Issuance

Intandem validates that the code_verifier corresponds to the original code_challenge. If valid, access and refresh tokens are issued.


2. Client Authentication Using Private Key JWT

The Intandem platform supports private_key_jwt (RFC 7523) for OAuth client authentication. This method allows you to authenticate using asymmetric keys (signed JWT assertions) instead of a shared client_secret.

📘

Standard client authentication using client_secret is still fully supported. You may choose either method based on your security requirements.


Description

With private_key_jwt:

  • The client signs a JWT (Client Assertion) using its private key
  • Intandem verifies the signature using the client’s public keys (retrieved from your configured JWKS endpoint)
  • All validations follow RFC 7523 and OAuth 2.0 best practices

This improves security by eliminating shared secrets and enabling sender-constrained authentication.


Technical Info

Clients may authenticate using:

  • Traditional client_secret, or
  • private_key_jwt using a signed assertion

private_key_jwt is recommended for highly secure integrations and partner-facing applications.


Setup

Before using this flow (or when rotating keys), you must configure your application.

1. Generate an Asymmetric Key Pair

Create a public/private key pair (RSA 2048-bit or higher). Keep the private key secure, this will be used to sign client assertions.

2. Create a JWKS Endpoint

Expose your public key(s) via a JWKS endpoint served over HTTPS. The JSON Web Key Set must contain standard fields like kty, kid, n, and e.

3. Register the URL

Configure your application with the JWKS endpoint URL via Create or Update App API:

  • Field: client_auth_jwks_uri

Usage

1. Create the JWT Assertion Payload

Create a JWT with the following claims in the payload:

ClaimRequiredDescription / Value
issYesIssuer: Set to your client_id
subYesSubject: Set to your client_id
audYesAudience: Set to Intandem's token endpoint URL (e.g., https://api.vcita.biz/oauth/token)
expYesExpiration: Set to a future timestamp
jtiNoJWT ID: Unique identifier to prevent replay attacks
iatNoIssued At: Current timestamp
nbfNoNot Before: Timestamp before which the JWT is invalid

Validation Requirements Enforced by Intandem:

  • JWT must not be expired
  • Lifetime must not exceed 5 minutes
  • Each jti may be used only once (within 5 minutes)

2. Sign the JWT

Sign your client assertion using your private key with the RS256 algorithm.

Include the following properties in the JWT headers:

HeaderValue
algRS256
typJWT
kidIdentifier of the signing key (must match the kid in your JWKS)

3. Submit Token Request

When exchanging your authorization code or requesting a new token, replace client_secret with the assertion parameters:

POST /oauth/token

ParameterValue
client_assertion_typeurn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertionThe signed JWT string you generated
client_idYour application's Client ID
Other OAuth parametersBased on your grant type (e.g., code, redirect_uri, grant_type)

4. Token Issuance

Intandem validates the request by:

  1. Retrieves your JWKS
  2. Matches the kid
  3. Verifies the signature
  4. Validates the payload claims

Tokens are issued after successful authentication.


3. JWT Access Tokens

The Intandem platform supports issuing OAuth 2.0 access tokens in signed JWT format, following RFC 9068 and OpenID Connect best practices. This allows your application or identity provider to validate access tokens locally without making a request to Intandem.

📘

Standard opaque access tokens are still fully supported and remain the default. You may choose the token format that best fits your architecture.


Description

A JWT access token:

  • Contains structured claims about the authenticated subject
  • Is signed using Intandem’s private keys
  • Can be verified locally using Intandem’s JWKS
  • Removes the need for token introspection calls

Setup

Configure your application to receive JWT access token by setting the access_token_format field to jwt via Create or Update App API:

  • Field: access_token_format

If not configured, tokens default to opaque.


Usage

1. Receive the Access Token

After calling /oauth/token, the response includes:

  • A JWT access token (structure: header.payload.signature)
  • A refresh token (single-use)

2. Decode the JWT Header

Extract:

  • kid: Key identifier for selecting the correct public key
  • alg: Signing algorithm (typicallyRS256)
  • typ: Token type (at+jwt per RFC 9068)

3. Retrieve Intandem’s Public Keys

Fetch the JWKS from:

https://<intandem-domain>/.well-known/jwks.json

Tip: Keys should be cached for performance.


4. Select the Matching Key

Choose the key wherekid matches the token header.


5. Verify the JWT Signature

Use a standard JWT library with the selected public key to verify:

  • Integrity: The signature is valid
  • Authenticity: The token was issued by Intandem
  • Expected claims

6. Use the Access Token

Include the JWT access token in your API requests to Intandem's resource servers using the following header

Authorization: Bearer <access_token>

7. Refreshing the Token

To refresh an access token, call /oauth/token with:

ParameterValue
grant_typerefresh_token
refresh_tokenThe refresh token provided earlier
Client Authenticationclient_id AND one of the following: client_secret OR client_assertion + client_assertion_type

A new access token and refresh token will be returned. The old refresh token becomes invalid once used.


Additional Material

Intandem JWKS Example

The platform’s JWKS can be found at:

https://api2.vcita.com/.well-known/jwks.json

Use this endpoint to obtain the public keys needed to verify JWT access tokens.