Auditor Workbench + MSP Cockpit
Auditor Workbench (/auditor)
Section titled “Auditor Workbench (/auditor)”POST /api/v1/auditor/bundle with body {period_start, period_end}.
Owner / admin / auditor only. TOTP-gated in production (purpose
auditor_bundle); no TOTP in dev.
Bundle contents (ZIP):
manifest.json bundle metadata + pack list + key listverify.py offline Ed25519 verifier (pynacl-based)signing_keys.json public keys + rotation reasons in periodcompliance_summary.md markdown audit reportevidence_packs/<id>.tar.gz each pack from the period (only from allowlisted storage paths)Path-traversal guard: evidence_packs.storage_uri MUST start with one of:
/var/lib/monsys/ai-evidence-packs//var/lib/monsys/copilot-evidence-packs//var/lib/monsys/openai-evidence-packs/
Otherwise the pack is omitted from the bundle (a row with archive_path:""
remains in manifest.json for traceability).
The download URL is one-shot, 24h expiry. The atomic claim sits in the UPDATE:
UPDATE auditor_bundle_tokens SET downloaded_at = NOW(), downloaded_by = $3 WHERE token = $1 AND tenant_id = $2 AND downloaded_at IS NULL AND expires_at > NOW()RETURNING file_pathPostgres MVCC + row lock guarantees that two concurrent requests do not both receive RETURNING.
Offline verify
Section titled “Offline verify”Each recipient runs python3 verify.py (pynacl) inside the unpacked
bundle. No network, no monsys credentials needed — verifies every pack’s
signature against the bundled signing_keys.json. Output:
pack 1234: OKpack 1235: BAD SIGNATURE=== 12 OK, 1 BAD ===Exit code 0 = all OK, 1 = at least one pack fails.
MSP Cockpit (/msp/cockpit)
Section titled “MSP Cockpit (/msp/cockpit)”GET /api/v1/msp/overview. Strictly fenced: role = msp_operator OR
is_superadmin = true. A normal owner/admin user gets 403 — this
endpoint walks every tenant in the platform.
Per tenant:
- name + plan
- current Trust Score + Δ7d
-
open critical+warning alerts
Section titled “open critical+warning alerts” -
failing compliance evidence rows
Section titled “failing compliance evidence rows” - last login activity
Default sort = urgency composite:
urgency = open_alerts*5 + failing_controls + (-Δ7d if Δ7d < 0) + 0.5 * (60 - score) if score < 60Per-column sort is available from the dashboard (urgency / name / score).
New roles
Section titled “New roles”Migration 064 extends the users.role CHECK with:
| Role | Access |
|---|---|
auditor | read-only + bundle generate/download (TOTP-gated in production) |
msp_operator | cross-tenant via /api/v1/msp/overview |
Existing roles (analyst, admin, owner) unchanged.