Understand the access token
The access token is the output of the OAuth token exchange. It is different from the client assertion your service created to request it. The authorization server issues the access token, and the Customer API validates it.
Bearer means possession of the token is normally enough to use it. Anyone who
obtains an unexpired token may be able to exercise its permissions, so protect
it as a secret. If the integration requires certificate proof, the matching
client certificate is required as an additional proof.
Treat the access token as opaque even if it resembles a JWT. Do not parse its claims to decide what the integration can access. Use discovery and API responses as the current authorization contract.
Send the token
read -rsp 'Customer API access token: ' WAVAC_ACCESS_TOKEN
echo
curl --fail-with-body \
-H "Authorization: Bearer $WAVAC_ACCESS_TOKEN" \
-H 'Accept: application/json' \
https://api.wavac.io/api/customer/v1/discovery
unset WAVAC_ACCESS_TOKEN
Use the access token only with the Customer API origin and routes supplied for
the integration. Put it in the Authorization header using the exact Bearer
scheme shown. Do not place it in a URL, cookie, or request body, and do not send
the client assertion as a Bearer token.
Renew and recover
Access tokens expire after 10 minutes. The client credentials flow does not issue refresh tokens. Before expiry, request another token with the integration's configured authentication mode. Customer-managed mode signs a new one-time client assertion; platform-managed mode presents the active mTLS certificate.
Use one process-wide token manager per credential:
- Normalize and sort the requested scope set. Reject empty, duplicate, or malformed scopes before sending a request.
- Key the in-memory cache by the credential, normalized scopes, and mTLS certificate SHA-256 thumbprint when certificate binding applies.
- Return a cached token only before its early-refresh time. Derive expiry from
expires_in; do not parse the token. - Allow only one refresh in flight. Other callers wait for that result instead of requesting parallel tokens.
- Begin replacement 90 to 120 seconds before expiry, using one cryptographically random jitter value per process to spread refresh load.
- Prove each candidate with the authentication session endpoint before publishing it to callers.
- If refresh fails transiently, retain the previous token only while more than 30 seconds remain. An authoritative
401or invalid response discards it and fails closed.
On a Customer API 401, discard the matching cached token. Retry at most once
with a newly authenticated request, and only when replay is safe. Do not
automatically replay a request that creates or changes state. A 403 means the
token was accepted but the integration is not permitted to perform that
request; requesting another token does not change that policy.
Do not persist access tokens, put them in distributed caches, or log them. This keeps the credential's exposure bounded to the process that uses it. A service with multiple instances must coordinate refresh frequency against the shared integration allowance. Jitter reduces synchronized refreshes but does not raise the allowance or guarantee that independent managers stay below it. See authentication limits.
Check the authentication session
Use the authentication session operation only to prove a newly issued token or to diagnose the current authentication boundary. It reads no customer data and does not consume the integration's daily API allowance.
HEAD /api/customer/v1/auth/session
Host: customer-api.wavac.io
Authorization: Bearer <access-token>
Platform-managed integrations must present the same client certificate used to
obtain the token. Customer-managed integrations use api.wavac.io and their
configured transport requirements. HEAD is preferred because the successful
response has no body; GET has the same status contract.
| Status | Meaning | Client action |
|---|---|---|
204 No Content |
The token, credential, integration, customer, audience, scopes, and any certificate binding are currently accepted. | Publish the token to waiting callers. |
401 Unauthorized |
Authentication or certificate binding failed. | Discard the candidate and stop; do not fall back to an older token after an authoritative failure. |
404 Not Found |
The current credential cannot access the requested Customer API surface. | Discard the candidate and review integration state and scopes. |
429 Too Many Requests |
The session-check allowance has been reached. | Honor Retry-After; keep a safely valid prior token if available. |
503 Service Unavailable |
The session check is temporarily unavailable. | Do not bypass the check. Honor Retry-After when present and keep a safely valid prior token if available. |
The operation is a current-session check, not a polling or health endpoint. Do not call it for every API request. The .NET token manager included in the Azure reference package demonstrates the in-process pattern. Its cache does not coordinate separate running jobs.
Revoking a credential stops its API access immediately, including requests with an otherwise unexpired token; there is no renewal grace period. If a token or signing key may be exposed, stop the integration and ask an administrator to revoke the credential.
Bearer-token transport follows OAuth 2.0 Bearer Token Usage (RFC 6750). Certificate-bound token use follows OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens (RFC 8705).