Skip to content

[finding] authorization.mdx lists the inert D5 pair alongside the enforced reason / delegated_from as one set of "lifecycle-audit columns" #9671

Description

@os-project-manager

Observation-class, filed unassigned. Surfaced while implementing #9046 (PR #9669); deliberately not fixed there — a content/docs/** edit pulls in a different gate family than that card's packages/** surface, so it fails the in-place bounding test and gets its own card.

What the page says

content/docs/permissions/authorization.mdx:296-299, in the "Grant lifecycle: validity windows (ADR-0091 L1)" section:

Every user-grant row (sys_user_position, sys_user_permission_set) carries optional effective-dating columnsvalid_from / valid_until (half-open [from, until), UTC; null = unbounded) — plus the lifecycle-audit columns reason, delegated_from, last_certified_at / certified_by.

Four columns are named in one list, as one kind of thing. Measured on main, they are two kinds:

columnstatus
reasonenforced — the delegated-admin gate requires it on delegation rows; packages/lint/src/validate-security-posture.ts errors on a delegation row without one
delegated_fromenforced — read by plugin-security/src/delegated-admin-gate.ts, and by the explain engine for attribution
last_certified_atinert — no producer, no consumer anywhere in the repo (#9046's sweep)
certified_byinert — same

Why it is worth a line rather than a shrug

The page is not lying outright, and that is what makes it easy to miss: further down (line ~330) it correctly says "Break-glass activation and recertification campaigns remain enterprise product … their community shapes (a time-boxed direct grant with a reason; certification stamps) are the L1 substrate above." So the page does distinguish campaign from substrate — just not in the sentence where a reader meets the four column names side by side.

Access recertification is a compliance surface (SOX / ISO 27001 access review), so the reader most likely to scan that list is the one for whom the conflation is expensive: it reads as four audit columns the platform maintains, when two are maintained and two are storage nothing touches.

#9669 has now made the field descriptions themselves state the inertness outright. That leaves this page as the remaining place where the two classes are presented as one, and it is now weaker than the metadata it documents.

Suggested shape (not a spec)

One clause splitting the list — e.g. naming reason / delegated_from as enforced audit columns and last_certified_at / certified_by as the D5 substrate that no framework code writes or reads today, matching the wording that landed on the declarations in #9669. No behavior change, no ADR change: ADR-0091 D5 already says framework ships the substrate and cloud ships the campaign.

Refs: #9046 (the finding this came out of) · #9669 (the field-description fix) · ADR-0091 D5 · ADR-0049.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions