Skip to main content
Your progress
0 of 7 complete0%
T1 / M1.6 / L6 OF 6 / Operator LEVEL / 11 min

Where audit logs live and how to query them

Outcome

By the end of this lesson, you will be able to query the audit log for specific events and explain what is captured in request and response bodies.


PrerequisitesL1-L4
Time11 minutes

1. Concept

The audit log is the complete record of every action in ZopNight that changed anything.

Every request that creates, updates or deletes is captured on the way through, with both what was asked for and what came back. Entries appear immediately, kept separately per organisation, and are written to permanent storage every minute.

Three things rest on it: the evidence a SOC 2 or ISO 27001 audit asks for, answering “who did this”, and piecing together what happened after the fact.

What gets logged

Terminal window
EVENT CLASS LOGGED? BODY CAPTURED?
─────────────────────────────────────────────────────────────────────
Schedule created / updated / deleted Yes Yes
Override applied / cancelled Yes Yes
Auto-remediation triggered Yes Yes
Manual start / stop Yes Yes
Group created / updated / member changed Yes Yes
Resource attached / detached from schedule Yes Yes
Cloud account connected / updated / deleted Yes No (whole body dropped)
Notification channel changed Yes No (whole body dropped)
RBAC role / policy changed Yes Yes
SAML / OAuth config changed Yes Yes
Dashboard mutations Yes Yes
MCP tool call, read or write Yes Request only for reads
Discovery sync run (success/failure) No N/A
REST read operations (GET) No N/A

Every mutation is captured. REST reads are not (the volume would be enormous and read access is already restricted by RBAC). MCP is the exception: every MCP tool call is audited, reads included, with source mcp, so you can see exactly what an assistant looked at and did. Discovery syncs are background jobs, not API requests, so they do not appear here.

What the log entry looks like

Terminal window
AUDIT LOG ENTRY
─────────────────────────────────────────────────────────
Timestamp: 2026-05-19 14:23:47 UTC
Org ID: org_abc123
User: jane@zopcloud.com (api_key_xxx)
Method: POST
Path: /orgs/org_abc123/overrides
Status: 201 Created
Latency: 87ms
REQUEST BODY:
{
"resourceUid": "i-0abc123",
"targetName": "demo-api-1",
"action": "force_on",
"reason": "Acme Corp demo Sat 2pm",
"expiresAt": "2026-05-26T08:00:00Z"
}
RESPONSE BODY:
{
"id": "ov_5678",
"status": "active",
"created_at": "2026-05-19T14:23:47Z"
}

The audit log is rich enough to reconstruct any past mutation. The request body shows what the user asked for; the response shows what ZopNight returned. Both together pinpoint the exact event.

Sensitive data redaction

Secrets are kept out of storage in two ways:

Terminal window
WHERE THE SECRET IS WHAT IS STORED
─────────────────────────────────────────────────────────
REST calls under cloud-accounts, connect, The row (who, when, path,
integrations, ai, app-secrets, basic-auth, status), with NO body at all
and notifications/channels
MCP tool calls The body, with each secret
field replaced by [REDACTED]

REST has no per-field list of which values are secret, so for those paths the whole body is dropped. MCP tools declare their secret fields, so only those values are replaced, except that an MCP call that touches one of the paths above has its whole body dropped too, just like REST. That is why a notification channel’s Slack token, signing secret or webhook URL never reaches the audit log: the request and the response are both left out. One thing is NOT masked: the user’s email is stored in full. Treat access to the audit log accordingly.

The redaction is at storage time, not at view time. There is no way to retrieve a dropped or redacted value through the audit log.

Querying the audit log

The Audit Log page exposes filters:

Terminal window
FILTERS
─────────────────────────────────────────────────────────
Time range: [Last 7 days ▾] or custom range
Method: [Any ▾] POST / PUT / PATCH / DELETE
Resource: [Any path ▾] /schedules /overrides /resources etc.
Status: [Any ▾] success / failure
User: [Any user ▾]
Source: [Any ▾] ui / api / mcp
Search: [free-text] searches request and response bodies
Sort by: Timestamp (default), latency, status

