Problem/Motivation

The results store (#3608513: Add results store and trends) already tracks movement of the permission risk check's findings: a risky grant appearing or being revoked shows up in the changes timeline today. But those findings only cover the dangerous classes. For everything else — the ordinary majority of permission-space — the site has no memory at all: "when did the contractor role get that permission?" is answerable only by config-history archaeology on sync-disciplined sites, and by nothing on the rest.

An earlier revision of this issue framed new grants as problems to flag. Review discarded that framing: granting permissions is the CMS working as intended, and a "warning until acknowledged" model would need an acknowledgment workflow while lying about state. What a diagnosis-over-time tool honestly owes is memory, not judgment — an inventory with a timeline.

Steps to reproduce

Grant any non-flagged permission to any role between two check-ups: nothing anywhere records that it happened or when.

Proposed resolution

The check

A new permission_grants check (security category, sibling of permission_risk, sharing PermissionResolver): one OK-severity finding per (role, permission) grant — the full inventory, not only flagged permissions, because the "restrict access"/admin flags are advisory metadata that contrib modules apply inconsistently, and a flagged-only inventory would inherit that unreliability. The store's existing lifecycle machinery provides all semantics for free: a new grant is a "New" event with a date, a revocation is "No longer found", and "when did role X get permission Y" becomes a stored fact.

Deliberate semantics: events, not severity. A new grant stays OK — the news is the timeline entry, not a state judgment. Intended changes need no acknowledgment (a diary is reviewed, not resolved); revocation is the only resolution; this check never gates CI. The existing risky-grant rules in permission_risk keep their severities and their (already working) movement tracking; a risky grant simply appears in both checks, answering two different questions. The first run establishes the baseline as a one-time wave of "New" inventory events — expected and documented, not a bug.

The Inventory section (presentation rule: OK = inventory)

This check makes OK findings load-bearing, which exposes that they currently squat in problem-framed UI. New page-wide rule: OK findings appear in a new "Inventory" report-page section, and nowhere else on the page. The section is the one-stop shop:

  • Holdings — current counts per inventory-contributing check ("Permission grants: 1,412 · Configuration overrides: 3"), now-state, labeled "as of the latest check-up".
  • Inventory changes — its own movement feed (own pager, element-indexed so page=N,M composes with the main feed's; the period and area filters apply; severity structurally does not, and the section says so).

"What changed" becomes problems-only. Severity transitions across the OK boundary appear in both feeds with per-feed vocabulary: the main feed says "Got worse (OK → warning)" / "Improved (warning → OK)"; the inventory feed says "Left inventory (became a warning)" / "Entered inventory (improved from a warning)" — one stored event, two readerships, and the holdings count changes are always explained by the inventory feed. Machine formats (json/llm/the store) are untouched — they carry everything.

What this deliberately is not

Not an audit log (no actor attribution, no keystroke trail — who-did-it belongs to audit tooling); not a gate; not a replacement for config-drift's coarse role-config tracking, which remains the right signal for sync-disciplined deploy review.

Recipe: plugin in src/Plugin/SiteDoctor/Check/, kernel test in tests/src/Kernel/Check/ extending CheckKernelTestBase, fixtures in both directions. See CONTRIBUTING.md.

Remaining tasks

  • Implement the check + kernel tests, including the two-run "grant appears as a New event" assertion.
  • Implement the Inventory section (holdings + movement feed + second pager) and remove OK events from the main feed per the routing above; kernel tests for the routing table.
  • Document the first-run baseline wave in the check description and README.
  • Escape hatch noted for review: if the full inventory proves heavy on very large sites, scoping becomes a settings knob later — narrowing preserves fingerprints, widening would re-baseline, hence full-first.

User interface changes

New "Inventory" section on /admin/reports/site-doctor (holdings + its own paged changes feed); the main "What changed" feed no longer shows pure OK events.

API changes

One new check plugin. No service or schema changes.

Data model changes

None — uses the existing results store tables. Row-count note: the inventory adds one lifecycle row per current grant (hundreds to low thousands; steady-state writes remain churn-only).

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

amangrover90 created an issue. See original summary.

amangrover90’s picture

Issue summary: View changes

  • amangrover90 committed aa7581b7 on 1.x
    Resolves #3608634: Permission grants inventory and Inventory dashboard...
amangrover90’s picture

Status: Active » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.