From 8007edecc4323c91edc78a32d705f8a18b762d5d Mon Sep 17 00:00:00 2001 From: tegwick Date: Tue, 15 Sep 2026 22:45:46 +0200 Subject: [PATCH] Compile compact sitting review package without widening T03. Seven exact-record pins from the 2026-09-15 sitting-create receipt. c01 is omitted. Identity bar matches T03. 147 local evaluator checks pass. Deploy waits on a CI image that contains the new package. Assistant: grok Assistant-Session: 01a0a6cb-0334-72c0-83b0-2df57474a0f6 --- .../2026-09-15-sitting-approval-creates.json | 229 +++++++ .../2026-09-15-sitting-review-policy.json | 593 ++++++++++++++++++ docs/request-enrichment.md | 1 + .../informed-decision-sitting/fixtures.json | 21 + examples/informed-decision-sitting/policy.md | 108 ++++ .../informed-decision-sitting/records.json | 121 ++++ .../informed-decision-sitting/registry.json | 17 + tools/exercise_sitting_review_policy.py | 93 +++ values/informed-decision-sitting.yaml | 28 + .../FLEX-WP-0028-compact-sitting-review.md | 50 ++ 10 files changed, 1261 insertions(+) create mode 100644 docs/evidence/2026-09-15-sitting-approval-creates.json create mode 100644 docs/evidence/2026-09-15-sitting-review-policy.json create mode 100644 examples/informed-decision-sitting/fixtures.json create mode 100644 examples/informed-decision-sitting/policy.md create mode 100644 examples/informed-decision-sitting/records.json create mode 100644 examples/informed-decision-sitting/registry.json create mode 100644 tools/exercise_sitting_review_policy.py create mode 100644 values/informed-decision-sitting.yaml create mode 100644 workplans/FLEX-WP-0028-compact-sitting-review.md diff --git a/docs/evidence/2026-09-15-sitting-approval-creates.json b/docs/evidence/2026-09-15-sitting-approval-creates.json new file mode 100644 index 0000000..038e127 --- /dev/null +++ b/docs/evidence/2026-09-15-sitting-approval-creates.json @@ -0,0 +1,229 @@ +{ + "observed_at": "2026-09-15T20:35:14.412859+00:00", + "status": "created", + "phase": "seven_unapproved_requests_created", + "requests": [ + { + "memo_id": "infd-20260914-c02", + "approval": { + "binding": { + "action": "accept", + "actor": "informed-decision", + "digest": "sha256:942cf7d5e6805987df2077a0cc6cde75b148e1729a96dd0692153287820b6a0a", + "human_control": true, + "pdp_digest": null, + "pdp_path": false, + "principal": "railiance-platform", + "purpose": "Accept provisioning of the secrets-engine service JWT login on the reviewed credential lane", + "target": { + "id": "rpf-wp-0035-t02", + "system": "railiance-platform", + "type": "credential-lane" + } + }, + "created_at": "2026-09-15T20:35:16+00:00", + "entries": [], + "id": "ccfd8007-2061-48fd-9356-99b16279dac1", + "required_count": 1, + "status": "requested", + "superseded_by": null, + "updated_at": "2026-09-15T20:35:16+00:00", + "validity": { + "expires_at": "2026-09-16T20:35:16.122938+00:00", + "not_before": "2026-09-15T20:35:16.122938+00:00" + } + } + }, + { + "memo_id": "infd-20260914-c03", + "approval": { + "binding": { + "action": "apply", + "actor": "informed-decision", + "digest": "sha256:95cae135b994acea6dad9da978dd3df1aa3354de900a1f43c2e5a03a20e8e844", + "human_control": true, + "pdp_digest": null, + "pdp_path": false, + "principal": "netkingdom", + "purpose": "Apply the live OpenBao role addition already specified for the operator-tunneled browser callback", + "target": { + "id": "nk-wp-0032-t03", + "system": "netkingdom", + "type": "openbao-role" + } + }, + "created_at": "2026-09-15T20:35:16+00:00", + "entries": [], + "id": "a0611d0d-b9ef-4b9a-aa79-e94a9e3fcd5f", + "required_count": 1, + "status": "requested", + "superseded_by": null, + "updated_at": "2026-09-15T20:35:16+00:00", + "validity": { + "expires_at": "2026-09-16T20:35:16.122938+00:00", + "not_before": "2026-09-15T20:35:16.122938+00:00" + } + } + }, + { + "memo_id": "infd-20260914-c04", + "approval": { + "binding": { + "action": "attend", + "actor": "informed-decision", + "digest": "sha256:dec960b30efaf654abbdcd8a2cdd20d4ff6bf52e170744f817dc55845d9cb192", + "human_control": true, + "pdp_digest": null, + "pdp_path": false, + "principal": "ops-warden", + "purpose": "Attend the graded lockdown / break-glass seal for ops-warden trust-root work", + "target": { + "id": "warden-wp-0027-t02", + "system": "ops-warden", + "type": "trust-root" + } + }, + "created_at": "2026-09-15T20:35:17+00:00", + "entries": [], + "id": "22ac6df3-e6a9-472b-a68e-c8caca4289a7", + "required_count": 1, + "status": "requested", + "superseded_by": null, + "updated_at": "2026-09-15T20:35:17+00:00", + "validity": { + "expires_at": "2026-09-16T20:35:16.122938+00:00", + "not_before": "2026-09-15T20:35:16.122938+00:00" + } + } + }, + { + "memo_id": "infd-20260914-d01", + "approval": { + "binding": { + "action": "retire", + "actor": "informed-decision", + "digest": "sha256:8cb7cc93f38db9d19b49e201e0554b50af1891fec853fef333a06ea078541d15", + "human_control": true, + "pdp_digest": null, + "pdp_path": false, + "principal": "the-custodian", + "purpose": "After HA failover and restore drills pass, retire WSL2 as a State Hub fallback", + "target": { + "id": "cust-wp-0038-t08", + "system": "the-custodian", + "type": "operating-model" + } + }, + "created_at": "2026-09-15T20:35:17+00:00", + "entries": [], + "id": "9f7c3506-68de-4826-86ff-e301f428408d", + "required_count": 1, + "status": "requested", + "superseded_by": null, + "updated_at": "2026-09-15T20:35:17+00:00", + "validity": { + "expires_at": "2026-09-16T20:35:16.122938+00:00", + "not_before": "2026-09-15T20:35:16.122938+00:00" + } + } + }, + { + "memo_id": "infd-20260914-d02", + "approval": { + "binding": { + "action": "confirm", + "actor": "informed-decision", + "digest": "sha256:be0c7de123216740d2c2eeaed80384e03e6b6d1668104f94bb8f9cbae7dfe30f", + "human_control": true, + "pdp_digest": null, + "pdp_path": false, + "principal": "helixforge-factory", + "purpose": "Confirm the existing operator-group claim for CCR-2026-0019 as required by the factory identity/audit/approval path", + "target": { + "id": "ccr-2026-0019", + "system": "helixforge-factory", + "type": "ccr" + } + }, + "created_at": "2026-09-15T20:35:17+00:00", + "entries": [], + "id": "b3ce2c01-0a3b-401e-b4ed-c1954af169c9", + "required_count": 1, + "status": "requested", + "superseded_by": null, + "updated_at": "2026-09-15T20:35:17+00:00", + "validity": { + "expires_at": "2026-09-16T20:35:16.122938+00:00", + "not_before": "2026-09-15T20:35:16.122938+00:00" + } + } + }, + { + "memo_id": "infd-20260914-d03", + "approval": { + "binding": { + "action": "accept", + "actor": "informed-decision", + "digest": "sha256:3c562278e86bb5e7f747452cf2e99d3a136853ab748676e8359262b835cd1425", + "human_control": true, + "pdp_digest": null, + "pdp_path": false, + "principal": "mason", + "purpose": "Accept the fluid-telegram operator credential lane plan so construction may proceed", + "target": { + "id": "mason-wp-0005", + "system": "mason", + "type": "workplan" + } + }, + "created_at": "2026-09-15T20:35:17+00:00", + "entries": [], + "id": "3b483e6b-0b92-45ff-83b6-bc5057c0a496", + "required_count": 1, + "status": "requested", + "superseded_by": null, + "updated_at": "2026-09-15T20:35:17+00:00", + "validity": { + "expires_at": "2026-09-16T20:35:16.122938+00:00", + "not_before": "2026-09-15T20:35:16.122938+00:00" + } + } + }, + { + "memo_id": "infd-20260914-d04", + "approval": { + "binding": { + "action": "confirm", + "actor": "informed-decision", + "digest": "sha256:3c2d7759679d871cb7c5cac8999542a365e64c918d59d0c4ce864ffb837453e4", + "human_control": true, + "pdp_digest": null, + "pdp_path": false, + "principal": "railiance-clock", + "purpose": "Confirm ecosystem ownership and the security role for Railiance Clock as specified", + "target": { + "id": "rclk-wp-0002-t01", + "system": "railiance-clock", + "type": "workplan" + } + }, + "created_at": "2026-09-15T20:35:17+00:00", + "entries": [], + "id": "356e67a3-5539-46a1-922a-f5591fd38ee5", + "required_count": 1, + "status": "requested", + "superseded_by": null, + "updated_at": "2026-09-15T20:35:17+00:00", + "validity": { + "expires_at": "2026-09-16T20:35:16.122938+00:00", + "not_before": "2026-09-15T20:35:16.122938+00:00" + } + } + } + ], + "credential_values_emitted": false, + "human_entries_created": false, + "skipped": [ + "infd-20260914-c01" + ] +} diff --git a/docs/evidence/2026-09-15-sitting-review-policy.json b/docs/evidence/2026-09-15-sitting-review-policy.json new file mode 100644 index 0000000..046c5d3 --- /dev/null +++ b/docs/evidence/2026-09-15-sitting-review-policy.json @@ -0,0 +1,593 @@ +{ + "scope": "local actual evaluator with synthetic identity; no live human approvals; T03 package untouched", + "checks": [ + { + "check": "c02:read", + "effect": "allow" + }, + { + "check": "c02:acknowledge", + "effect": "allow" + }, + { + "check": "c02:accept", + "effect": "allow" + }, + { + "check": "c02:return", + "effect": "allow" + }, + { + "check": "c02:discuss", + "effect": "allow" + }, + { + "check": "c02:decline", + "effect": "allow" + }, + { + "check": "c02:wrong-group", + "effect": "deny" + }, + { + "check": "c02:no-group", + "effect": "deny" + }, + { + "check": "c02:service", + "effect": "deny" + }, + { + "check": "c02:stale-mfa", + "effect": "deny" + }, + { + "check": "c02:future-mfa", + "effect": "deny" + }, + { + "check": "c02:no-mfa", + "effect": "deny" + }, + { + "check": "c02:forged-human-route", + "effect": "deny" + }, + { + "check": "c02:wrong-tenant", + "effect": "deny" + }, + { + "check": "c02:other-memo", + "effect": "deny" + }, + { + "check": "c02:omitted-c01", + "effect": "deny" + }, + { + "check": "c02:t03-memo", + "effect": "deny" + }, + { + "check": "c02:changed-version", + "effect": "deny" + }, + { + "check": "c02:changed-approval", + "effect": "deny" + }, + { + "check": "c02:changed-digest", + "effect": "deny" + }, + { + "check": "c02:consume", + "effect": "deny" + }, + { + "check": "c03:read", + "effect": "allow" + }, + { + "check": "c03:acknowledge", + "effect": "allow" + }, + { + "check": "c03:accept", + "effect": "allow" + }, + { + "check": "c03:return", + "effect": "allow" + }, + { + "check": "c03:discuss", + "effect": "allow" + }, + { + "check": "c03:decline", + "effect": "allow" + }, + { + "check": "c03:wrong-group", + "effect": "deny" + }, + { + "check": "c03:no-group", + "effect": "deny" + }, + { + "check": "c03:service", + "effect": "deny" + }, + { + "check": "c03:stale-mfa", + "effect": "deny" + }, + { + "check": "c03:future-mfa", + "effect": "deny" + }, + { + "check": "c03:no-mfa", + "effect": "deny" + }, + { + "check": "c03:forged-human-route", + "effect": "deny" + }, + { + "check": "c03:wrong-tenant", + "effect": "deny" + }, + { + "check": "c03:other-memo", + "effect": "deny" + }, + { + "check": "c03:omitted-c01", + "effect": "deny" + }, + { + "check": "c03:t03-memo", + "effect": "deny" + }, + { + "check": "c03:changed-version", + "effect": "deny" + }, + { + "check": "c03:changed-approval", + "effect": "deny" + }, + { + "check": "c03:changed-digest", + "effect": "deny" + }, + { + "check": "c03:consume", + "effect": "deny" + }, + { + "check": "c04:read", + "effect": "allow" + }, + { + "check": "c04:acknowledge", + "effect": "allow" + }, + { + "check": "c04:accept", + "effect": "allow" + }, + { + "check": "c04:return", + "effect": "allow" + }, + { + "check": "c04:discuss", + "effect": "allow" + }, + { + "check": "c04:decline", + "effect": "allow" + }, + { + "check": "c04:wrong-group", + "effect": "deny" + }, + { + "check": "c04:no-group", + "effect": "deny" + }, + { + "check": "c04:service", + "effect": "deny" + }, + { + "check": "c04:stale-mfa", + "effect": "deny" + }, + { + "check": "c04:future-mfa", + "effect": "deny" + }, + { + "check": "c04:no-mfa", + "effect": "deny" + }, + { + "check": "c04:forged-human-route", + "effect": "deny" + }, + { + "check": "c04:wrong-tenant", + "effect": "deny" + }, + { + "check": "c04:other-memo", + "effect": "deny" + }, + { + "check": "c04:omitted-c01", + "effect": "deny" + }, + { + "check": "c04:t03-memo", + "effect": "deny" + }, + { + "check": "c04:changed-version", + "effect": "deny" + }, + { + "check": "c04:changed-approval", + "effect": "deny" + }, + { + "check": "c04:changed-digest", + "effect": "deny" + }, + { + "check": "c04:consume", + "effect": "deny" + }, + { + "check": "d01:read", + "effect": "allow" + }, + { + "check": "d01:acknowledge", + "effect": "allow" + }, + { + "check": "d01:accept", + "effect": "allow" + }, + { + "check": "d01:return", + "effect": "allow" + }, + { + "check": "d01:discuss", + "effect": "allow" + }, + { + "check": "d01:decline", + "effect": "allow" + }, + { + "check": "d01:wrong-group", + "effect": "deny" + }, + { + "check": "d01:no-group", + "effect": "deny" + }, + { + "check": "d01:service", + "effect": "deny" + }, + { + "check": "d01:stale-mfa", + "effect": "deny" + }, + { + "check": "d01:future-mfa", + "effect": "deny" + }, + { + "check": "d01:no-mfa", + "effect": "deny" + }, + { + "check": "d01:forged-human-route", + "effect": "deny" + }, + { + "check": "d01:wrong-tenant", + "effect": "deny" + }, + { + "check": "d01:other-memo", + "effect": "deny" + }, + { + "check": "d01:omitted-c01", + "effect": "deny" + }, + { + "check": "d01:t03-memo", + "effect": "deny" + }, + { + "check": "d01:changed-version", + "effect": "deny" + }, + { + "check": "d01:changed-approval", + "effect": "deny" + }, + { + "check": "d01:changed-digest", + "effect": "deny" + }, + { + "check": "d01:consume", + "effect": "deny" + }, + { + "check": "d02:read", + "effect": "allow" + }, + { + "check": "d02:acknowledge", + "effect": "allow" + }, + { + "check": "d02:accept", + "effect": "allow" + }, + { + "check": "d02:return", + "effect": "allow" + }, + { + "check": "d02:discuss", + "effect": "allow" + }, + { + "check": "d02:decline", + "effect": "allow" + }, + { + "check": "d02:wrong-group", + "effect": "deny" + }, + { + "check": "d02:no-group", + "effect": "deny" + }, + { + "check": "d02:service", + "effect": "deny" + }, + { + "check": "d02:stale-mfa", + "effect": "deny" + }, + { + "check": "d02:future-mfa", + "effect": "deny" + }, + { + "check": "d02:no-mfa", + "effect": "deny" + }, + { + "check": "d02:forged-human-route", + "effect": "deny" + }, + { + "check": "d02:wrong-tenant", + "effect": "deny" + }, + { + "check": "d02:other-memo", + "effect": "deny" + }, + { + "check": "d02:omitted-c01", + "effect": "deny" + }, + { + "check": "d02:t03-memo", + "effect": "deny" + }, + { + "check": "d02:changed-version", + "effect": "deny" + }, + { + "check": "d02:changed-approval", + "effect": "deny" + }, + { + "check": "d02:changed-digest", + "effect": "deny" + }, + { + "check": "d02:consume", + "effect": "deny" + }, + { + "check": "d03:read", + "effect": "allow" + }, + { + "check": "d03:acknowledge", + "effect": "allow" + }, + { + "check": "d03:accept", + "effect": "allow" + }, + { + "check": "d03:return", + "effect": "allow" + }, + { + "check": "d03:discuss", + "effect": "allow" + }, + { + "check": "d03:decline", + "effect": "allow" + }, + { + "check": "d03:wrong-group", + "effect": "deny" + }, + { + "check": "d03:no-group", + "effect": "deny" + }, + { + "check": "d03:service", + "effect": "deny" + }, + { + "check": "d03:stale-mfa", + "effect": "deny" + }, + { + "check": "d03:future-mfa", + "effect": "deny" + }, + { + "check": "d03:no-mfa", + "effect": "deny" + }, + { + "check": "d03:forged-human-route", + "effect": "deny" + }, + { + "check": "d03:wrong-tenant", + "effect": "deny" + }, + { + "check": "d03:other-memo", + "effect": "deny" + }, + { + "check": "d03:omitted-c01", + "effect": "deny" + }, + { + "check": "d03:t03-memo", + "effect": "deny" + }, + { + "check": "d03:changed-version", + "effect": "deny" + }, + { + "check": "d03:changed-approval", + "effect": "deny" + }, + { + "check": "d03:changed-digest", + "effect": "deny" + }, + { + "check": "d03:consume", + "effect": "deny" + }, + { + "check": "d04:read", + "effect": "allow" + }, + { + "check": "d04:acknowledge", + "effect": "allow" + }, + { + "check": "d04:accept", + "effect": "allow" + }, + { + "check": "d04:return", + "effect": "allow" + }, + { + "check": "d04:discuss", + "effect": "allow" + }, + { + "check": "d04:decline", + "effect": "allow" + }, + { + "check": "d04:wrong-group", + "effect": "deny" + }, + { + "check": "d04:no-group", + "effect": "deny" + }, + { + "check": "d04:service", + "effect": "deny" + }, + { + "check": "d04:stale-mfa", + "effect": "deny" + }, + { + "check": "d04:future-mfa", + "effect": "deny" + }, + { + "check": "d04:no-mfa", + "effect": "deny" + }, + { + "check": "d04:forged-human-route", + "effect": "deny" + }, + { + "check": "d04:wrong-tenant", + "effect": "deny" + }, + { + "check": "d04:other-memo", + "effect": "deny" + }, + { + "check": "d04:omitted-c01", + "effect": "deny" + }, + { + "check": "d04:t03-memo", + "effect": "deny" + }, + { + "check": "d04:changed-version", + "effect": "deny" + }, + { + "check": "d04:changed-approval", + "effect": "deny" + }, + { + "check": "d04:changed-digest", + "effect": "deny" + }, + { + "check": "d04:consume", + "effect": "deny" + } + ] +} diff --git a/docs/request-enrichment.md b/docs/request-enrichment.md index ec39f6b..8c873df 100644 --- a/docs/request-enrichment.md +++ b/docs/request-enrichment.md @@ -110,6 +110,7 @@ genuinely the request; **ambiguous** is the T01 input. | markitect (example) | subject.groups | membership | allowlist | yes (first-class `groups`) | | markitect (example) | subject.roles | membership | allowlist | yes (first-class `roles`) | | informed-decision-t03 (fixture) | subject.assurance, groups, principal_type_source, tenant_source | mixed | see T01 | fixture-only; not a published consumer package | +| informed-decision-sitting (fixture) | subject.assurance, groups, principal_type_source, tenant_source | mixed | see T03 | new package, not a T03 expansion; unpublished until FLEX-WP-0028-T02 | No published-package ceiling or allowlist remains unbacked after the two declaration fixes above. `ttl_hours`, `purpose`, `requested_ttl_seconds`, and diff --git a/examples/informed-decision-sitting/fixtures.json b/examples/informed-decision-sitting/fixtures.json new file mode 100644 index 0000000..a4b6f93 --- /dev/null +++ b/examples/informed-decision-sitting/fixtures.json @@ -0,0 +1,21 @@ +[ + { + "id": "unknown-request-denied", + "request": { + "id": "unknown", + "subject": { + "id": "unknown", + "type": "human" + }, + "action": "accept", + "resource": { + "id": "memo:unrelated", + "type": "decision-memo", + "system": "informed-decision" + } + }, + "expect": { + "effect": "deny" + } + } +] diff --git a/examples/informed-decision-sitting/policy.md b/examples/informed-decision-sitting/policy.md new file mode 100644 index 0000000..72f44b2 --- /dev/null +++ b/examples/informed-decision-sitting/policy.md @@ -0,0 +1,108 @@ +--- +id: informed-decision.compact-sitting +name: Compact sitting exact-record human review +namespace: informed-decision:decision-memo +version: v1 +status: ready +package: flexauth.informed_decision.compact_sitting +allow_ttl: 30s +actions: [read, acknowledge, accept, return, discuss, decline] +owner: flex-auth +fixtures: [fixtures.json] +caring: + profile: caring-0.4.0-rc2 + enforce: false +activation: + mode: local +--- + +# Compact sitting review mandate + +This is a new exact-record package for seven 2026-09-14 sitting memos. +It is not an expansion of `examples/informed-decision-t03` / FLEX-WP-0027. +`memo:infd-20260914-c01` is omitted (create-client still undecided). + +The identity bar matches T03: authenticated informed-decision caller, +`net-kingdom-admins`, fresh KeyCape AAL2 MFA. No permission follows from +memo content or presentation state. TokenReview must admit +`system:serviceaccount:informed-decision:review` before this package is +served. Membership tenant provenance may follow the accepted registration +route; it does not assert directory membership in tenant:platform. +Only a real human uses accept. This package neither issues nor consumes +approval. Native pins: `docs/evidence/2026-09-15-sitting-approval-creates.json`. + +```rego +import rego.v1 + +records := { + "memo:infd-20260914-c02": { + "approval_id": "ccfd8007-2061-48fd-9356-99b16279dac1", + "binding_digest": "sha256:942cf7d5e6805987df2077a0cc6cde75b148e1729a96dd0692153287820b6a0a" + }, + "memo:infd-20260914-c03": { + "approval_id": "a0611d0d-b9ef-4b9a-aa79-e94a9e3fcd5f", + "binding_digest": "sha256:95cae135b994acea6dad9da978dd3df1aa3354de900a1f43c2e5a03a20e8e844" + }, + "memo:infd-20260914-c04": { + "approval_id": "22ac6df3-e6a9-472b-a68e-c8caca4289a7", + "binding_digest": "sha256:dec960b30efaf654abbdcd8a2cdd20d4ff6bf52e170744f817dc55845d9cb192" + }, + "memo:infd-20260914-d01": { + "approval_id": "9f7c3506-68de-4826-86ff-e301f428408d", + "binding_digest": "sha256:8cb7cc93f38db9d19b49e201e0554b50af1891fec853fef333a06ea078541d15" + }, + "memo:infd-20260914-d02": { + "approval_id": "b3ce2c01-0a3b-401e-b4ed-c1954af169c9", + "binding_digest": "sha256:be0c7de123216740d2c2eeaed80384e03e6b6d1668104f94bb8f9cbae7dfe30f" + }, + "memo:infd-20260914-d03": { + "approval_id": "3b483e6b-0b92-45ff-83b6-bc5057c0a496", + "binding_digest": "sha256:3c562278e86bb5e7f747452cf2e99d3a136853ab748676e8359262b835cd1425" + }, + "memo:infd-20260914-d04": { + "approval_id": "356e67a3-5539-46a1-922a-f5591fd38ee5", + "binding_digest": "sha256:3c2d7759679d871cb7c5cac8999542a365e64c918d59d0c4ce864ffb837453e4" + } +} + +decision := {"effect": "allow", "reason": "operator_admitted_compact_sitting"} if { + input.tenant == "tenant:platform" + input.subject.tenant == "tenant:platform" + input.subject.type == "human" + is_string(input.subject.id) + input.subject.id != "" + input.subject.attributes.principal_type_source == "authentication-derived" + input.subject.attributes.tenant_source in {"registration-supplied", "directory-asserted"} + "net-kingdom-admins" in input.subject.attributes.groups + assurance := input.subject.attributes.assurance + assurance.level == "aal2" + assurance.mfa == true + assurance.source == "key-cape" + assurance.methods == ["pwd", "otp"] + is_number(assurance.at) + assurance.at > 0 + age := time.now_ns() / 1000000000 - assurance.at + age >= -30 + age <= 900 + input.resource.tenant == "tenant:platform" + input.resource.system == "informed-decision" + input.resource.type == "decision-memo" + record := records[input.resource.id] + input.context.memo_version == 1 + input.context.approval_id == record.approval_id + input.context.approval_binding_digest == record.binding_digest + input.action in {"read", "acknowledge", "accept", "return", "discuss", "decline"} +} else := {"effect": "deny", "reason": "compact_sitting_scope_or_identity_refused"} if { + true +} +``` + +```rego test +package flexauth.informed_decision.compact_sitting_test +import rego.v1 +import data.flexauth.informed_decision.compact_sitting + +test_unknown_request_denied if { + compact_sitting.decision.effect == "deny" with input as {} +} +``` diff --git a/examples/informed-decision-sitting/records.json b/examples/informed-decision-sitting/records.json new file mode 100644 index 0000000..14b4dde --- /dev/null +++ b/examples/informed-decision-sitting/records.json @@ -0,0 +1,121 @@ +{ + "memo:infd-20260914-c02": { + "approval_id": "ccfd8007-2061-48fd-9356-99b16279dac1", + "binding_digest": "sha256:942cf7d5e6805987df2077a0cc6cde75b148e1729a96dd0692153287820b6a0a", + "label": "c02", + "binding": { + "action": "accept", + "actor": "informed-decision", + "principal": "railiance-platform", + "purpose": "Accept provisioning of the secrets-engine service JWT login on the reviewed credential lane", + "target": { + "id": "rpf-wp-0035-t02", + "type": "credential-lane", + "system": "railiance-platform" + } + }, + "memo_version": 1 + }, + "memo:infd-20260914-c03": { + "approval_id": "a0611d0d-b9ef-4b9a-aa79-e94a9e3fcd5f", + "binding_digest": "sha256:95cae135b994acea6dad9da978dd3df1aa3354de900a1f43c2e5a03a20e8e844", + "label": "c03", + "binding": { + "action": "apply", + "actor": "informed-decision", + "principal": "netkingdom", + "purpose": "Apply the live OpenBao role addition already specified for the operator-tunneled browser callback", + "target": { + "id": "nk-wp-0032-t03", + "type": "openbao-role", + "system": "netkingdom" + } + }, + "memo_version": 1 + }, + "memo:infd-20260914-c04": { + "approval_id": "22ac6df3-e6a9-472b-a68e-c8caca4289a7", + "binding_digest": "sha256:dec960b30efaf654abbdcd8a2cdd20d4ff6bf52e170744f817dc55845d9cb192", + "label": "c04", + "binding": { + "action": "attend", + "actor": "informed-decision", + "principal": "ops-warden", + "purpose": "Attend the graded lockdown / break-glass seal for ops-warden trust-root work", + "target": { + "id": "warden-wp-0027-t02", + "type": "trust-root", + "system": "ops-warden" + } + }, + "memo_version": 1 + }, + "memo:infd-20260914-d01": { + "approval_id": "9f7c3506-68de-4826-86ff-e301f428408d", + "binding_digest": "sha256:8cb7cc93f38db9d19b49e201e0554b50af1891fec853fef333a06ea078541d15", + "label": "d01", + "binding": { + "action": "retire", + "actor": "informed-decision", + "principal": "the-custodian", + "purpose": "After HA failover and restore drills pass, retire WSL2 as a State Hub fallback", + "target": { + "id": "cust-wp-0038-t08", + "type": "operating-model", + "system": "the-custodian" + } + }, + "memo_version": 1 + }, + "memo:infd-20260914-d02": { + "approval_id": "b3ce2c01-0a3b-401e-b4ed-c1954af169c9", + "binding_digest": "sha256:be0c7de123216740d2c2eeaed80384e03e6b6d1668104f94bb8f9cbae7dfe30f", + "label": "d02", + "binding": { + "action": "confirm", + "actor": "informed-decision", + "principal": "helixforge-factory", + "purpose": "Confirm the existing operator-group claim for CCR-2026-0019 as required by the factory identity/audit/approval path", + "target": { + "id": "ccr-2026-0019", + "type": "ccr", + "system": "helixforge-factory" + } + }, + "memo_version": 1 + }, + "memo:infd-20260914-d03": { + "approval_id": "3b483e6b-0b92-45ff-83b6-bc5057c0a496", + "binding_digest": "sha256:3c562278e86bb5e7f747452cf2e99d3a136853ab748676e8359262b835cd1425", + "label": "d03", + "binding": { + "action": "accept", + "actor": "informed-decision", + "principal": "mason", + "purpose": "Accept the fluid-telegram operator credential lane plan so construction may proceed", + "target": { + "id": "mason-wp-0005", + "type": "workplan", + "system": "mason" + } + }, + "memo_version": 1 + }, + "memo:infd-20260914-d04": { + "approval_id": "356e67a3-5539-46a1-922a-f5591fd38ee5", + "binding_digest": "sha256:3c2d7759679d871cb7c5cac8999542a365e64c918d59d0c4ce864ffb837453e4", + "label": "d04", + "binding": { + "action": "confirm", + "actor": "informed-decision", + "principal": "railiance-clock", + "purpose": "Confirm ecosystem ownership and the security role for Railiance Clock as specified", + "target": { + "id": "rclk-wp-0002-t01", + "type": "workplan", + "system": "railiance-clock" + } + }, + "memo_version": 1 + } +} diff --git a/examples/informed-decision-sitting/registry.json b/examples/informed-decision-sitting/registry.json new file mode 100644 index 0000000..0536a09 --- /dev/null +++ b/examples/informed-decision-sitting/registry.json @@ -0,0 +1,17 @@ +{ + "subjects": [ + { + "id": "sitting-reviewer", + "type": "Human", + "display_name": "Compact sitting reviewer", + "organization_relation": "ServiceProvider", + "groups": ["net-kingdom-admins"], + "claims": { + "assurance": "aal2", + "principal_type_source": "authentication-derived", + "tenant_source": "registration-supplied" + } + } + ], + "resources": [] +} diff --git a/tools/exercise_sitting_review_policy.py b/tools/exercise_sitting_review_policy.py new file mode 100644 index 0000000..72e988d --- /dev/null +++ b/tools/exercise_sitting_review_policy.py @@ -0,0 +1,93 @@ +import json, time, copy, subprocess, tempfile +from pathlib import Path +import argparse + +p = argparse.ArgumentParser() +p.add_argument('--binary', required=True) +p.add_argument('--receipt', type=Path, required=True) +args = p.parse_args() +r = Path(__file__).resolve().parents[1] / 'examples/informed-decision-sitting' +records = json.loads((r / 'records.json').read_text()) +results = [] +with tempfile.TemporaryDirectory() as temp: + request_path = Path(temp) / 'request.json' + + def check(name, request, expected): + request_path.write_text(json.dumps(request)) + result = subprocess.run( + [args.binary, 'check', '--registry', str(r / 'registry.json'), + '--policy', str(r / 'policy.md'), '--request', str(request_path)], + capture_output=True, text=True, check=True) + d = json.loads(result.stdout) + assert d['effect'] == expected, (name, d) + results.append({'check': name, 'effect': d['effect']}) + return d + + for memo, record in records.items(): + request = { + 'id': 'local-regression', + 'tenant': 'tenant:platform', + 'subject': { + 'id': 'synthetic-reviewer', + 'type': 'human', + 'tenant': 'tenant:platform', + 'attributes': { + 'groups': ['net-kingdom-admins'], + 'roles': [], + 'tenant_source': 'registration-supplied', + 'principal_type_source': 'authentication-derived', + 'assurance': { + 'level': 'aal2', + 'mfa': True, + 'methods': ['pwd', 'otp'], + 'source': 'key-cape', + 'at': int(time.time()), + }, + }, + }, + 'resource': { + 'id': memo, + 'type': 'decision-memo', + 'system': 'informed-decision', + 'tenant': 'tenant:platform', + }, + 'action': 'accept', + 'context': { + 'memo_version': 1, + 'approval_id': record['approval_id'], + 'approval_binding_digest': record['binding_digest'], + }, + 'policy_version': 'v1', + } + label = record['label'] + for action in ['read', 'acknowledge', 'accept', 'return', 'discuss', 'decline']: + check(label + ':' + action, request | {'action': action}, 'allow') + for name, path, value in [ + ('wrong-group', ['subject', 'attributes', 'groups'], ['net-kingdom-users']), + ('no-group', ['subject', 'attributes', 'groups'], []), + ('service', ['subject', 'type'], 'service'), + ('stale-mfa', ['subject', 'attributes', 'assurance', 'at'], int(time.time()) - 901), + ('future-mfa', ['subject', 'attributes', 'assurance', 'at'], int(time.time()) + 300), + ('no-mfa', ['subject', 'attributes', 'assurance', 'mfa'], False), + ('forged-human-route', ['subject', 'attributes', 'principal_type_source'], 'registration-supplied'), + ('wrong-tenant', ['subject', 'tenant'], 'tenant:other'), + ('other-memo', ['resource', 'id'], 'memo:other'), + ('omitted-c01', ['resource', 'id'], 'memo:infd-20260914-c01'), + ('t03-memo', ['resource', 'id'], 'memo:SECRETS-WP-0010-T03-apply'), + ('changed-version', ['context', 'memo_version'], 2), + ('changed-approval', ['context', 'approval_id'], 'other'), + ('changed-digest', ['context', 'approval_binding_digest'], 'sha256:' + '0' * 64), + ('consume', ['action'], 'consume'), + ]: + candidate = copy.deepcopy(request) + target = candidate + for key in path[:-1]: + target = target[key] + target[path[-1]] = value + check(label + ':' + name, candidate, 'deny') + +args.receipt.write_text(json.dumps({ + 'scope': 'local actual evaluator with synthetic identity; no live human approvals; T03 package untouched', + 'checks': results, +}, indent=2) + '\n') +print(len(results), 'policy checks passed') diff --git a/values/informed-decision-sitting.yaml b/values/informed-decision-sitting.yaml new file mode 100644 index 0000000..19ceccf --- /dev/null +++ b/values/informed-decision-sitting.yaml @@ -0,0 +1,28 @@ +# Compact sitting exact-record human review. Distinct from +# values/informed-decision-t03.yaml / FLEX-WP-0027. +# image.digest is filled after CI builds the commit that added +# examples/informed-decision-sitting. Do not helm-upgrade until then: +# the live T03 digest does not contain this package. +name: flex-auth-informed-decision-sitting +image: + repository: forgejo.coulomb.social/coulomb/flex-auth + digest: sha256:0000000000000000000000000000000000000000000000000000000000000000 +args: + - serve + - --addr + - 0.0.0.0:8080 + - --registry + - /opt/flex-auth/examples/informed-decision-sitting/registry.json + - --policy + - /opt/flex-auth/examples/informed-decision-sitting/policy.md +callerAuth: + mode: enforce + kubernetesURL: https://10.43.0.1 + binding: informed-decision=system:serviceaccount:informed-decision:review +consumer: + isolated: false + namespace: informed-decision + podName: informed-decision +resources: + requests: {cpu: 5m, memory: 32Mi} + limits: {cpu: 300m, memory: 192Mi} diff --git a/workplans/FLEX-WP-0028-compact-sitting-review.md b/workplans/FLEX-WP-0028-compact-sitting-review.md new file mode 100644 index 0000000..1b066c5 --- /dev/null +++ b/workplans/FLEX-WP-0028-compact-sitting-review.md @@ -0,0 +1,50 @@ +--- +id: FLEX-WP-0028 +type: workplan +title: "Admit scoped human review for the seven compact sitting memos" +domain: infotech +repo: flex-auth +status: active +flavor: implementation +owner: grok +topic_slug: netkingdom +created: "2026-09-15" +updated: "2026-09-15" +related_workplans: + - FLEX-WP-0027 + - INFD-WP-0002 +--- + +Opened from informed-decision inbox `f266bf8c-072e-4a80-9a6b-ff89ee422d6b`. +Do not widen `examples/informed-decision-t03` / FLEX-WP-0027. + +## Compile the seven-record sitting mandate + +```task +id: FLEX-WP-0028-T01 +status: done +priority: high +``` + +Pins from `docs/evidence/2026-09-15-sitting-approval-creates.json`. +`examples/informed-decision-sitting` binds the seven native approval ids and +digests. `memo:infd-20260914-c01` is omitted. Same identity bar as T03. +147 evaluator checks pass (42 allow / 105 deny), including omitted c01, T03 +memo ids, consume, and identity refusals. T03's 57 checks still pass. +Reproduce with `python3 tools/exercise_sitting_review_policy.py --binary /path/to/flex-auth --receipt /tmp/sitting-checks.json`. +Receipt: `docs/evidence/2026-09-15-sitting-review-policy.json`. + +## Deploy the isolated caller-bound policy + +```task +id: FLEX-WP-0028-T02 +status: wait +priority: high +``` + +Wait for CI to publish an image that contains `examples/informed-decision-sitting`, +then pin `values/informed-decision-sitting.yaml` by digest and helm-upgrade a +new release. Do not reuse the T03 image or change the T03 Deployment. +TokenReview admits only `system:serviceaccount:informed-decision:review`. +Native caller checks with synthetic identities are required before calling +this admitted. Human bind stays with INFD-WP-0002.