Skip to main content
Version: Next

Data access credentials

A provider HTTP data plane hands the consumer a short-lived access JWT plus a refresh grant instead of a permanent token. Flows shows how an application obtains and uses them; configuration lists the lifetimes and key settings. This page covers what an operator has to get right.

Signing key

The plane signs access tokens and will not start without a key. Supply a private JWK through dataAccess.signingKeyPath or dataAccess.signingKey, with a stable kid and one of ES256, ES384, RS256 or EdDSA. Keep the key and the database across restarts: generating a new key per pod start invalidates every outstanding credential. GET /.well-known/jwks.json publishes only the public keys.

To rotate, supply a new private key with a new kid and keep the old public JWK in dataAccess.previousPublicKeys for at least the maximum refresh-grant lifetime, because a refresh proof may reference an access token signed with the old key. Remove it afterwards.

Replicas

Replicas coordinate only through the database: rotation is a compare-and-swap on the flow row. Scaling beyond one replica therefore requires a shared database such as PostgreSQL and the same signing key Secret on every pod. SQLite gives each pod its own file and will not work.

Operational notes

Public proxy and refresh endpoints require HTTPS; plain HTTP is for local development only and logs a warning at startup.

A refresh grant is single-use. The provider rotates it and the consumer persists the result in separate transactions, so a consumer crash in between leaves a refresh token the provider has already retired; that transfer has to be started again.

The consumer only renews against the origin that serves the data, and rejects redirects at the refresh endpoint, so a provider cannot direct proof credentials at another host.

Suspension, completion and termination revoke renewal. Resume issues a new generation, and credentials from before the resume stay invalid.