Verified the digest join against flex-auth's T03 replay fixtures and found request_digest was hashing fields docs/canonical-request-digest.md excludes. The material is tenant, subject, action, resource, context only: id is correlation, policy_version lives in provenance, caring_context is hashed separately. This engine included all three when present. Because the join adopts the served request id, every real production request would have carried one, so the computed digest would have matched no issued decision and failed closed against every correct allow. Same unsatisfiable shape as the removed AUTHORITY constant. The old pinned constant was computed with the id inside the material, so it was wrong and its passing proved nothing. Replaced with fixture-driven tests over two real envelopes (vendored with provenance) plus a structural test that correlation fields do not move the digest. Both fixtures are needed: input_claim_digests.context appears only with a non-empty context. Also stops computing the native claim digest. The claim's binding.action and binding.target speak approval-engine's vocabulary while ours speaks the catalog's, and no mapping is published; flex-auth makes no cross-check and states the correspondence is ours via pdp_digest. A claim recording no pdp_digest now fails closed naming the missing mapping rather than comparing two different languages. That mapping is a prerequisite for destroy. 274 tests pass. Production still fails closed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M65ovP3eiiPHubibvWs9mD Assistant: claude-code Assistant-Model: opus Assistant-Process: 393550@bnt-lap001 Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
110 lines
3.5 KiB
JSON
110 lines
3.5 KiB
JSON
{
|
|
"id": "decision:49309356905a2ad3",
|
|
"contract_version": "flex-auth.decision-record.v1",
|
|
"request_id": "check:secrets-engine-rotate",
|
|
"effect": "allow",
|
|
"reason": "catalog_lane_policy_matched",
|
|
"matched_policy_version": "v1",
|
|
"matched_rule": "catalog_lane_policy_matched",
|
|
"resource": {
|
|
"id": "lane:glas-primary",
|
|
"type": "secret-catalog-lane",
|
|
"system": "secrets-engine",
|
|
"tenant": "tenant:platform",
|
|
"attributes": {
|
|
"auth_targets": [],
|
|
"fields": [
|
|
"password"
|
|
],
|
|
"policy_targets": [],
|
|
"stage": "prod"
|
|
}
|
|
},
|
|
"subject": {
|
|
"id": "secrets-engine",
|
|
"type": "service",
|
|
"tenant": "tenant:platform",
|
|
"attributes": {
|
|
"description": "secrets-engine's own service identity, the single calling identity for the twelve gated catalog-lane actions it sends to POST /v1/check. Because it is the only subject, the package has no action_not_granted branch (FLEX-WP-0021-T02); registering a second identity is the revisit trigger.",
|
|
"display_name": "secrets-engine service principal",
|
|
"groups": [
|
|
"group:secrets-engine-lane-operators"
|
|
],
|
|
"organization_relation": "ServiceProvider",
|
|
"roles": [
|
|
"Operator"
|
|
]
|
|
}
|
|
},
|
|
"binding": {
|
|
"tenant": "tenant:platform",
|
|
"subject": {
|
|
"id": "secrets-engine",
|
|
"type": "service",
|
|
"tenant": "tenant:platform",
|
|
"attributes": {
|
|
"description": "secrets-engine's own service identity, the single calling identity for the twelve gated catalog-lane actions it sends to POST /v1/check. Because it is the only subject, the package has no action_not_granted branch (FLEX-WP-0021-T02); registering a second identity is the revisit trigger.",
|
|
"display_name": "secrets-engine service principal",
|
|
"groups": [
|
|
"group:secrets-engine-lane-operators"
|
|
],
|
|
"organization_relation": "ServiceProvider",
|
|
"roles": [
|
|
"Operator"
|
|
]
|
|
}
|
|
},
|
|
"action": "rotate",
|
|
"resource": {
|
|
"id": "lane:glas-primary",
|
|
"type": "secret-catalog-lane",
|
|
"system": "secrets-engine",
|
|
"tenant": "tenant:platform",
|
|
"attributes": {
|
|
"auth_targets": [],
|
|
"fields": [
|
|
"password"
|
|
],
|
|
"policy_targets": [],
|
|
"stage": "prod"
|
|
}
|
|
},
|
|
"request_digest": "sha256:de67324f54187055307a833235f83ced9fcd3a20952a27b3d19493ed39734345"
|
|
},
|
|
"lifetime": {
|
|
"kind": "ttl",
|
|
"ttl": "15m",
|
|
"not_before": "2026-09-06T06:13:21Z",
|
|
"expires_at": "2026-09-06T06:28:21Z"
|
|
},
|
|
"diagnostics": {
|
|
"action": "rotate",
|
|
"matched_relationship": "",
|
|
"policy_package": "secrets-engine.catalog-lane.lifecycle",
|
|
"policy_status": "ready",
|
|
"registry_resource": false,
|
|
"registry_subject": true
|
|
},
|
|
"provenance": {
|
|
"evaluator": "flex-auth/local",
|
|
"mode": "standalone",
|
|
"policy_package": "secrets-engine.catalog-lane.lifecycle",
|
|
"policy_version": "v1",
|
|
"policy_package_digest": "sha256:fe0070b79f66442ae6c218697a49c470c6c8f670aa57a30c078a5284d097bd8c",
|
|
"registry_snapshot_digest": "sha256:f5a309bc0b36721fd6d9ad7f53eb21222162bc2eac62a0ab0802a9a1d51340bb",
|
|
"decision_time": "2026-09-06T06:13:21Z"
|
|
},
|
|
"caring": {
|
|
"profile": "caring-0.4.0-rc2",
|
|
"conformance_findings": [
|
|
{
|
|
"code": "CARING-DESCRIPTOR-MISSING",
|
|
"severity": "warning",
|
|
"message": "no CARING descriptor matched the request",
|
|
"fields": [
|
|
"caring_context"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|