Subscription plans only. Token issuance applies only to plan purchases. For route-based pay-per-call flows,
fetchResourceCredentials is not called:- Embedded per-request — Key0 settles on-chain and calls
next(), passing control to your route handler. No JWT is issued;req.key0Paymentcontains payment metadata. - Standalone per-request — Key0 settles on-chain and proxies the request to your backend via
fetchResource/proxyTo. The backend’s response is returned directly as aResourceResponse.
Token issuance flow
1
Challenge transitions to PAID
The
ChallengeEngine verifies the on-chain payment and transitions the challenge from PENDING to PAID.2
fetchResourceCredentials is called
Your callback receives the payment context:
3
Callback returns credentials
Your callback returns
{ token: string } (or any credential shape you define).4
Challenge transitions to DELIVERED
The engine atomically transitions the challenge to
DELIVERED.5
AccessGrant is returned
The agent receives the signed JWT and uses it as a
Bearer token on subsequent requests.AccessTokenIssuer
TheAccessTokenIssuer class handles JWT creation and verification. It supports two signing algorithms: HS256 (shared secret) and RS256 (RSA key pair).
Constructor
The constructor accepts either a plain string (backward-compatible) or a config object:HS256 secrets must be at least 32 characters. The constructor throws immediately if the secret is shorter.
Config type
Methods
sign
Creates a signed JWT with the given claims and TTL.verify
Verifies a token using the primary secret. HS256 only — RS256 tokens should be verified withvalidateKey0Token using the public key.
verifyWithFallback
Tries the primary secret first, then falls back to a list of previous secrets. Use this during secret rotation.TokenClaims
Every Key0 JWT contains these custom claims alongside the standardiat and exp:
validateToken middleware
ThevalidateToken function is a framework-agnostic utility that extracts and verifies a Bearer token from an Authorization header. The framework integrations (Express, Hono, Fastify) wrap this function into middleware.
Error handling
validateToken throws a Key0Error with the following codes:
validateKey0Token (lightweight validator)
If your backend service only needs to verify tokens and does not need the full SDK, use the standalone validator from@key0ai/key0/validator. It supports both HS256 and RS256 and has no blockchain dependencies.
sub, jti, resourceId, planId, txHash) and throws if any are missing.
HS256 vs RS256
Token issuance timeout
TheChallengeEngine wraps your fetchResourceCredentials callback in a Promise.race with a configurable timeout.
tokenIssueRetries times with exponential backoff (500ms base delay — 500ms, 1s, 2s, and so on).
If token issuance fails permanently, the challenge stays in the PAID state. The refund cron can pick it up and settle an on-chain refund automatically.
