Accept ActionAuthorization deferral; fix the state-hub authority constant
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Build and Publish Container Image / build-and-push (push) Successful in 40s

approval-engine filed APPROVAL-IN-0002: secrets-engine built its PEP
validator against our ActionAuthorization schema, pointed it at
GET /v1/approvals/{id}/claim, and it rejects every response. Both
envelopes declare schema_version 0.1, so it fails late and reads like an
approval-engine outage rather than a contract mismatch.

FLEX-DEC-2026-006 accepts the deferral and argues against flex-auth's own
proposal. The composed object had the PIP republish our decision, which
crosses the same layer boundary we invoked to decline authentication
evidence and to win section 17's schema. The claim-plus-DecisionEnvelope
split drops no check; each verification lands on the layer that owns it.

approval-engine asked, before the decision, whether the open G3 finding
argues for ratifying now. It does not: G3 is already closed the other
way. FLEX-WP-0019 added lifetime to the DecisionEnvelope itself, required
on every allow by schema conditional, published 2026-09-02. The trigger
resolved by adding a field rather than by composition, so the decision
stands alone and needs no bundle.

The provenance.authority == state-hub constant is our defect and is
fixed at source. It came from examples/caring/action_authorization.json,
which contradicted the same contract's ownership section. That fixture
now names approval-engine as the approval fact's authority and flex-auth
as the decision's, and its stale secrets-engine.lifecycle pin is
corrected to the reserved coordinate from FLEX-DEC-2026-005.

The contract doc and schema are marked deferred-not-withdrawn so no
other consumer builds a validator against them. The execute-time half is
untouched: /v1/check, binding, the canonical digest, and
flex-auth.decision-record.v1 stay published.

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
This commit is contained in:
tegwick 2026-09-06 01:30:04 +02:00
parent d144feb2e9
commit 74bfb3b664
5 changed files with 295 additions and 22 deletions

View file

