Customer API / Authentication

Use an access token

Keep the 10-minute access token out of URLs, source, logs, and persistent client storage.

In this article

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:

  1. Normalize and sort the requested scope set. Reject empty, duplicate, or malformed scopes before sending a request.
  2. Key the in-memory cache by the credential, normalized scopes, and mTLS certificate SHA-256 thumbprint when certificate binding applies.
  3. Return a cached token only before its early-refresh time. Derive expiry from expires_in; do not parse the token.
  4. Allow only one refresh in flight. Other callers wait for that result instead of requesting parallel tokens.
  5. Begin replacement 90 to 120 seconds before expiry, using one cryptographically random jitter value per process to spread refresh load.
  6. Prove each candidate with the authentication session endpoint before publishing it to callers.
  7. If refresh fails transiently, retain the previous token only while more than 30 seconds remain. An authoritative 401 or 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).