Auditor — evidence ophalen en verifiëren
Deze pagina veronderstelt dat de auditor een eigen account heeft in
/auditor met read-only scope. De cliënt geeft géén shell-access en
géén dashboard-admin — alle evidence is signed en offline verifieerbaar.
1. Kwartaalaudit NIS2 — wat heb ik
In het dashboard
- Login als auditor in /auditor → Sidebar → Audit Packs
- Download .jsonl.gz + .pdf + .sig voor de maand
- Klik ‘Download verify-CLI’ om de offline verifier op te halen
- Run CLI tegen pubkey — krijgt vier groene checkmarks
Open /audit-packs. Je ziet één rij per maand voor de gekozen tenant.
Download:
2026-04.jsonl.gz— alle ruwe events (machine-leesbaar)2026-04.pdf— human-readable rapport, 12-15 pagina’s2026-04.sig— Ed25519-handtekening overmanifest_hash
Verifieer lokaal (geen netwerk-roundtrip naar monsys):
Of via API (geavanceerd — voor automatisering)
wget https://get.monsys.ai/monsys-verify-eat-linux-x64chmod +x monsys-verify-eat-linux-x64./monsys-verify-eat-linux-x64 verify-pack \ --pack 2026-04.jsonl.gz \ --sig 2026-04.sig \ --pubkey https://transparency.monsys.ai/pubkeys/hub.pubWat de CLI checkt:
- Berekent
manifest_hash = sha256(manifest)— moet matchen met.sig-inhoud - Loopt door elke regel in JSONL.gz, ketent sha256 → moet eindigen op
hash_chain_rootin de manifest - Verifieert Ed25519-signature met de gepubliceerde hub-pubkey
Output bij succes:
✓ manifest_hash matches signature✓ hash chain root matches manifest✓ Ed25519 signature valid against pubkey 7c34a9e2b1f0…✓ 1247 entries in pack, 0 tampered2. Bewijs dat CVE-2026-XXXX binnen 7 dagen gepatched is
In het dashboard
- Sidebar → Kernel CVE’s → zoek CVE-2026-XXXX
- Tab ‘Tijdlijn’ toont per host: detected, patched, operator
- Filter ‘Time to patch > 7 days’ isoleert SLA-breaches
- Knop ‘Export voor audit’ → CSV met alle kolommen
Drie vragen voor de auditor:
- Wanneer is de CVE eerst gedetecteerd?
- Wanneer is hij gepatched per host?
- Wie heeft de actie uitgevoerd?
In één SQL-rapport:
Of via API (geavanceerd — voor automatisering)
WITH first_detected AS ( SELECT agent_id, MIN(detected_at) AS first_seen FROM kernel_cve_findings WHERE tenant_id = $1::UUID AND cve_id = 'CVE-2026-XXXX' GROUP BY agent_id),patched AS ( SELECT r.agent_id, MIN(r.boot_time) AS rebooted_at, r.eat_id FROM kernel_reboot_history r JOIN first_detected fd ON fd.agent_id = r.agent_id WHERE r.tenant_id = $1::UUID AND r.expected = true AND r.boot_time > fd.first_seen GROUP BY r.agent_id, r.eat_id)SELECT a.hostname, fd.first_seen, p.rebooted_at, p.rebooted_at - fd.first_seen AS time_to_patch, u.email AS operator FROM first_detected fd LEFT JOIN patched p ON p.agent_id = fd.agent_id LEFT JOIN agents a ON a.id = fd.agent_id LEFT JOIN emergency_tokens et ON et.id = p.eat_id LEFT JOIN users u ON u.id = et.user_id ORDER BY time_to_patch NULLS FIRST;Een rij met time_to_patch IS NULL = host nog niet gepatched. Een rij
met operator IS NULL = reboot was niet EAT-driven (manueel) — minder
robuust evidence, maar wel een rij in kernel_reboot_history met
expected=false.
3. Geef me elke privileged actie van laatste kwartaal
In het dashboard
- Sidebar → Audit log (onder MANAGE)
- Filter: event_type = emergency_token_issued + datum-range Q1
- Per rij: operator, target, actions JSON, exit_code
- Knop ‘Verify in transparency log’ opent externe verifier per nonce
Of via API (geavanceerd — voor automatisering)
SELECT et.issued_at, u.email AS operator, a.hostname AS target, et.level AS escalation, et.actions::TEXT AS actions, et.reason AS reason, (et.result->>'exit_code')::INT AS exit_code FROM emergency_tokens et LEFT JOIN users u ON u.id = et.user_id LEFT JOIN agents a ON a.id = et.agent_id WHERE et.tenant_id = $1::UUID AND et.issued_at >= '2026-01-01' AND et.issued_at < '2026-04-01' ORDER BY et.issued_at DESC;Voor offline verificatie: elke nonce zit in de transparency log.
Auditor kan onafhankelijk valideren:
./monsys-verify-eat-linux-x64 verify-eat \ --nonce 7a3c… \ --log-endpoint https://transparency.monsys.ai/api/v1/transparency-log/entry \ --pubkey https://transparency.monsys.ai/pubkeys/hub.pub→ Bevestigt dat het EAT door de legitieme hub-key is uitgegeven én dat de log-entry niet retroactief gemanipuleerd is (hash-chain verify).
4. Welke NIS2/CRA-controls vallen tekort
In het dashboard
- Sidebar → Compliance → kies framework NIS2
- Matrix toont per control: coverage + evidence count + reviewed status
- Filter op reviewed_status=‘draft’ om openstaande review-werk te zien
- Knop ‘Export as CSV’ voor je kwartaalrapport
/compliance/NIS2 toont een matrix:
| Control | Coverage | Evidence count | Reviewed |
|---|---|---|---|
| NIS2-Art21-2-a | automatic | 247 | ✓ |
| NIS2-Art21-2-b | partial | 12 | draft |
| NIS2-Art21-2-c | manual | 0 | draft |
| … |
coverage_level=automatic = monsys voert de evidence query elke nacht
uit en stort het resultaat in compliance_evidence. partial = deels
geautomatiseerd, deels manuele attestatie. manual = enkel een tekstveld
voor menselijke verklaring.
reviewed_status='draft' betekent: nog niet juridisch gevalideerd. Tot
deze flag op reviewed staat én COMPLIANCE_PRODUCTION=1 is gezet op
de hub, krijg je in de PDF een waarschuwingsbanner “draft mapping — not
suitable for legal claims”.
Voor het kwartaalrapport download je deze matrix als CSV via:
Of via API (geavanceerd — voor automatisering)
curl 'https://app.monsys.ai/api/v1/compliance/coverage?framework=NIS2&format=csv' \ -H "Authorization: Bearer $TOKEN" > nis2-coverage-2026-Q1.csv5. Verifieer cryptografische integriteit van één specifieke evidence-rij
In het dashboard
- Sidebar → Audit Packs → kies de maand
- Klik ‘Tamper check’ knop in download view
- Paste de verdachte JSONL regel + lijnnummer
- UI toont expected vs computed hash + verdict
Stel de auditor twijfelt of regel #847 in 2026-04.jsonl.gz echt zo
geregistreerd was, of dat de operator hem achteraf heeft aangepast.
Of via API (geavanceerd — voor automatisering)
zcat 2026-04.jsonl.gz | sed -n '847p' > suspicious-line.jsonsha256sum suspicious-line.json# 7c34a9e2b1f0…Vergelijk met de hash_chain in de manifest — elke regel in JSONL
voegt zijn sha256 toe aan de keten:
zcat 2026-04.jsonl.gz | ./monsys-verify-eat-linux-x64 chain-position --line 847# expected_position: 7c34a9e2b1f0…# computed_position: 7c34a9e2b1f0…# ✓ line 847 matches the chainMismatch = bewijs van retroactieve manipulatie. Geen mismatch = de
regel is identiek aan toen hij geschreven werd op signed_at.
6. Welke users hebben admin-rechten over alle systemen
In het dashboard
- Sidebar → RBAC → tab ‘Admin overzicht’
- Per user: alle hosts + EATs uitgevoerd laatste 90d
- Sorteer op eats_last_90d ascending — admins die nooit gebruiken
- Klik ‘Downgrade to editor’ voor least-privilege oprationalisatie
Of via API (geavanceerd — voor automatisering)
SELECT u.email, ARRAY_AGG(DISTINCT a.hostname) FILTER (WHERE a.hostname IS NOT NULL) AS hosts, ARRAY_AGG(DISTINCT iu.username) AS local_users, COUNT(DISTINCT et.id) AS eats_last_90d FROM users u LEFT JOIN role_assignments r ON r.user_id = u.id LEFT JOIN inventory_users iu ON iu.email = u.email -- explicit link, no auto-correlate LEFT JOIN agents a ON a.id = iu.agent_id LEFT JOIN emergency_tokens et ON et.user_id = u.id AND et.issued_at >= NOW() - INTERVAL '90 days' WHERE u.tenant_id = $1::UUID AND r.role = 'admin' GROUP BY u.email ORDER BY eats_last_90d DESC NULLS LAST;Wat je hieruit ziet:
- Admins die nooit EAT hebben uitgevoerd → kandidaat voor downgrade
- Admins op meer hosts dan strikt nodig → minimal-privilege check
- Admins zonder lokale-user-link → enkel dashboard, geen shell
7. Backup-evidence per host laatste 90 dagen
In het dashboard
- Sidebar → Inventaris → tab Backups → filter tag ‘production’
- Per host: successful_runs_90d + failed_runs_90d
- Sorteer ascending op successful — 0 op prod = audit finding
- Klik ‘Export evidence’ voor je ISO 27001 A.8.13 rapport
Of via API (geavanceerd — voor automatisering)
SELECT a.hostname, b.tool, b.destination, b.last_successful_run, (SELECT COUNT(*) FROM backup_inventory bi WHERE bi.agent_id = b.agent_id AND bi.run_at >= NOW() - INTERVAL '90 days' AND bi.success = true) AS successful_runs_90d, (SELECT COUNT(*) FROM backup_inventory bi WHERE bi.agent_id = b.agent_id AND bi.run_at >= NOW() - INTERVAL '90 days' AND bi.success = false) AS failed_runs_90d FROM backup_configs b JOIN agents a ON a.id = b.agent_id WHERE b.tenant_id = $1::UUID AND 'production' = ANY(a.tags) ORDER BY successful_runs_90d ASC;successful_runs_90d = 0 op een prod-host is een audit-finding (ISO
27001 A.8.13 / NIS2 §2(c) business continuity).
8. Retention check — hoe lang houden we evidence
In het dashboard
- Sidebar → Trust Score → component ‘Evidence continuity’
- Tabel toont per evidence-tabel oudste rij + nieuwste
- Direct visueel: groen >12m, rood <12m (NIS2 minimum)
- Klik rode rij → details + remediation suggesties
Of via API (geavanceerd — voor automatisering)
SELECT 'audit_log' AS table_name, MIN(created_at) AS oldest, MAX(created_at) AS newest, COUNT(*) AS rows FROM audit_log WHERE tenant_id=$1::UUIDUNION ALLSELECT 'emergency_tokens', MIN(issued_at), MAX(issued_at), COUNT(*) FROM emergency_tokens WHERE tenant_id=$1::UUIDUNION ALLSELECT 'transparency_log', MIN(appended_at), MAX(appended_at), COUNT(*) FROM transparency_log WHERE tenant_id=$1::UUIDUNION ALLSELECT 'audit_packs', MIN(month_start), MAX(month_start), COUNT(*) FROM audit_packs WHERE tenant_id=$1::UUID;NIS2 vereist (interpretatie van de Belgische omzetting): minimum 12
maanden voor audit-evidence. Trust Score evidence_continuity-component
straft tenants af die <12 maanden continuum hebben — die zie je terug
in /trust-score/v12/tenant.