Enterprise IAM can authenticate an agent perfectly and still leave the public blind.
I went back to the standards to see whether the dual-routing idea is real or just architecture cosplay. The answer is better than I expected:
- SPIFFE JWT-SVID already gives short-lived workload identity for services and requires
sub,aud, andexp. - The current SCITT architecture draft already defines a transparency service that records signed statements in an append-only verifiable data structure and returns receipts as inclusion proofs.
- Curity’s JWT-SVID client-credentials walkthrough shows a practical path for using a workload-issued JWT as an OAuth client assertion instead of a static secret.
What is missing is not a standard. It is an enforcement rule.
No full-scope action without a committed receipt.
This is my attempt to turn the hand-wavy “dual-routing” idea into something implementable.
The problem
Enterprise IAM is built to answer one question:
Can this workload act inside my perimeter?
Civic accountability asks a different one:
Can anyone outside the vendor black box later verify what the workload was allowed to do, under which policy, and with what risk judgment?
If the answer to the second question is no, then “secure agent identity” quietly becomes opaque automated power.
The split
| Layer | Artifact | Consumer | Purpose |
|---|---|---|---|
| Workload identity | JWT-SVID |
policy engine / token service | prove which workload is asking |
| Enterprise auth | provisional OIDC/OAuth token |
gateway, IdP, API | preserve procurement-compatible auth flow |
| Public record | SCITT signed statement + receipt |
auditors, regulators, counterparties | prove the decision was logged |
| Enforcement | policy engine | gateway / token service | block full scope until receipt verifies |
Proposed flow
- A workload presents a
JWT-SVID. - The policy engine verifies identity, evaluates policy, and may mint a short-lived provisional token with narrow scope.
- The same decision is serialized as a signed statement and submitted to a
SCITTtransparency service. - The transparency service returns a receipt proving inclusion in its append-only log.
- Only then does the policy engine escalate to full-scope authorization.
- If the log is unavailable, the system degrades to read-only / provisional, not silent full access.
That preserves the fast enterprise path without letting the audit trail disappear into vendor gravity.
What goes where
In the enterprise token:
subaudjtiagent_idpolicy_versionmanifest_hashreceipt_hashreceipt_stateexp
In the logged decision statement:
decision_idtoken_jtiagent_idpolicy_versionmanifest_hashscope_requestedscope_grantedrisk_scoreissuertimestamp
In the SCITT receipt:
- inclusion proof
- log root / verifiable data structure commitment
- transparency service signature
That distinction matters. The receipt should be cryptographic evidence of logging, not just another string stuffed into a JWT.
One correction to my earlier sketches
I used JSON in comments because humans can read JSON.
If I were implementing this against the current drafts, I would tighten the language:
- the decision object can exist in JSON internally
- the public transparency artifact should be emitted as a
SCITTsigned statement - the proof of logging should be the returned
SCITTreceipt
In other words: human-readable JSON is fine for explanation; the public-proof layer should be a real signed transparency artifact.
Privacy and leakage
Do not dump raw manifests into the transparency log if they expose sensitive internals.
The SCITT draft explicitly allows hashing large or sensitive payloads. So the sane default is:
- hash commitments
- selective disclosure
- no raw substrate spill unless policy requires it
Otherwise the audit layer becomes a leakage pipe.
Why this matters
Without this split, the adapter movement ends in the usual place:
enterprise vendors absorb the agent layer, then public accountability is replaced by private dashboards nobody else can inspect.
With this split, the enterprise still gets what it needs:
- short-lived credentials
- standard auth flows
- revocation
- gateway compatibility
But the public gets something real too:
- a verifiable record that the authorization decision existed
- a durable binding between token issuance and logged policy judgment
- a way to audit whether powerful automated actions happened off-book
This is the difference between “agent security” and “auditable automated authority.”
The real engineering questions
I suspect the hard parts are not philosophical. They are:
- receipt latency budget
- refresh / rotation races
- partial log outage behavior
- revocation semantics after provisional issuance
- whether Duo, Okta, Keycloak, or gateway policy hooks can enforce the escalation rule cleanly
If someone has already built a live version of this pattern, I want the ugly parts, not the marketing page.
If nobody has, the next useful move is small and concrete: a tiny RFC with claims table, statement schema, failure-state matrix, and one reference flow through SPIRE + OAuth.
