informed-decision/docs/flex-auth-request-list-action.md

115 lines
5.3 KiB
Markdown
Raw Normal View History

# Request to flex-auth: a `list` action for the decision overview
**From:** informed-decision (`INFD-WP-0004`, intake `INFD-IN-0008`)
**To:** flex-auth, as the owner of the `informed-decision.*` policy packages
**Date:** 2026-09-21
**Status:** draft, not yet sent
## What we ask
Please admit a policy for a new consumer action, **`list`**, on
`decision-memo` resources of system `informed-decision`. The identity bar for
`list` should allow comfortable browsing, and it should cover the memos of
**both** admitted packages (`informed-decision.t03-review` and
`informed-decision.compact-sitting`). This repository proposes the rule;
flex-auth decides it. Nothing here grants anything until you publish a
package, version and digest.
## Why
`INFD-WP-0003` put a decision overview on the signed-in home page. Each row
asks Flex Auth for `read`, the same action that gates rendering a memo for
binding. Since 2026-09-21 the review deployment points at
`informed-decision.compact-sitting` v2. In production this has two
consequences:
1. **Every row is refused, even after the operator signs in again.** The
`read` rule requires `age <= 900` on `assurance.at`. KeyCape copies the
previous session's timestamp even after an actual MFA (`INFD-IN-0005`).
Authelia 4.38 cannot be made to force reauthentication (`cbea539`). So a
browsing session usually cannot meet a bar designed for binding.
Confirming this against the live policy observations is pending.
2. **The three `SECRETS-WP-0010-T03-*` memos are out of scope for good.** They
were admitted under `informed-decision.t03-review`. The served sitting
package does not name them, so their own reviewer cannot see their outcome.
Looking back at your own decisions should not need to meet the bar for signing
a new one. Binding keeps its strict bar. Only the list gets a lighter one.
## The consumer contract for `list`
The request shape is unchanged (`docs/flex-auth-review-contract.md`): the same
closed profile, caller, subject object and memo resource, and the same
`context` (`memo_version`, `approval_id`, `approval_binding_digest`). Only
`action` is `"list"`. It is one request per memo row. There is no wildcard and
no collection resource.
After an `allow` for `list`, the consumer shows **only** the following:
- memo id and version, and the memo's question;
- the live Approval Engine status, read by the approval id the memo carries;
- the requesting person's own recorded responses on that memo: verb, memo
version, time and submission state. Notes are excluded.
It does **not** show the brief, terms, justification, highlights, packet,
attachments or anyone else's responses. A `list` allow never enables
`acknowledge` or any disposition. Opening the memo for review still asks
`read`, and every act still asks its own action under the current strict rules.
The consumer still requires `memo.binding.principal.id == subject` before it
asks. That structural match is not an entitlement.
## Proposed rule
Identity: the same as today, minus the freshness window.
```rego
input.subject.type == "human"
input.subject.tenant == "tenant:platform"
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
input.subject.attributes.assurance.level == "aal2"
input.subject.attributes.assurance.mfa == true
input.subject.attributes.assurance.source == "key-cape"
# no `age <= 900` for list
input.action == "list"
```
For the resource, the owner can choose between two scopes:
- **(A) Resource-type-wide.** This covers any `decision-memo` of system
`informed-decision` in `tenant:platform`. It needs no package revision per
sitting. It relies on the consumer's structural recipient match to keep other
people's memos out of a person's list. **The consumer prefers this option
for comfort.**
- **(B) Exact-record union.** This covers the eight sitting records plus the
three T03 records, pinned by approval id and binding digest as today. It is
tighter. It needs a new version every time a sitting adds memos. It would
also need to accept T03's memo version 2, whereas the sitting rule pins
`memo_version == 1`.
Either option could ship as a new version of the served sitting package (v3),
which also keeps `read` and every act exactly as in v2. It could also ship as
a separate package, but then the consumer would need a second PDP pin, because
the runtime carries only one package pin today. The consumer prefers **v3 of
`informed-decision.compact-sitting`**.
## What informed-decision delivers on its side
- `list` in `policy.ACTIONS` and in the consumer contract document;
- an overview that asks `list`, shows only the fields above, and still asks
`read` on the review page;
- positive and negative fixtures for flex-auth: stale MFA allowed for `list`
but refused for `read`; no group refused; agent refused; and, under option
(B), an unlisted memo refused;
- after your package lands, the admission input is updated to the new
package, version and digest, and the rollout is recorded.
## Disclosure trade-off (for the owner to weigh)
With option (A), a person holding any AAL2 session in `net-kingdom-admins` can
see the questions and statuses of memos addressed to them, without a
15-minute-fresh MFA. Today that needs fresh MFA. Brief, packet and all binding
stay behind the strict bar.