Skip to content

Concepts

Every term on this page is something you will meet in the CLI, the contracts, and the logs. Learn the vocabulary here once, and the commands and reason codes you see later will make immediate sense.

A caller with a workload identity gets a short-lived passport, attaches proof that binds it to this exact request, and a verifier checks the passport and proof against local trust material and route policy before the protected API ever sees the request.

flowchart LR
  ID["Workload identity<br/>(SPIFFE / OIDC / local)"] --> ISS["Issuer / Broker"]
  ISS -->|"short-lived passport"| C["Caller"]
  C -->|"request + passport + proof"| V["Verifier (adapter / middleware)"]
  V --> TM["Trust material<br/>(bundle of public keys)"]
  V --> POL["Route policy<br/>(allowed_sources, freshness)"]
  V -->|"allow"| API["Protected API"]
  V -->|"deny + stable reason"| C

Who the machine is. Comes from an identity provider:

  • SPIFFE/SPIRE — CNCF-native workload identity for Kubernetes (e.g. an X.509-SVID with a SPIFFE ID like spiffe://example.local/ns/default/sa/orders-caller).
  • OIDC/JWT issuer — an existing identity provider.
  • TrustPlane-native issuer — a local issuer for development, demos, and conformance tests.

TrustPlane is SPIFFE-compatible, not SPIFFE-required, and Kubernetes-compatible, not Kubernetes-required.

A short-lived, proof-bound authorization artifact derived from workload identity. It is not a long-lived bearer token. Its minimum claims are:

Claim Meaning
iss Issuer URI
sub Subject — URI-compatible, provider-neutral identity
aud Audience — the specific API/service this passport is for
iat Issued-at timestamp
exp Expiry timestamp (short!)
jti Unique passport ID (used for replay protection)
trust_domain The administrative trust boundary
cnf Confirmation claim — the key/identity that must be proven at request time

Evidence that this specific request was made by the passport holder. The transcript-v1 format binds the request’s method, authority, path, query, selected headers, nonce, body hash, audience, route_id, passport jti, issued-at bucket, and key binding into a signed string. Change any of those (e.g. tamper the path) and verification fails.

The thing that says allow or deny. It can be:

  • a brownfield adapter (trustplane-adapter) — a reverse proxy in front of an existing API,
  • library middleware (pkg/middleware/http) inside your Go service,
  • a gateway or sidecar.

The verifier checks the passport and the proof locally, using public keys from a trust bundle — no mandatory online call.

  • Trust material = the set of trusted issuer/broker public keys the verifier uses to check signatures. Distributed as a TrustPlane bundle document.
  • Route policy = a trustplane-bundle-v1 document that says, per route, which sources (issuer + trust domain + subject + key-binding) are allowed, plus freshness rules.

These bundle keys are trust anchors in the Auth route-source authorization sense: they are evaluated locally on every request. Control’s enrollment-time Trust Anchor Sources are a different plane — they validate workload evidence once, before a derived client key is issued. See Two trust planes.

How strong is the key that signed this? Ordered weakest → strongest:

software < remote_kms < hardware_local < attested_workload

A route can demand a minimum, e.g. required_key_binding: attested_workload. Off-host key-reuse prevention is only claimed for hardware_local and attested_workload; software only proves possession. See the Security model.

A small local service (over a Unix domain socket) that issues request-bound passports for callers. By default it signs with a local software Ed25519 key. On Kubernetes it can verify a caller’s SPIFFE/SPIRE X.509-SVID before issuing an attested_workload passport.

Every accepted jti is consumed atomically so the same passport+proof cannot be used twice. Backed by memory (single instance) or Redis (multi-replica). A repeat is denied with jti_replay.

A stable JSON record (trustplane-auth-audit-event-v0.1) describing each allow/deny decision — with a reason_code, route_id, transcript_sha256, and more.

Scope: a per-request decision from local trust material

Section titled “Scope: a per-request decision from local trust material”

TrustPlane Auth makes a per-request authorization decision from configured local trust material and route policy. Keep that scope in mind:

  • It runs locally and offline — no account, database, or hosted service required.
  • It remembers no caller state: each request is decided on its own; there are no persistent principal records.
  • Trust material and policy bundles are local files you mount — built by hand or with trustplane bundle build / merge-source.
  • It does not run approval workflows, host a revocation feed, or distribute bundles; those governance concerns are out of scope for this runtime.
Term One-liner
Passport Short-lived, audience-scoped, proof-bound authorization artifact
transcript-v1 The canonical request-binding format the proof signs over
cnf Confirmation claim — the key that must be proven at request time
jti Unique passport id; consumed once to stop replay
Trust bundle Document of trusted public keys for local verification
Policy bundle (trustplane-bundle-v1) Per-route allowed_sources + freshness rules
allowed_sources The list of (issuer, trust domain, subject, key-binding) a route accepts
Adapter Reverse-proxy verifier in front of an existing API (“the wedge”)
Broker Local issuer of request-bound passports over a Unix socket
Signer class software < remote_kms < hardware_local < attested_workload
Freshness class realtime / bounded / offline-ok — how stale a bundle may be