Run the AI governance overview
Read the AI estate in one screen, run a discovery scan, tune what discovery looks at, and route each open finding to the page that resolves it.
- Version: 0.4
- Feature: governance
- Role: admin_user, viewer
- Type: task
The compliance module answers what did our controls catch. Governance answers a question no detection stream can: what AI is this organisation accountable for, who owns it, and what risk tier did a human put it in. Governance Overview is that estate in one screen, and every number on it is a link to the rows behind it.
What do I need?
- Licence
- Any
- Role
admin_userviewer
Prerequisites
- The appliance has traffic in the usage lookback window, or at least one active model in the catalogue — discovery reads existing records and creates none of its own.
- You are signed in as admin_user or superadmin if you intend to run a scan or change the discovery settings.
admin_user, superadmin, auditor and viewer may open all four governance pages. Run
discovery and Discovery settings are shown only to admin_user and superadmin; a
viewer reading the page has its writes refused globally with READ_ONLY_ROLE, and hiding the
controls is a better way to learn that than pressing them.
/assets/screenshots/governance@0.4.pngThe distinction the module is built around
Four statuses, and the difference between the first two is the point of the whole module:
| Status | What it means | Finding raised | Who fixes it |
|---|---|---|---|
| Shadow | Seen in traffic, covered by no managed configuration | shadow_app_detected | Security — this is Shadow AI |
| Unregistered | Configured and known, nobody owns it | missing_owner | Management — assign an owner |
| Registered | A person accepted ownership | missing_risk_profile while no tier is declared | The owner — classify it |
| Decommissioned | Retired, kept for the audit trail | none | — |
"We did not know it existed" and "we know it and nobody owns it" go to different people. Collapsing them into one untracked bucket is the mistake this module exists to avoid.
Status only ever climbs that ladder. A scan can never demote a registered asset, and nothing can move a decommissioned one back — otherwise the Register button would have a half-life of one scan.
Read the estate
Open the page
Select Governance → Governance Overview.
The sub-navigation across the top — Overview, Inventory, Risk, Ownership — is shared by all four governance pages.
Read the four estate tiles
Read The estate.
Assets tracked, Ownerless, Unclassified and Open findings. Each is a link: selecting one opens the filtered list that produced it. Unclassified is not low risk — it means nobody has declared a profile.
Read the lifecycle and the tiers
Read Lifecycle and Risk tiers.
Lifecycle is a count per status; Risk tiers is a count per EU AI Act tier, riskiest first. Every member of both vocabularies is present, with a zero where nothing matched, so a tier that is genuinely empty is distinguishable from one the page forgot.
Route the open findings
Read Open findings by type, and select a row.
Each type routes to the page that can actually resolve it: Missing owner to Ownership, Shadow app detected to the shadow slice of Inventory, Missing risk profile to the unclassified group on Risk classification, and Declared vs observed mismatch to Risk. Findings are not filterable by asset anywhere in the dashboard, so this routing is the way in.
Check when discovery last saw anything
Read the Discovery box.
Most recent observation is the newest asset sighting; Latest finding day is the day the last finding was written. Both empty on a box where discovery has never produced anything.
Run a scan now
Run it
Select Run discovery.
The button reads Scanning… while the scan runs, and the result toast reports subjects scanned, assets created and updated, and findings opened. The drift pass runs in the same request and adds Drift: N new findings.
Read whether it overrode the schedule
If the toast is a warning carrying Scheduled discovery is disabled by policy — this was a manual override., the scheduled loop is switched off.
The manual run scans anyway, by design: an administrator who turned the loop off and then asked for a reading meant the reading. A successful run is therefore not proof that the schedule is on.
Note
Pressing the button twice leaves the same rows: assets are upserted on a fingerprint and findings deduplicate per type, asset, tenant and day. It does re-execute the whole scan each time, and it advances the last-run time — which defers the next scheduled run by the configured interval.
What a scan actually looks at
Discovery reads two sources and writes no new telemetry of its own:
- The managed catalogue — active models joined to their providers. Managed by definition, so
they enter as Unregistered until somebody owns them. The key is
<provider>/<model>and the channel is managed chat. - The usage union — the same queries the Shadow-AI usage report runs, so the inventory and that report can never disagree about which app a hostname belongs to. An observed app is configured when it maps to a provider the gateway holds a credential for; otherwise it is Shadow. Models those apps report that are not in the catalogue enter as shadow models.
Hostnames under the reserved test TLDs (.test, .example, .invalid, .localhost) are
excluded so a fixture does not become an asset somebody is asked to own. That is the only hostname
exclusion: an unknown-but-real destination is exactly what shadow-AI discovery is for.
Warning
Discovery never deletes. An asset created from a hostname before an exclusion landed stays in the inventory — decommission it rather than waiting for a scan to remove it.
Tune what discovery looks at
Open the settings
Read Discovery settings, directly under the sub-navigation.
The form is built from the gateway's own description of each key, so every control arrives with its bounds, its default and a one-line explanation of what it does.
Change the values you need
Set the switches and the numbers.
A value outside its bounds is rejected in the form before the request is sent, and the whole patch is all-or-nothing on the gateway: one bad value rejects the request rather than leaving a half-applied policy nobody can see.
Save
Select Save settings.
The toast reads Discovery settings saved — N value(s) changed., or Saved — nothing changed. when the values were already those. The helper line states when it takes effect: Applied on the next scheduled run — no restart.
Warning
Turning Discovery enabled off stops the scheduled loop and nothing else. The Run discovery button still scans, and the form says so in an inline note as soon as you switch it off.
Fields reference
Discovery settings
| Setting | Type | Bounds | Default | Effect |
|---|---|---|---|---|
| Discovery enabled | Switch | — | On | Whether the scheduled loop runs. Does not disable Run discovery |
| Discovery interval minutes | Integer | 5 – 10080 | 60 | Minutes between scheduled runs. A manual run defers the next one. The floor of 5 is the scheduler's own tick |
| Usage lookback days | Integer | 1 – 365 | 30 | How far back the usage union is read. Also the window the who used it list reports over |
| Evidence window | Integer | 1 – 100 | 20 | Observations kept per asset, newest first. Evidence that the asset is real, not a usage series |
| Min observations | Integer | 1 – 10000 | 1 | Requests a subject needs in the lookback window before it enters the inventory. Raise it on a noisy estate |
| Drift enabled | Switch | — | On | Whether the drift pass runs inside each discovery run |
The nine drift thresholds — the window lengths, the sample floors and the four trigger factors — are deliberately not in this form. They are the calibration the module is built around, and putting them beside a toggle would invite tuning them without reading any of it. They are set in the configuration store only.
Estate tiles
| Tile | Counts |
|---|---|
| Assets tracked | Every app, model and destination discovery has seen |
| Ownerless | Assets with no owner email |
| Unclassified | Assets with no declared risk profile |
| Open findings | Findings of every type still open |
Drift: has the estate moved?
The drift pass runs inside every discovery run — there is no second scheduler and no second button — and compares a 28-day baseline against the current 7 days. The baseline ends where the current window opens, so this week cannot dilute the comparator it is judged against.
| Metric | Finding | Fires when |
|---|---|---|
| Intervention rate | Drift intervention drop | The blocked-or-redacted share fell by more than 50% relative to baseline |
| Intervention rate | Drift intervention spike | It rose by more than 50% |
| Sensitive content that reached the model | Drift sensitive allowed | The share is more than twice the baseline |
| Shadow-app breadth | Drift shadow breadth | Distinct shadow apps are more than twice the baseline and more than three apps up |
A drop is a finding, not good news: nothing else in the product alerts when a control quietly stops working, because the absence of detections looks exactly like clean traffic. "Reached the model" means allowed or flagged — a flag is not a control, the content still left the building.
A window with too little data reports insufficient data and produces no finding. A fresh appliance must not manufacture governance gaps out of having no history.
Warning
Drift findings are organisation-wide, and the dashboard shows only their counts. There is no
screen that lists them — read them through GET /admin/governance/findings with a
finding_type of one of the four drift types. Their one-line meanings are also blank on the
overview, because the dashboard's own vocabulary predates them; the name itself still renders.
Verify
- Run a scan. The toast reports non-zero subjects scanned on any appliance that has traffic or an active model catalogue, and the Discovery box's Most recent observation advances.
- Open Event logs and filter for audit events. Registering an asset writes
GOVERNANCE_ASSET_REGISTERED, retiring one writesGOVERNANCE_ASSET_DECOMMISSIONED, saving the settings writesGOVERNANCE_POLICY_UPDATEDlisting what moved, and each newly opened drift finding writesGOVERNANCE_DRIFT_DETECTED. All four are audit-category events kept for 365 days and forwarded to SIEM where that is configured. - An idempotent re-observation writes no event. Running the scan twice on the same day produces one set of rows and one set of events, not two.
If it fails
- Access denied — your role is not admitted to the governance pages.
- A 403 with
FEATURE_NOT_LICENSED— the installed licence does not carry thegovernancecapability. It ships in all three tiers, so this usually means the licence is missing or invalid; see Licensing and activation. - Discovery failed: … — the scan threw. The message is the gateway's own.
- Discovery did not run: … — a scan was already in progress, or the run was refused. The reason is shown verbatim.
- Discovery could not run. — the gateway reported a refusal with no reason. Check the
nestjs-corelogs. - Could not save: … with a 400 naming a key — the settings form sent a name the gateway does not accept. An unknown key is refused rather than written, so it cannot become a stray configuration row.
- Whole number. or Between N and M. under a field — the value is not an integer or is outside its bounds. The gateway would refuse it too; the form is only getting there first.
- Every count reads zero on an appliance that has traffic — check that Min observations is not set higher than your usage, and run a scan.
Next steps
- Governance inventory — the full estate, filtered and searchable, where assets are registered and retired.
- Ownership — everything nobody has claimed, newest sighting first.
- Risk classification — the EU AI Act tiers and the written reason behind each one.
Last updated on