Skip to main content

Overview

Grantex tokens are standard JWTs (RS256) extended with agent-specific claims. Any service can verify them offline using the published JWKS — no dependency on Grantex at runtime.

Decoded Example

{
  "iss": "https://grantex.dev",
  "sub": "user_abc123",
  "agt": "did:grantex:ag_01HXYZ123abc",
  "dev": "org_yourcompany",
  "scp": ["calendar:read", "payments:initiate:max_500"],
  "iat": 1709000000,
  "exp": 1709086400,
  "jti": "tok_01HXYZ987xyz",
  "grnt": "grnt_01HXYZ456def"
}

Standard Claims

ClaimTypeDescription
issstringIssuer — the Grantex server that signed the token
substringThe end-user (principal) who authorized this agent
iatnumberIssued-at timestamp (seconds since epoch)
expnumberExpiry timestamp (seconds since epoch)
jtistringUnique token ID — used for real-time revocation

Grantex-Specific Claims

ClaimTypeDescription
agtstringThe agent’s DID — cryptographically verifiable identity
devstringThe developer org that built the agent
scpstring[]Exact scopes granted — services should check these
grntstringGrant record ID — links token to the persisted grant
audstring?Intended audience (optional) — services should reject tokens with a mismatched aud

Delegation Claims

Present on tokens issued to sub-agents via grants.delegate():
ClaimTypeDescription
parentAgtstringDID of the parent agent that spawned this sub-agent
parentGrntstringGrant ID of the parent grant — full delegation chain is traceable
delegationDepthnumberHow many hops from the root grant (root = 0)

Verification

Grant tokens can be verified two ways: Verify the RS256 signature locally using the published JWKS. No network call to Grantex is needed — just fetch the public keys once and cache them.
import { verifyGrantToken } from '@grantex/sdk';

const grant = await verifyGrantToken(token, {
  jwksUri: 'https://api.grantex.dev/.well-known/jwks.json',
  requiredScopes: ['calendar:read'],
});

Online

Call the Grantex API for real-time revocation status:
const result = await grantex.tokens.verify(token);
console.log(result.valid);   // true or false
console.log(result.scopes);

Security

  • Algorithm pinning: RS256 is hardcoded in all three verification layers (auth service, TypeScript SDK, Python SDK). The alg header in the token cannot override this.
  • Replay prevention: Every token’s jti is tracked. Presenting a previously-seen jti returns valid: false.
  • Minimum key size: The auth service enforces a minimum 2048-bit RSA modulus on all signing keys.