flex-auth/examples/secrets-engine/replay
tegwick 9e10d1cec1
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 37s
Emit T03 replay fixtures from the published package
Two real DecisionEnvelopes in examples/secrets-engine/replay/ for
secrets-engine to verify its digest join unchanged: a plain allow
(rotate, empty context) and the dual-control allow (destroy with a valid
approval-claim).

Both are included deliberately. input_claim_digests.context appears only
when the request carries a non-empty context, so a consumer asserting the
field is always present would pass on destroy and fail on rotate. One
fixture would have hidden that.

request_digest, policy_package_digest, registry_snapshot_digest and the
context claim digest are verified identical across two runs and are the
fields to pin. id, decision_time and the lifetime bounds move with the
clock; the README says so rather than leaving a consumer to discover it
by flake. lifetime.ttl is 15m from the package allow_ttl.

Emitted from flex-auth/local in standalone mode, not from a cluster pin.
T03 is progress, not done -- it closes when secrets-engine confirms their
validator accepts the records unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JTbVXpEiXA7mNJVpDnEPcB

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 412054@bnt-lap001
Assistant-Session: 3968fae1-8d59-4209-9bd6-c22594b8ab19
2026-09-06 08:14:14 +02:00
..
decision_destroy_dual_control.json Emit T03 replay fixtures from the published package 2026-09-06 08:14:14 +02:00
decision_rotate.json Emit T03 replay fixtures from the published package 2026-09-06 08:14:14 +02:00
README.md Emit T03 replay fixtures from the published package 2026-09-06 08:14:14 +02:00

T03 replay fixtures

Real DecisionEnvelopes emitted from the published package, for secrets-engine to verify its digest join (627810b) unchanged. FLEX-WP-0021-T03.

File From
decision_rotate.json ../check_request_allow_rotate.json — plain allow, empty context
decision_destroy_dual_control.json ../check_request_allow_destroy_dual_control.json — dual control, valid approval-claim

Regenerate either with:

go run ./cmd/flex-auth check \
  -policy   examples/secrets-engine/policy_package.md \
  -registry examples/secrets-engine/registry_snapshot.json \
  -request  examples/secrets-engine/check_request_allow_rotate.json

What is stable and what is not

Stable across runs — these are the fields to pin a contract test against:

Field rotate destroy
binding.request_digest sha256:de67324f…4345 sha256:570d1128…7f56
provenance.policy_package_digest sha256:fe0070b7…bd8c same
provenance.registry_snapshot_digest sha256:f5a309bc…40bb same
provenance.input_claim_digests.context absent (empty context) sha256:45fa9f41…fdc8

Verified identical across two runs.

Not stable: id, provenance.decision_time, and lifetime.not_before / lifetime.expires_at move with the clock. lifetime.ttl is 15m from the package's allow_ttl. Do not pin the record as a whole.

input_claim_digests.context appears only when the request carries a non-empty context — which is why both fixtures are here rather than just one. A consumer asserting the field is always present would pass on destroy and fail on rotate.

Not a deployment

These come from flex-auth/local in standalone mode (provenance.evaluator / mode), not from a cluster pin. No flex-auth-secrets-engine pin exists yet (FLEX-WP-0021-T04), and the consumer policy pin stays unset until T05.