Skip to main content
A mandate is a short-lived JWT issued by the Inviolet Mandate Issuer that binds a specific actor to a specific intent card with a specific scope. Every tool call presents one; the gateway verifies it before deciding.

Claims

  • iss — always inviolet
  • jti — the cred id (used for audit + revocation)
  • aud — the audience the mandate was minted for (e.g. postgres-prod)
  • exp — expires at; default 300s, max 3600s
  • inviolet_organization_id — your org
  • inviolet_intent_id — the intent card id
  • inviolet_scope — the requested scope (subset of the intent card’s allowed scope)
  • inviolet_prompt_id — optional; correlates dispense to a captured prompt

Lifecycle

  1. Mint — POST /v1/mandate/dispense. The gateway validates the requested scope against the intent card, signs an RS256 JWT, persists a mandate_dispenses row.
  2. Refresh — POST /v1/mandate/refresh. Extends TTL up to max_ttl_seconds.
  3. Use — attach to every tool call as X-Inviolet-Mandate. The gateway verifies the signature against the published JWKS, runs the decision engine, returns a verdict.
  4. Revoke — POST /v1/mandate/revoke. Adds the cred id to the blocklist + propagates to any downstream credential broker.

Verifying mandates yourself

The Mandate Issuer publishes its public keys at /v1/mandate/jwks. Use any RS256-aware JWT library to verify the signature locally. The TypeScript canonical helper is in @inviolet/mandate:

Mandate-aware credential brokers

When you’ve connected Vault or Conjur, you can tell the dispense endpoint to also forward the mandate to the broker by passing broker_dispense. The response then includes the downstream Vault/Conjur token. See Credential broker.