Skip to content
Registry StackDocsv0.46.0

Request an access token from your own code

For the consumer or verifier

View as Markdown

If your code must present a bearer access token to Registry Evidence, Base Registry Engine (BReg), or another Registry Stack service, you get it from the deployment’s OAuth issuer with the client-credentials grant, authenticating with a signed client assertion instead of a secret.

Get these values from the issuer administrator and the service’s operator:

  • The HTTPS token endpoint
  • Your registered client identifier
  • Your client’s private JWK, with a kid and an alg the issuer accepts
  • The client-assertion audience, if not the token endpoint URL
  • The RFC 8707 resource identifier of the service you call
  • The scopes that service’s deployment requires

Keep the private key in a secret store, and never fall back to a client secret. Scopes are the deployment’s choice: one target may require a scope such as evidence:request, another may require none. Request exactly the scopes your deployment names.

A client built with EvidenceClient.from_profile, as in Request Evidence from your application, needs no token code: the client profile drives the exchange. The explicit constructor takes it as token=:

client = EvidenceClient(
base_url, trusted_jwks, revoked_key_ids,
token={"private_key_jwt": private_key_jwt},
)

private_key_jwt holds token_endpoint, client_id, client_key, and optionally audience, resource, and scopes; the client API reference has the rest. The client builds and signs each client assertion for you.

Any other caller, BReg callers included, signs a client assertion and posts this form to the token endpoint:

grant_type=client_credentials
client_id=<client-id>
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertion=<signed-client-assertion>
resource=<resource-identifier>
scope=<scopes>

Omit scope when the deployment requires none. Keep resource and scope fixed for the client’s lifetime, so a cached token never serves another service. resource is a registered identifier, not a URL to fetch.

The client assertion is a compact JWT signed with your private key. Its protected header carries:

  • alg: the algorithm your key signs with, one of EdDSA, ES256, RS256, ES384, or RS384
  • kid: your key’s identifier, which the issuer uses to select your registered public key
  • typ: JWT

Its claims carry:

  • iss and sub: your client identifier
  • aud: the token endpoint URL, or the audience the issuer names instead
  • iat: the current Unix time
  • exp: iat plus a short lifetime, at most 300 seconds and no longer than your issuer accepts (the maintained clients default to 60)
  • jti: a fresh identifier for every assertion, because a replay-checking issuer refuses a repeated one

An issuer checks iat and exp against its own clock, so keep yours synchronized.

SymptomCheck
The issuer returns invalid_clientClient identifier, header kid and alg, assertion audience, clock, jti
The service rejects the tokenToken issuer, resource, the scopes the deployment requires