The consumed T03 approval IDs cannot be created again. The T03 review package and the sitting list pins now name three new approval IDs. Binding digests and the sitting act records stay as they are. Assistant: grok Assistant-Session: 01a0e2a1-8058-7553-9999-b7d106c17047
197 lines
8 KiB
Markdown
197 lines
8 KiB
Markdown
---
|
|
id: informed-decision.compact-sitting
|
|
name: Compact sitting exact-record human review
|
|
namespace: informed-decision:decision-memo
|
|
version: v3
|
|
status: ready
|
|
package: flexauth.informed_decision.compact_sitting
|
|
allow_ttl: 30s
|
|
actions: [read, acknowledge, accept, return, discuss, decline, list]
|
|
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.
|
|
v2 (2026-09-21) adds exactly one record, `memo:infd-20260921-b01` (the
|
|
SECRETS-WP-0009-T03 spend envelope), with native pins from informed-decision
|
|
`docs/evidence/2026-09-21-budget-approval-create.json`. The seven v1 records
|
|
and the identity bar are unchanged.
|
|
It is not an expansion of `examples/informed-decision-t03` / FLEX-WP-0027.
|
|
`memo:infd-20260914-c01` is omitted (create-client still undecided).
|
|
|
|
v3 (2026-09-21, `FLEX-WP-0032`, `FLEX-DEC-2026-017`) adds one action, `list`,
|
|
for informed-decision's decision overview (`INFD-IN-0008`). It is a separate
|
|
rule, not an extra member of the act set, and it changes nothing else:
|
|
|
|
- `read` and the five acts keep the v2 rule unchanged — the same eight records,
|
|
the same 900-second MFA window. A `list` allow satisfies no other action.
|
|
- `list` covers the **union** of this package's eight records and the three
|
|
`SECRETS-WP-0010-T03-*` records from `informed-decision.t03-review`, each
|
|
pinned by approval id, binding digest and its own memo version (T03 at 3).
|
|
Scope stays exact-record: a memo is listable only once someone admitted it.
|
|
The operator declined resource-type-wide scope because the PDP checks no
|
|
recipient, and a type-wide rule would have left consumer code — which the
|
|
consumer itself says is not an entitlement — as the only scope.
|
|
- `list` carries the same identity bar with a **12-hour** MFA window instead of
|
|
900 seconds. Looking back at your own outcomes is not binding a new one. The
|
|
bar is lighter, not absent: the PDP still states a bound.
|
|
- The KeyCape stale-timestamp defect (`INFD-IN-0005`) is **not** worked around
|
|
here. `read` stays strict; that defect is key-cape's to fix.
|
|
|
|
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"
|
|
},
|
|
"memo:infd-20260921-b01": {
|
|
"approval_id": "ba5ce2d8-8b6d-40be-af89-2e8c147029a3",
|
|
"binding_digest": "sha256:e9eaf454e94871ec2060855fcfbd327bcaec873d2c61cae031bec9f95a34bcae"
|
|
}
|
|
}
|
|
|
|
list_only_records := {
|
|
"memo:SECRETS-WP-0010-T03-apply": {
|
|
"approval_id": "b5fcbfcc-ad56-456f-bc36-c823052e9917",
|
|
"binding_digest": "sha256:03cc5b37437f14e86b686ce4054f976556334eff3fa260b03e8014ed3d9217e5",
|
|
"memo_version": 3
|
|
},
|
|
"memo:SECRETS-WP-0010-T03-verify": {
|
|
"approval_id": "4e9ff881-d59f-4143-9155-929afbe8dd43",
|
|
"binding_digest": "sha256:72d9267d038c17107c880ffc9009793ce9c70defbddfe2219628854b811a04b2",
|
|
"memo_version": 3
|
|
},
|
|
"memo:SECRETS-WP-0010-T03-exec": {
|
|
"approval_id": "a24e0898-b3c5-4e50-85a8-18a2c2aa229e",
|
|
"binding_digest": "sha256:f2cf0fb53b740900756ccde5587c3578fcff44beef2f1edab17b9a198a4033d8",
|
|
"memo_version": 3
|
|
}
|
|
}
|
|
|
|
# listable is the union list may range over. Sitting records are memo version 1,
|
|
# as the act rule pins; T03 records carry their own version (3).
|
|
listable := object.union(
|
|
{id: object.union(r, {"memo_version": 1}) | some id, r in records},
|
|
list_only_records,
|
|
)
|
|
|
|
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": "allow", "reason": "operator_admitted_overview_list"} if {
|
|
input.action == "list"
|
|
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 <= 43200
|
|
input.resource.tenant == "tenant:platform"
|
|
input.resource.system == "informed-decision"
|
|
input.resource.type == "decision-memo"
|
|
record := listable[input.resource.id]
|
|
input.context.memo_version == record.memo_version
|
|
input.context.approval_id == record.approval_id
|
|
input.context.approval_binding_digest == record.binding_digest
|
|
} 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 {}
|
|
}
|
|
|
|
test_listable_is_exact_union if {
|
|
count(compact_sitting.listable) == count(compact_sitting.records) + count(compact_sitting.list_only_records)
|
|
}
|
|
|
|
test_t03_records_not_in_act_scope if {
|
|
every id, _ in compact_sitting.list_only_records {
|
|
not compact_sitting.records[id]
|
|
}
|
|
}
|
|
```
|