Record authenticated caller in the decision envelope.
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 1m0s

FLEX-WP-0023-T04: provenance.caller is additive (mode required;
principal/audience/not_after when a token was reviewed). TokenReview
keeps the JWT exp. request_digest is unchanged because the caller is
not binding material.

Assistant: grok
Assistant-Session: 01a09dc1-b21e-77e1-919e-fcad2f82b267
This commit is contained in:
tegwick 2026-09-14 04:44:07 +02:00
parent e62c0cfc36
commit ca070df32d
15 changed files with 344 additions and 35 deletions

View file

@ -39,9 +39,17 @@ same shape.
| `provenance.directory_etag` | Directory consistency token when a delegated directory was joined |
| `provenance.input_claim_digests` | SHA-256 per request-time claim class (`context`, `caring_context`) |
| `provenance.decision_time` | UTC timestamp used to compute `lifetime` |
| `provenance.caller` | How the request was authenticated to the PDP. Additive; **not** decision material. `mode` is required (`disabled` / `warn` / `enforce`). A `principal` recorded under `warn` was observed, not enforced. Under `disabled` the object is `{"mode":"disabled"}` with no principal. `not_after` is the reviewed token `exp`. **Does not affect `request_digest`.** See `FLEX-DEC-2026-009` |
`reason`, `diagnostics`, and CARING prose are not an authorization contract.
## Caller provenance is not a digest input
`provenance.caller` records who obtained the decision. The caller is
deliberately absent from `binding`, so two requests that differ only in the
authenticated principal produce the same `request_digest`. Consumers must not
re-pin replay joins because this field appeared (`FLEX-DEC-2026-009`).
## Allow lifetime
Every allow carries `lifetime.kind = ttl`. The duration comes from the policy