Skip to content
Registry StackDocsv0.34.0

Request an access token from your own code

View as Markdown

Use a private key JWT client assertion when an application needs its own short-lived access token for Evidence Gateway, Base Registry Engine (BReg), or Registry Relay. The deployment’s OAuth issuer owns client registration and token issuance. The resource server independently verifies the resulting token against its configured issuer, audience, algorithm, token type, and authority claims.

Obtain these values from the issuer administrator:

  • The exact HTTPS token endpoint.
  • The registered client identifier.
  • The client’s private JWK and registered key identifier.
  • The client-assertion audience. This often equals the issuer identifier or token endpoint, but the issuer contract decides the exact value.
  • The RFC 8707 resource identifier for the intended resource server.
  • The non-empty scopes approved for this client and resource.

Keep the private key in the calling process’s secret store. The issuer registration holds only the public key. Do not add a client secret as a fallback when assertion authentication fails.

The Evidence Gateway Node binding performs the exchange, refreshes before token expiry, coalesces concurrent refreshes, and invalidates a cached token after an authentication refusal. Configure its credential source explicitly:

const token = {
privateKeyJwt: {
tokenEndpoint: "https://issuer.example.org/oauth2/token",
clientId: "permit-desk",
clientKey: privateJwk,
audience: "https://issuer.example.org",
resource: "urn:registry:evidence",
scopes: ["evidence:evaluate"],
},
};

The Python binding uses the same contract with snake-case field names:

token = {
"private_key_jwt": {
"token_endpoint": "https://issuer.example.org/oauth2/token",
"client_id": "permit-desk",
"client_key": private_jwk,
"audience": "https://issuer.example.org",
"resource": "urn:registry:evidence",
"scopes": ["evidence:evaluate"],
}
}

Pass this token value in the client configuration shown by request Evidence from an application. The Relay and BReg client bindings expose the same private key JWT credential provider for their own resource URLs and registered scopes.

If another client library performs the exchange, it must create a fresh signed JWT assertion for each request. Its iss and sub are the registered client identifier, aud is the configured assertion audience, jti is fresh, and iat and exp fit the issuer’s accepted lifetime. The protected header names the registered key with kid and uses the registered signing algorithm.

Send the assertion in an OAuth form:

grant_type=client_credentials
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertion=<signed-client-assertion>
resource=urn:registry:evidence
scope=evidence:evaluate

Treat the endpoint as HTTPS, disable redirects, apply a bounded timeout and response-size limit, and never log the assertion, private key, access token, or token response. Keep resource and scope immutable for one configured provider so a caller cannot redirect cached authority to a different service.

SymptomCheck
The issuer returns invalid_clientConfirm the client identifier, registered public key, kid, signing algorithm, assertion audience, clock, and fresh jti.
The issuer rejects the request shapeConfirm the exact token endpoint, client_credentials grant, assertion type URN, resource, and non-empty scopes.
The resource server rejects the tokenConfirm the token issuer, audience or resource, token type, algorithm, scopes, and configured authority claim names.
A migrated configuration names mintReplace the retired key with the owning component’s token_client or private key JWT configuration and provide the explicit endpoint, audience, client, key, resource, and scopes. The retired key is rejected rather than aliased.