@ -2,9 +2,9 @@
"schema": "repo_manager.index.v1",
"slug": "flex-auth",
"repo_root": "/home/worsch/flex-auth",
"head_sha": "56940727bfb36aec705318b0128599f367256c23",
"observed_at": "2026-09-05T23:08:53.160637Z",
"source_fingerprint": "727c449ea8eb418a198b97d34244e377936060c84024b65b2af950ea71714259",
"head_sha": "d144feb2e9b74df39a085ce752335c1169ffac9a",
"observed_at": "2026-09-05T23:29:23.679186Z",
"source_fingerprint": "8708283bc20e40a97e9193fcf6de5b81cb3174f0cac5af6665ecc62d6c716c7e",
"source_files": [
".repo-classification.yaml",
"INTENT.md",
@ -29,7 +29,8 @@
"workplans/FLEX-WP-0017-action-bound-authorization-contract.md",
"workplans/FLEX-WP-0018-inbound-auth-corrections.md",
"workplans/FLEX-WP-0019-layer-model-conformance.md",
"workplans/FLEX-WP-0020-repository-identity-migration.md"
"workplans/FLEX-WP-0020-repository-identity-migration.md",
"workplans/FLEX-WP-0021-secrets-engine-consumer-policy-gate.md"
],
"work_records": [
{
@ -1216,6 +1217,66 @@
"parent_id": "FLEX-WP-0020",
"extra": {}
},
{
"kind": "workplan",
"id": "FLEX-WP-0021",
"status": "proposed",
"title": "secrets-engine consumer policy package and cluster-local pin",
"source_path": "workplans/FLEX-WP-0021-secrets-engine-consumer-policy-gate.md",
"uuid": "b01f655e-f71a-50ae-b110-178557f07c63",
"parent_id": null,
"extra": {}
},
{
"kind": "task",
"id": "FLEX-WP-0021-T01",
"status": "todo",
"title": "1. Obtain the real action vocabulary from secrets-engine",
"source_path": "workplans/FLEX-WP-0021-secrets-engine-consumer-policy-gate.md",
"uuid": "3c191808-6fe5-5a9b-9a68-a4ce4a672dbd",
"parent_id": "FLEX-WP-0021",
"extra": {}
},
{
"kind": "task",
"id": "FLEX-WP-0021-T02",
"status": "todo",
"title": "2. Publish `secrets-engine.catalog-lane.lifecycle` v1",
"source_path": "workplans/FLEX-WP-0021-secrets-engine-consumer-policy-gate.md",
"uuid": "38770813-dfcc-5711-bba3-0db50d3af135",
"parent_id": "FLEX-WP-0021",
"extra": {}
},
{
"kind": "task",
"id": "FLEX-WP-0021-T03",
"status": "todo",
"title": "3. Confirm the digest join against a real decision record",
"source_path": "workplans/FLEX-WP-0021-secrets-engine-consumer-policy-gate.md",
"uuid": "8f7e5cdd-777e-5f54-9b92-c72b79f65672",
"parent_id": "FLEX-WP-0021",
"extra": {}
},
{
"kind": "task",
"id": "FLEX-WP-0021-T04",
"status": "wait",
"title": "4. Stand up the `flex-auth-secrets-engine` pin",
"source_path": "workplans/FLEX-WP-0021-secrets-engine-consumer-policy-gate.md",
"uuid": "f4e8709a-65dd-5172-97ae-e7c3432afb22",
"parent_id": "FLEX-WP-0021",
"extra": {}
},
{
"kind": "task",
"id": "FLEX-WP-0021-T05",
"status": "wait",
"title": "5. Hand the pin coordinates back and close",
"source_path": "workplans/FLEX-WP-0021-secrets-engine-consumer-policy-gate.md",
"uuid": "f0828871-fd65-5d8c-adfd-28b13fedd2b0",
"parent_id": "FLEX-WP-0021",
"extra": {}
},
{
"kind": "decision",
"id": "FLEX-DEC-2026-001",
@ -1344,7 +1405,7 @@
"status": "resolved",
"title": "Decision lifetime does not reach past issuance: answer to ops-warden WARDEN-WP-0034-T05",
"source_path": "decisions/decisions.md",
"uuid": null,
"uuid": "f6bfb02a-bbf3-4488-acf9-0e1cb57ce19d",
"parent_id": null,
"extra": {
"record": {
@ -1366,7 +1427,9 @@
"decided_by": "flex-auth (access-engine / PDP)",
"rationale": "Answered, not declined. A decision lifetime shorter than the SSH certificate TTL is meaningful, but only as an authority-to-issue window, never as an authority-to-use window over an already-issued certificate. flex-auth lifetime.expires_at bounds how long that one allow may be relied on to authorise a sign; it cannot bound an artifact ops-warden issued under it, and flex-auth does not claim it does. The downstream contract that consumes the shorter lifetime is the pre-sign gate itself: no replay of an allow past expires_at, and a fresh Check per sign. The lever that actually shortens effective access is the requested TTL as a policy input, which is already deployed as the ttl_out_of_bounds deny; ops-warden section 9.7.2 window through cert TTL is correctly stated and correctly owned by the PEP.",
"created": "2026-09-05T23:08:38.877787Z",
"updated": "2026-09-05T23:08:38.877787Z"
"updated": "2026-09-06T00:00:00.000000Z",
"decided_at": "2026-09-06T00:00:00.000000Z",
"state_hub_decision_id": "f6bfb02a-bbf3-4488-acf9-0e1cb57ce19d"
}
}
},
@ -1376,7 +1439,7 @@
"status": "resolved",
"title": "secrets-engine policy package is expected but unpublished; /v1/check has no estate-wide endpoint by design",
"source_path": "decisions/decisions.md",
"uuid": null,
"uuid": "f318e4e2-6195-4db8-b8c0-c71eeecad766",
"parent_id": null,
"extra": {
"record": {
@ -1398,7 +1461,43 @@
"decided_by": "flex-auth (access-engine / PDP)",
"rationale": "Two answers. (1) Yes, a real package is expected, and flex-auth authors it in this repo as it did for every other consumer; the reserved coordinate is secrets-engine.catalog-lane.lifecycle at version v1, and it does not exist yet. Until it is published and pinned, secrets-engine keeping SECRETS_ENGINE_AUTHORIZATION_POLICY_PACKAGE and _VERSION as required configuration with no fallback is the correct shape and flex-auth endorses it. (2) POST /v1/check is deployed, but there is no estate-wide PDP address and there is not meant to be one: each consumer gets its own cluster-local pin whose NetworkPolicy default-denies ingress except from that one approved workload. The 2026-09-06 probe finding no reachable PDP is the design working, not an outage. A reachable endpoint for secrets-engine is a per-consumer pin that follows its policy package.",
"created": "2026-09-05T23:08:51.144287Z",
"updated": "2026-09-05T23:08:51.144287Z"
"updated": "2026-09-06T00:00:00.000000Z",
"decided_at": "2026-09-06T00:00:00.000000Z",
"state_hub_decision_id": "f318e4e2-6195-4db8-b8c0-c71eeecad766"
}
}
},
{
"kind": "decision",
"id": "FLEX-DEC-2026-006",
"status": "resolved",
"title": "ActionAuthorization deferral accepted; G3 is closed and does not argue for ratifying it",
"source_path": "decisions/decisions.md",
"uuid": null,
"parent_id": null,
"extra": {
"record": {
"id": "FLEX-DEC-2026-006",
"kind": "decision",
"title": "ActionAuthorization deferral accepted; G3 is closed and does not argue for ratifying it",
"status": "resolved",
"origin": "cross-repo",
"origin_ref": "APPROVAL-IN-0002 / GH-DEC-2026-003",
"owner": "flex-auth",
"affects": [
"flex-auth",
"approval-engine",
"gate-house",
"secrets-engine"
],
"requested_dispositions": [
"accept",
"contest"
],
"decided_by": "flex-auth (access-engine / PDP)",
"rationale": "Accepted, and flex-auth argues against its own proposal. The composed ActionAuthorization object was never ratified; the approval-claim plus DecisionEnvelope split lands each check on the layer that owns it and drops none. approval-engine asked whether the open G3 finding (DecisionEnvelope carries no lifetime) argues for ratifying the composed object now. It does not, because G3 is already closed the other way: FLEX-WP-0019 added lifetime to the DecisionEnvelope itself, required on every allow by schema conditional, published 2026-09-02. The revisit trigger is spent, and it resolved by adding a field rather than by composition, so the decision now stands alone and needs no bundle. Separately, the provenance.authority == state-hub constant is flex-auth defect: it came from examples/caring/action_authorization.json, which contradicted our own ownership section. Corrected at source, with the schema and contract doc marked deferred-not-withdrawn so no other consumer builds a validator against them.",
"created": "2026-09-05T23:29:20.156770Z",
"updated": "2026-09-05T23:29:20.156770Z"
}
}
},
@ -1479,15 +1578,15 @@
"type": "repo.command.applied",
"command": "repo.work.create_decision",
"operation": "create",
"correlation_id": "ff360be5-e7bf-4914-95c3-1ea6df9f6957",
"correlation_id": "ead04d14-441f-4ecd-8ee8-12ae0cd23362",
"kind": "decision",
"id": "FLEX-DEC-2026-005",
"id": "FLEX-DEC-2026-006",
"git_sha": null,
"files_touched": [
"decisions/decisions.md"
],
"source": "repo-manager",
"emitted_at": "2026-09-05T23:08:53.160770Z"
"emitted_at": "2026-09-05T23:29:23.679390Z"
}
]
}