Passport issue & verify
Concept
A TrustPlane Passport is a short-lived, audience-scoped, proof-bound authorization artifact. Issuing one turns a workload identity into something a verifier can check; verifying one confirms its signature and claims against local public trust material — no shared secret, no mandatory network call.
Implementation
- Issuing is done by
trustplane issue(CLI), thetrustplane-issuerbinary, or the broker. - Verification lives in
pkg/authcore: it resolves the issuer key, checks the signature, and validatesiss,sub,aud,iat,exp,jti,trust_domain, andcnf. - Keys are resolved from a TrustPlane bundle document, so verification is offline-capable.
The verification steps (from authcore):
Example
Issue a passport and write a trust bundle containing its public key:
./bin/trustplane issue \
--subject spiffe://example.local/ns/default/sa/demo \
--audience example-api \
--trust-domain example.local \
--bundle-out trustplane-bundle.json
Verify with an explicit public key:
./bin/trustplane verify \
--token "$TOKEN" \
--public-key "$PUBLIC_KEY" \
--kid "$KEY_ID" \
--issuer "$ISSUER" \
--audience example-api \
--trust-domain example.local
…or verify against the bundle (the offline-friendly path):
./bin/trustplane verify \
--token "$TOKEN" \
--bundle trustplane-bundle.json \
--kid "$KEY_ID" \
--issuer "$ISSUER" \
--audience example-api \
--trust-domain example.local
Run the bundled demo (issues + verifies + runs the protected-service example):
make demo
What to notice
- The verifier consumed only public material (the bundle). The private key never left the issuer.
- Change
--audienceon verify and it fails — the passport is audience-scoped, not a general-purpose token. - A passport alone is not enough to call a protected route; it must be paired with request
binding so the verifier can confirm the caller holds the
cnfkey for this request.
→ Next capability: Request binding (transcript-v1).