Skip to main content
Version: 3.0 (next)

Ad-hoc CSV export — for compliance auditors and one-off pulls

CSV is the format compliance auditors ask for during a SOC 2 or ISO 27001 evidence review: "give me a spreadsheet of every role change to System.Admin in Q3." No SIEM required.

From a browser​

Log into MaestroHub as an admin who holds audit_log:export (Organization.Admin, Security.Admin, Compliance.Auditor, or System.Admin).

Open a URL like:

https://<your-maestro>/api/v1/audit/export
?format=csv
&from=2026-07-01T00:00:00Z
&to=2026-10-01T00:00:00Z
&action=role.assigned

Because format=csv sets a Content-Disposition attachment header, the browser triggers a download named audit-export.csv.

From curl (headless auditors)​

curl -o audit-q3.csv \
-H "Authorization: Bearer $MAESTRO_TOKEN" \
'https://<your-maestro>/api/v1/audit/export?format=csv&from=2026-07-01T00:00:00Z&to=2026-10-01T00:00:00Z'

Column schema​

The CSV emits a header row on the first line. Column order is stable within releases; new columns append to the end so existing spreadsheet-imports keep working.

A large window can span multiple pages (X-Audit-Next-Cursor — see the endpoint overview). The header row travels on the first page only: pages fetched with a cursor are fragments of the same logical document, so append them as-is and the result is one valid CSV with a single header line.

ColumnMeaning
idUUID of the audit record
timestampRFC3339 nano — UTC
actor_id · actor_type · actor_emailWho performed the action
subjectCanonical principal — often user:<uuid>
impersonator_idNon-empty when an admin impersonated
actione.g. role.assigned, user.login
modulee.g. authz, auth, connectors
resource_type · resource_id · resource_nameThe thing acted on
org_idMulti-tenancy pivot
resultsuccess · failure · denied
denial_reasonPopulated only when result=denied
correlation_idOpenTelemetry trace id (blank if pre-UC36)
ip_address · user_agentClient context
severity0–10 (blank rendered as empty cell — Excel doesn't misread "not set" as "not severe")
categoryECS category — iam, authentication, etc.

Filtering during the pull​

Any query param the interactive audit page accepts, the export endpoint accepts too:

  • action=<verb> — e.g. action=role.assigned
  • module=<mod> — e.g. module=authz
  • actor_id=<id>
  • result=denied
  • high_sensitivity_only=true — the D9.2 classifier's "worth attention" subset

Combine with from / to to scope the window.

Anti-siphon guard​

from and to are required — an unbounded request returns 400. This is a deliberate compliance safeguard. If an auditor needs "everything," they run a series of month-sized windows.

Working with the file​

The file is UTF-8, RFC 4180 CSV. Every quoted field is properly quote-escaped. Excel, Sheets, and pandas all read it without transformation.

import pandas as pd

df = pd.read_csv("audit-q3.csv")
df[df["action"] == "role.assigned"].groupby("actor_email").size()