Client Credentials Flow
The OAuth 2.0 Client Credentials Flow is an authentication method designed for server-to-server or machine-to-machine interactions, where an application needs to securely obtain an access token without direct user involvement. This flow is commonly used for backend services, automation tasks, administrative functions, or system-level integrations that require secure API access.
Key Concepts and Terminology
- Client (Application): The trusted application or server requesting resource access directly, without user interaction.
- Authorization Server (Jack Henry Authentication Framework): Issues access tokens after client authentication.
- Resource Server (Jack Henry APIs): Provides protected resources upon receiving valid tokens.
- Access Token: Credential allowing the client to access protected resources.
- JWT-Based Client Authentication: Secure authentication using signed JWTs and public/private key pairs, exclusively supported by Jack Henry for this flow.
When to Use Client Credentials Flow
- Backend services executing tasks without direct user input.
- Automated processes, such as scheduled jobs or data synchronization routines.
- Administrative or privileged API access, including Jack Henry’s Admin APIs.
Step-by-Step Client Credentials Flow (JWT-Based Authentication)
signed with private key Client_Backend->>Auth_Server: Request token (POST)
grant_type=client_credentials,
client_assertion,
client_assertion_type,
scope Auth_Server->>Client_Backend: Issue access token Client_Backend->>Client_Backend: Securely store access token end rect rgb(255, 245, 200) note over Client_Backend,Resource_Server: Accessing Resources Client_Backend->>Resource_Server: API call with Access Token
Authorization: Bearer ACCESS_TOKEN Resource_Server->>Client_Backend: Return protected resources end
1. Application Registration
Register your application with Jack Henry’s Authentication Framework, configuring public/private key pairs specifically for JWT-based authentication. During registration, upload your public key or provide a JWKS URL to Jack Henry. Once the application has been registered successfully, a client id will be created which can then be used by your application to request a token.
2. Generate JWT and Request Token
To authenticate, you must generate a signed JWT (client_assertion) using your registered private key. The JWT must contain the following claims:
jti: A unique identifier for the token, used as a nonce to prevent replay attacks.aud: The exact URL of the token endpoint (e.g.,https://login.jackhenry.com/a/oidc-provider/api/v0/token).sub: The Client ID of the application.iss: The Client ID of the application.exp: A timestamp (in seconds) indicating when the JWT will expire. Do not set this value to more than 5 minutes (300 seconds) from the time of issuance.
The JWT must be signed with your application’s private key. The following algorithms are supported by Jack Henry’s Authentication Framework:
ES256- ECDSA using P-256 and SHA-256PS256- RSASSA-PSS using SHA-256 with MGF1 and SHA-256RS256- RSASSA-PKCS1-v1_5 using SHA-256
Submit the JWT in a POST request to the token endpoint (Banno-specific example):
POST AUTHORIZATION_SERVER_URL/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_assertion=GENERATED_JWT
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&scope=openid full
Note: AUTHORIZATION_SERVER_URL could be https://login.jackhenry.com or another authorization server.
3. Receive Access Token
The authorization server responds with a JSON object:
{
"access_token": "eyJhbGciOiJIUzI1NiIsIn...",
"expires_in": 600,
"token_type": "Bearer"
}
Using Access Tokens
Include the access token in the Authorization header when making API calls:
GET API_SERVER/TARGET_ENDPOINT
Authorization: Bearer eyJhbGciOiJIUzI1NiIsIn...
Notes:
API_SERVERcould behttps://banno.com/or another API server.
Token Lifecycle and Expiration
- Tokens obtained through Client Credentials Flow have no refresh tokens.
- When tokens expire, the client must request a new token by repeating the token request process.
Example Implementation (Simplified)
Using curl to request an access token and call an API endpoint:
# Generate and sign your JWT first, then request an access token
curl -X POST https://login.jackhenry.com/a/oidc-provider/api/v0/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_assertion=GENERATED_JWT&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&scope=admin:read"
# Call a protected API endpoint
curl -X GET https://banno.com/TARGET_ENDPOINT \
-H "Authorization: Bearer ACCESS_TOKEN"
Security Considerations and Best Practices
- Secure private keys: Store private keys securely in environment variables or secure storage solutions like key vaults.
- Least privilege: Request only necessary scopes to minimize access risks.
- Token management: Implement efficient token caching and renewal processes.
Troubleshooting Common Issues
- Invalid credentials: Ensure the JWT is correctly signed and matches your registered public key.
- Scope errors: Confirm requested scopes match those approved during registration.
- Token expiration handling: Automate token renewal upon expiration to maintain seamless API interactions.
- Permission errors: Verify the client has appropriate privileges for requested API actions.
Differences from Other OAuth Flows
The Client Credentials Flow is distinct from the Authorization Code Flow in several ways:
- No user interaction: Exclusively for server-to-server interactions.
- No refresh tokens or consent screens: Tokens are issued without user involvement or consent screens.
- Have a how-to question? Seeing a weird error? Get help on StackOverflow.
- Register for the Developer Office Hours where we answer technical Q&A from the audience.