Skip to main content
When your auditor asks for evidence, Reports → Generate audit package outputs a structured archive your auditor can ingest directly. This page documents the format so you can answer “what’s in here?” before the auditor opens it.

Top-level archive contents

audit-export-<framework>-<YYYY-MM-DD>.zip
├── README.txt                       # Cover sheet for the auditor
├── manifest.json                    # Machine-readable index of every file
├── controls/
│   ├── <control-id>/
│   │   ├── status.json              # Current status, last verified, owner
│   │   ├── evidence/
│   │   │   ├── <evidence-id>.json   # Raw API response with timestamp
│   │   │   └── ...
│   │   └── exceptions.md            # Documented exceptions (when applicable)
│   └── ...
├── exports/
│   ├── access-review-<period>.csv   # Per-user app access at the period end
│   ├── terminations-<period>.csv    # HRIS termination → IdP deactivation diffs
│   ├── changes-<period>.csv         # Merged PRs with reviewer + timestamp
│   └── incidents-<period>.csv       # Incident timeline + post-mortem links
└── policies/
    ├── information-security-policy.pdf
    └── ...                          # Linked from connected docs system

Per-control structure

Each control gets a folder named by the control ID (e.g. CC6.1 for SOC 2, A.5.16 for ISO 27001). Inside:

status.json

{
  "control_id": "CC6.1",
  "title": "Logical access provisioning",
  "framework": "SOC 2 (TSC 2017)",
  "status": "met",
  "last_verified": "2026-04-17T10:23:00Z",
  "owner": "alice@axiomancer.io",
  "evidence_count": 47,
  "evidence_period": {
    "start": "2025-10-17T00:00:00Z",
    "end": "2026-04-17T23:59:59Z"
  },
  "auto_evidenced": true,
  "exceptions": []
}

evidence/<evidence-id>.json

Each evidence file is a single observation with full provenance:
{
  "evidence_id": "ev_01HXYZ...",
  "control_id": "CC6.1",
  "type": "user_provisioning_event",
  "source": "google_workspace",
  "source_url": "https://admin.google.com/ac/users/<user_id>",
  "collected_at": "2026-04-17T10:23:01Z",
  "raw_response": {
    "user_id": "12345",
    "email": "newhire@axiomancer.io",
    "creation_time": "2026-04-15T09:00:00Z",
    "created_by": "alice@axiomancer.io",
    "org_unit": "Engineering"
  },
  "summary": "User newhire@axiomancer.io provisioned by alice@axiomancer.io on 2026-04-15"
}
The raw_response field is the auditor’s friend — it’s the actual API response, unmodified, with the timestamp Codex received it. Auditors trust this because it’s not editorialized; if a question comes up about a specific event, the auditor can match the source_url to the live admin console.

exceptions.md

When a control has documented exceptions (e.g. “this user retained access for 48h post-termination because of a contract negotiation”), they’re recorded as Markdown:
# Exceptions for CC6.1

## 2026-03-20 — extended access for departing engineer

User: bob@axiomancer.io
Termination: 2026-03-18 17:00 UTC
Deactivation: 2026-03-20 22:00 UTC (53h gap)
SLA: 24h (failed by 29h)

Justification: Engineer was retained as contractor for knowledge
transfer on a customer escalation. Bob's account was demoted to
read-only on 2026-03-18 17:30 (within SLA) and fully deactivated
after the contract concluded.

Approved by: charlie@axiomancer.io (security lead) on 2026-03-19.
Risk acceptance: bob's read-only access was monitored via
Datadog event log; no anomalous activity observed.

Aggregate exports (exports/)

These are CSVs the auditor can open in Excel/Sheets to scan for patterns. Common asks:
FileWhat’s in it
access-review-<period>.csvOne row per (user, app) — current role, last activity, last review date
terminations-<period>.csvOne row per termination — HRIS event, IdP deactivation, gap, exceptions
changes-<period>.csvOne row per merged PR — repo, author, reviewers, merge time, deployed-to-prod time
incidents-<period>.csvOne row per incident — severity, detected, acknowledged, resolved, post-mortem URL
vulnerabilities-<period>.csvOne row per finding — source, severity, discovered, triaged, resolved, SLA met (Y/N)

Manifest

manifest.json is the machine-readable index. Useful when the auditor uses a tool that ingests structured evidence (some now do — common in SOC 2 firms with audit-tech investments):
{
  "framework": "SOC 2 Type II",
  "generated_at": "2026-04-17T10:23:00Z",
  "evidence_period": { "start": "...", "end": "..." },
  "controls_total": 64,
  "controls_met": 58,
  "controls_partial": 4,
  "controls_missing": 2,
  "controls": [
    {
      "control_id": "CC6.1",
      "status": "met",
      "evidence_count": 47,
      "evidence_files": ["controls/CC6.1/evidence/ev_01HXYZ...", "..."]
    }
  ]
}

Format choices auditors notice

A few decisions Codex makes that auditors call out positively:
  1. No PDF-only artifacts — every control has both human-readable status AND machine-readable JSON. Auditors can grep, filter, and aggregate.
  2. Every evidence has a timestamp from Codex’s collection — not “we generated this in March.” If the auditor questions a specific date, Codex’s collection time is the timestamp of record.
  3. Source links are deep URLs into the source admin console — the auditor can open Codex’s evidence and Google Workspace side by side to verify.
  4. Exceptions are first-class — Codex doesn’t hide failed controls, it surfaces them with documented justification. Auditors prefer companies that admit gaps (and remediate) over companies that paper over them.

What’s NOT in the export

  • Source documents — your PDFs, contracts, BAA documents are linked from policies/ or controls/<id>/exceptions.md but not duplicated. Auditors get separate read-only access to those source systems.
  • Personal data — user names + emails are included where they’re material to the control (e.g. who did what, when). Customer PII is never included unless it’s specifically the audit subject.
  • Source code — repo metadata (author, reviewer, merge time) is included; source code itself is not.