Capability → example map
This is the single table the docs promise: every capability, the code that implements it, the command/target that demonstrates it, and the stable outcomes you should observe. Use it as a checklist when validating a build.
Master map
| Capability | Implemented in | Run / try it | Observable outcomes (reason codes) |
|---|---|---|---|
| Passport issue/verify | pkg/authcore, cmd/trustplane-cli, cmd/trustplane-issuer | trustplane issue / trustplane verify; make demo | Valid passport verifies; wrong --audience/--trust-domain/--issuer → deny |
| Request binding (transcript-v1) | pkg/proof | make demo-provider-gateway; trustplane sign --curl; make transcript-conformance | Valid binding allows; tamper → request_binding_mismatch; bad proof → invalid_request_proof; Go/JS/Py identical transcript |
| Replay protection | pkg/authcore (memory.go, redis.go) | make demo-provider-gateway (duplicate); make test (concurrency) | 2nd presentation → jti_replay; 1-of-N concurrent succeeds; Redis fail-closed |
| Bundle policy & freshness | pkg/bundle, pkg/middleware/http | trustplane bundle build; make demo-provider-gateway | Missing policy → bundle_policy_missing; unknown route → bundle_route_missing; stale → stale_bundle_fail_closed; bad class → bundle_freshness_unknown |
Trust anchors & allowed_sources | pkg/bundle (multi-anchor), pkg/middleware/http | multi-anchor fixture acme-demo.config.json | source_issuer_mismatch / source_trust_domain_mismatch / source_subject_mismatch / insufficient_key_binding; provenance/context: missing_provenance, provenance_mismatch, missing_context, context_mismatch |
| Non-destructive merge | pkg/bundle/merge.go, cmd/trustplane-cli | trustplane bundle merge-source | Append preserves existing; duplicate rejected unless --replace-existing; new client allowed after publish |
| Brownfield adapter | cmd/trustplane-adapter, pkg/middleware/http | make demo-adapter | Valid allows; missing → 401; wrong audience → 403; adds X-TrustPlane-* headers |
Broker & attested_workload | cmd/trustplane-broker, internal/broker (+ spiffe_workload_api.go) | trustplane broker issue; trustplane up; SPIRE M2M smoke | Software issue works; abuse/wrong-peer/stale-nonce/replay deny; SPIFFE SVID gates attested_workload |
| Signer taxonomy | pkg/authcore/signer.go | route required_key_binding checks | software<remote_kms<hardware_local<attested_workload; below min → insufficient_key_binding |
| Audit events | pkg/audit | emitted by broker/verifier/adapter | Stable trustplane-auth-audit-event-v0.1 JSON with reason_code, route_id, transcript_sha256 |
| Local orchestration | cmd/trustplane-cli (up.go) | trustplane up; make v01-acceptance | Full local broker+adapter+bundle pipeline; acceptance gate green |
Demonstration targets at a glance
make target | Demonstrates |
|---|---|
make demo | Passport issue/verify + protected-service example |
make demo-bundle | Issuer key resolution from a local trust bundle |
make demo-adapter | Brownfield adapter: allow / 401 / 403 |
make demo-provider-gateway | Broker + transcript-v1 + replay + bundle policy + deny reasons |
make transcript-conformance | Cross-language transcript equality |
make v01-acceptance | The whole local readiness gate (see below) |
Deploy-side demonstrations (trustplane-auth-deploy)
| Script / workflow | Demonstrates |
|---|---|
scripts/render-chart.sh | Helm chart renders with no cluster; no broker Service |
scripts/acme-demo-software-smoke.sh | Software/JWKS caller → GET /orders allow + deny matrix |
scripts/acme-demo-key-lifecycle-smoke.sh | Add a client (merge + refresh) on a live adapter, no image rebuild |
scripts/acme-demo-multi-route-mockapi-smoke.sh | One adapter protecting /orders, /invoices, /customers |
scripts/example-spire-m2m-smoke.sh | Same-cluster broker sidecar + SPIRE attested_workload |
deploy-auth-adapter-example.yml | Manual example deployment via reviewed chart apply |
refresh-auth-bundles-example.yml | Bundle-only refresh + adapter refresh signal |
Full reason-code reference
| Reason code | Layer | Trigger |
|---|---|---|
bundle_policy_missing | bundle/adapter | No policy bundle loaded |
bundle_route_missing | bundle/adapter | No route matches method/path |
bundle_freshness_unknown | bundle | Unknown/invalid freshness class |
stale_bundle_fail_closed | bundle/adapter | Bundle too stale for the route |
source_issuer_mismatch | source policy | Issuer not allowed |
source_trust_domain_mismatch | source policy | Trust domain not allowed |
source_subject_mismatch | source policy | Subject not allowed |
insufficient_key_binding | signer taxonomy | Key class below route minimum |
missing_provenance / provenance_mismatch | provenance policy | Required provenance absent/wrong |
missing_context / context_mismatch | context policy | Required context absent/wrong |
invalid_request_proof | proof | Proof signature malformed / fails verify |
request_binding_mismatch | proof | Request doesn't match signed transcript |
jti_replay | replay | Passport jti already consumed |
401 / 403 | adapter HTTP | Missing passport / wrong audience |
reserved_rls_deny | audit (reserved) | Reserved future shape only — not implemented |
All policy-level denials (route, source, freshness, provenance/context) occur before replay
consume, so they never burn a victim's jti.