A typical query: “all override creations by jane@zopcloud.com in the last 30 days”: three filters, results in seconds.

Server-side filtering and pagination

Audit logs are large at scale. The Audit Log page uses server-side filtering and numbered pages, with a page-size selector.

For programmatic access:

Terminal window
# Pull last 7 days of override events to JSON
curl -s "https://api.zop.dev/audit-logs?method=POST&resource=overrides&startDate=2026-05-13&endDate=2026-05-20&page=1&size=50" \
-H "Authorization: Bearer ${PAT}" \
> overrides_last_week.json

The same query that the UI runs is available as an API call. Useful for exporting to SIEM, building custom dashboards, or audit evidence collection.

Common query patterns

Terminal window
PATTERN 1: "Who created this schedule?"
Filter: method=POST, resource=schedules, search=business-hours-eu
Returns: the create event with user, timestamp, full request body.
PATTERN 2: "All overrides in the last quarter"
Filter: method=POST, resource=overrides, startDate=2026-02-01,
endDate=2026-04-30
Returns: list of all override creations with reason, expiry, target.
PATTERN 3: "Failed actions from yesterday"
Filter: status=failed, startDate=2026-05-19, endDate=2026-05-20
Returns: every mutating call that returned an error. Useful for debugging.
PATTERN 4: "Changes to roles"
Filter: resource=roles, method=POST,PUT,PATCH,DELETE
Returns: every role create, edit and delete. Audit-relevant.

The audit log is a relational queryable surface. The right query gives the right answer in seconds.

Compliance use

For SOC 2 / ISO 27001 audits, the audit log produces evidence:

Terminal window
AUDITOR QUESTION EVIDENCE FROM AUDIT LOG
─────────────────────────────────────────────────────────────────────
"Who can create overrides?" Query: all override creations
last 12 months. List of users.
"How are SAML config changes controlled?" Query: SAML config mutations.
Show: which users (Admin only).
"How do you track who started/stopped Query: manual start/stop events.
production resources?" User, timestamp, justification.
"What's your auditable history of Query: rotation events for
credential rotations?" cloud accounts. Show monthly.
"Show me 3 examples of approval-gated Query: auto-remediation events
changes." with approval. Random sample.

Every question maps to a query. Every query returns reproducible evidence. The auditor can run the same queries (with appropriate access) and verify.

Export and long-term retention

Terminal window
STEP WHAT HAPPENS
─────────────────────────────────────────────────────────
Filter Narrow the Audit Logs page to the window and actions you need
Export Start a CSV export of the filtered view
export.ready When the export finishes, this notification carries a
signed download link (it is also emailed)
Archive Store the CSV in your own archive

There is no built-in export to S3 or GCS and no customer-facing event stream. If a regulation asks for years of retention, keep the CSV exports in storage you control. Redis Streams are internal transport only: entries are written there first and synced to the database every minute.

Performance

The Redis Streams + MySQL design balances real-time visibility with durable storage:

Terminal window
WRITE LATENCY <10ms (Redis Stream)
SYNC TO MySQL Every 60 seconds
QUERY LATENCY (UI) <100ms typical
QUERY LATENCY (API) <500ms with pagination
DATA SIZE Mid-size org: ~50 MB/month, ~600 MB/year

At scale (1,000+ resources, 10,000+ schedule firings per day), the audit log volume grows but stays queryable. Server-side filtering avoids full-table scans.


2. Demo

A compliance audit walked through:

