Authentication & OAuth 2.0
Guidance for managing access and refresh tokens across Bead integrations. This page covers both integration models you support today: Payments and Boarding and Entity Management.
Integration identities at a glance
Payments
Payments client
Terminal username and password (for example [email protected]
)
Password grant (terminal scoped)
terminalId (or clientId + merchantId + terminalId if you key by all)
Optimize for low latency and high volume
Boarding and Entity Management
Boarding client
Single integrator username and password
Password grant (today)
clientId (often a single token is sufficient)
Latency is secondary and auditability is primary
Token types and lifetimes
Access token
3600 seconds
Sent on every API call in Authorization: Bearer <access_token>
Refresh token
36000 seconds
Exchanged with the identity server to obtain a new access token and a new refresh token
Lifetimes can vary by environment and client. Always honor the expires_in
and refresh_expires_in
values returned by your token endpoint.
Standard policy for both models
Cache the access token and refresh two to five minutes before expiry.
If an API call returns 401 Unauthorized, perform one refresh and retry the request once.
Always store the newest refresh token that the identity server returns.
If refresh fails with
invalid_grant
or the refresh token is expired, perform a full sign in.Keep tokens on the server only. Do not log tokens. Encrypt at rest if persisted.
In multi process or multi worker apps, ensure only one worker performs the refresh and others reuse the result.
Payments integration (terminal scoped credentials)
Goal Fast and reliable requests at scale without authenticating on the hot path.
Policy highlights
Do not call the token endpoint per transaction.
Maintain a shared token cache keyed by terminalId (or by clientId + merchantId + terminalId if your app organizes this way).
Refresh proactively with a small buffer and add random jitter so many tokens do not refresh at the same second.
Use a leader process to perform the refresh and fan out the new pair to workers.
Warm the cache for your busiest terminals at service start or during off peak windows.
Only do a full sign in if refresh fails.
Boarding and entity management (password grant today)
Goal Safe and auditable operations where latency is less critical.
Policy highlights
Use the same refresh and 401 retry rules. A larger pre expiry buffer is fine since latency is not a concern.
A single service level token is usually sufficient for the whole administrative workload.
Emphasize least privilege scopes and clear audit logging of who did what and when.
Why use refresh tokens
Security and reliability first
Renew access without resending primary credentials.
The identity server can revoke a refresh token family to cut off access quickly.
Each refresh issues a fresh access token so roles and scopes remain current.
Performance
One light refresh call is faster and cheaper than a full sign in.
Fewer round trips and fewer failures under load.
With expires_in = 3600
and refresh_expires_in = 36000
, integrators can keep a one hour access token hot and silently renew for about ten hours without handling passwords again.
Error handling quick reference
401
—
Access token missing, malformed, or expired
Refresh once and retry once. If it still fails, perform full sign in.
400
invalid_grant
Refresh token expired, revoked, or already used
Perform full sign in to obtain a new token pair.
400
invalid_client
or unauthorized_client
Client is not allowed for the grant type in use
Verify client_id
and grant settings.
400
invalid_scope
Requested scopes are not permitted
Adjust requested scopes.
Request examples
Payments — password grant using terminal credentials
POST https://identity.beadpay.io/realms/<realm>/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded
grant_type=password&
client_id=<payments_client_id>&
username=<terminalId>@beadpay.io&
password=<terminal_password>&
scope=openid profile email
Boarding — password grant using integrator credential
POST https://identity.beadpay.io/realms/<realm>/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded
grant_type=password&
client_id=<boarding_client_id>&
username=<integrator_username>&
password=<integrator_password>&
scope=openid profile email
Refresh (both models)
POST https://identity.beadpay.io/realms/<realm>/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&
client_id=<same_client_id_as_above>&
refresh_token=<refresh_token>
Authorization header on API calls
Authorization: Bearer <access_token>
Minimal refresh decision logic
Proactive check before calling an API
If
now >= issued_at + expires_in − buffer
then refresh.Otherwise use the cached access token. Suggested buffer: 120 to 300 seconds. Add small random jitter in high volume systems.
Reactive fallback on failure
If a request returns 401 and you have not just refreshed, perform one refresh and retry once.
If it still fails, perform a full sign in and alert.
Model specific checklists to share with integrators
Payments token management
Maintain a shared cache keyed by terminalId, or by client + merchant + terminal if your app needs that.
Refresh with buffer and jitter. One leader refreshes and others reuse.
Never fetch a token per transaction.
On 401, refresh and retry once only.
If refresh fails, bootstrap a new pair off the hot path and alert.
Boarding and entity management token management
Use one backend token for administrative calls.
Same refresh and 401 retry rules, with a generous buffer.
Emphasize scopes, least privilege, and audit trails.
Last updated