approval-engine/docs/caller-authentication.md
tegwick 2370f69927 Harden the PEP harness and KeyCape registration request
Close remaining in-repo APPROVAL-WP-0002 gaps: drive GH-DEC-2026-003 against
the real HTTP surface, fail closed on JWT/human-consume/static-token paths,
treat audit 200 duplicates as drained, and ask KeyCape for the production
audience and client grants.

Assistant: grok
Assistant-Session: 01a06253-e557-7971-93d9-4f4c2cfbf455
2026-09-02 15:46:06 +02:00

1.9 KiB

Caller authentication

Production accepts only RS256 JWTs verified against KeyCape JWKS with the exact configured issuer and approval-engine audience. exp, iat, sub, principal_type, tenant, roles, scope, and assurance are mandatory. Missing or unverifiable credentials fail closed. The development static-token mode is explicit, file-backed, and refused with --production. The verified tenant must exactly match the service's configured store tenant; cross-tenant reads and mutations are rejected before object lookup.

Route Required scope
create approval approval:create
get approval or claim approval:read
add approval entry approval:approve
revoke approval:revoke
supersede approval:supersede
consume approval:consume and service/agent principal
cadence, outbox, storage approval:observe
explicit heartbeat approval:emit

Create additionally requires binding.actor == sub. Approval-entry subject, assurance, and evidence reference are derived from the verified JWT, never the request body. KeyCape owns client registration and scope grants; approval-engine only verifies and enforces them. Requested registrations are:

  • audience/resource server approval-engine with the scopes above;
  • the secrets-engine PEP service client with approval:read and approval:consume;
  • separately governed lifecycle/operator clients with only their needed mutation or observation scopes.

Client credentials belong in OpenBao/operator custody and must not be placed in manifests, logs, State Hub, or this repository.

KeyCape's OpenBao service-auth contract currently emits aud as the OAuth clientId. That pattern must not be reused here. Tokens presented to this API MUST have resource-server audience approval-engine. Requested non-secret client fragments are in docs/keycape-service-registrations.md.