Terminal window
SECURITY ASKS: "How do you control who can rotate cloud account
credentials? Show me last quarter's rotations."
T+0 Auditor opens the Audit Log page.
T+30 sec Filter:
path under /cloud-accounts
method = POST
from = 2026-02-01
to = 2026-04-30
T+45 sec Result: 7 rotation events in the period.
T+1 min For each event:
- User who initiated (Admin in all cases: RBAC enforced)
- Cloud account rotated
- Timestamp
- Success status
T+2 min Click into one event. There is no body: calls under
/cloud-accounts never store one, so a credential cannot leak
here. The row's user, path, status and timestamp are the evidence.
T+3 min Auditor copies the URL of the filtered view + screenshot of the
7 events. Adds to compliance evidence package.
T+5 min Compliance evidence collected. Auditor satisfied: rotations are
Admin-only, audit-logged, with full body context.

Five minutes to produce audit evidence that would take hours from raw logs.


3. Hands-on (7 min)

Terminal window
1. Open the Audit Log page.
2. Filter to the last 7 days, method=POST.
3. Browse the events: note the diversity of paths (schedules, overrides,
resources, etc.).
4. Click into one event. Read the request and response body.
5. Try a more specific filter:
- Filter to your own user (or a sample user)
- See all your recent mutations
6. Use the search field to find a specific event by name (e.g., search
for a schedule name).
7. For audit prep: try to answer "Who modified the RBAC role 'Editor'
in the last 90 days?" via filters.
If the answer is "no one": that's also useful evidence (no
unauthorized RBAC changes).

4. Knowledge check

Q1

The Audit Log captures:

A. All of the actions, including every single one of the read calls that are made
B. Only critical actions
C. Only failed actions
D. All mutating API calls (POST, PUT, PATCH, DELETE) with bodies, plus every MCP tool call

Show answer

Correct: D. REST reads (GET) are not logged (volume too high, read access already RBAC-restricted). MCP tool calls are the exception: they are audited, reads included, with source mcp. Discovery syncs are not API calls and are not logged.

Q2

A REST request to connect a cloud account carries a credential in its body. The audit log stores:

A. The full credential value
B. The credential, encrypted
C. The request row (who, when, path, status) with the body omitted
D. The body, with [REDACTED] written into the credential field only

Show answer

Correct: C. Calls under the cloud-accounts prefix never have their body stored, because REST has no per-field list of secrets and dropping the body is the only fail-closed choice. Field-level [REDACTED] is what MCP tool calls get. Either way the credential never reaches the log.

Q3

A SOC 2 auditor asks: “Show me three examples of approval-gated auto-remediations from last quarter.” The Audit Log approach is:

A. Manually inspect every single event in the whole of the log and then build the evidence pack by hand
B. Filter: path matches auto-remediation, method=POST, body contains approval reference, date range = last quarter
C. Generate a custom report
D. Wait for the next audit

Show answer

Correct: B. Return random sample of 3. The query produces reproducible evidence in seconds. Filter-based queries are the canonical way to produce audit evidence. Reproducible (auditor can re-run) and fast (seconds to results).


5. Apply

The audit log surface:

  • Audit Logs page: filterable, paginated UI
  • Audit API: same data, programmatic access
  • CSV export: export the filtered view; the export.ready notification carries the download link. Store exports in your own archive for long-term retention

For deeper coverage of audit-as-evidence patterns, see the Architect track’s audit logging module.


Module quiz

You have now completed all six lessons of M1.6. Take the module quiz: 10 questions, 80% to pass.


What’s next

M1.7: Red Hat OpenShift (ROSA). After it comes M1.8, the capstone.


Glossary terms touched

Audit log · Redaction


Start with the bill.

Foundations takes about five hours. The first lesson is nine minutes.

Free curriculum. No paywall. 290 lessons across 7 courses, plus an optional 24-lesson beginner course. Browse every course without an account; a free account opens the lessons, saves your progress and opens the exams for three publicly verifiable credentials. Read it on the train, take the exam on a Saturday, list the credential on your résumé Monday.

5h median time to finish Foundations
free account, every course, no paywall
3 certifications, each with a public verifier
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·