Skip to content

[finding] The ADR-0056 D10 authz matrix has no row for the ADR-0091 grant validity windows either — a second instance of #8711's gap #8811

Description

@qq9340100

Blocked-by: #8711

Found while implementing #8711 (which adds the rows for the grant-catalogue active flag). Filed unassigned; observation-class.

packages/qa/dogfood/test/authz-conformance.matrix.ts is described as "one row per authorization primitive, each in EXACTLY ONE honest state (enforced / experimental / removed)".

ADR-0091 grant validity windows are an authorization primitive, and they are enforced. isGrantActive(row, nowMs) drops a grant outside its valid_from / valid_to window at resolution time, at three call sites in packages/core/src/security/resolve-authz-context.ts:

  • step 3 — sys_member rows, before the membership role projection;
  • step 4 — sys_user_position rows (an expired role assignment stops granting);
  • step 6 — sys_user_permission_set rows, dropped BEFORE any derivation, so an expired admin_full_access grant cannot yield platform_admin either.

There is no row for it. The only mention of ADR-0091 anywhere in the matrix is incidental, inside accessible-org-ids's enforcement string — and that row classifies a different primitive (the core-resolved org access set). It does not put the validity window in a state of its own, so under the file's stated invariant the row is owed.

Same mechanism as #8711. The ratchet matches covers keys against a discover() that enumerates HTTP entry points from a curated per-file probe table, so a predicate inside an existing resolver can be neither UNCLASSIFIED nor STALE. Nothing can force this row to exist, and nothing can notice that it does not.

This is not #8802. That card reports that the window is not applied to one particular sys_member read (the org-admin role projection) — a defect in the enforcement. This is a gap in the ledger that records the enforcement. Fixing #8802 leaves the row just as missing.

Relationship to #8711. #8711's second question — whether the matrix's advertised scope should be narrowed in writing to what the ratchet can check, or the ratchet widened — is the general form of this. This card is a concrete second instance, and it is worth having on the record precisely because it shows the active flag was not a one-off: the measurement taken on #8711 found 41 of 48 rows carry no ratchet key at all. Whatever is decided on the general question, the row is owed under the invariant as currently written.

Not a recommendation on which way #8711's question should go.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions