Skip to content

security

Intended Documentation

Audit Export

Build, list, and download tenant audit evidence bundles — how the artifact is assembled, exactly how it is signed (HMAC with a server-held secret, not asymmetric), and how to verify it.

Audit Export#

Audit export turns a tenant's runtime history into a single, integrity-protected evidence artifact you can hand to an auditor. An export is a job: you create it with a filter, the platform assembles a canonical JSON summary of the tenant's authority actions, approvals, tokens, gateway and connector enforcement events, policy lifecycle, audit entries, and (optionally) anomalies and recommendations, then digests and signs it.

What an evidence export is — and is not

The export is a scoped, integrity-stamped snapshot of governance and runtime records for a tenant and time window. It demonstrates the mechanisms an auditor cares about — immutable hash-chained audit entries, signed authority decisions, single-use tokens, enforcement lineage. It does not assert SOC 2 / ISO / EU AI Act compliance and contains no certified control-ID mappings; the platform encodes none.

Authorization#

Creating an export requires the enterprise permission evidence:export (owner, admin, auditor). Listing and downloading exports require audit:read (every enterprise role). All endpoints are tenant-scoped — x-tenant-id, the body/query tenantId, and the credential's tenant must agree, or the call is rejected with 403 TENANT_MISMATCH.

Create an export job#

POST/admin/audit-exportsRequires auth

Builds an evidence bundle for the tenant. The job runs synchronously: a successful call returns a completed record (or a failed record with errorMessage if assembly fails). Responds 201 Created. Requires evidence:export.

tenantIdstring*Tenant identifier; must match credential and x-tenant-id.
environmentKeystringRestrict to one environment. Records without explicit environment classification are excluded (and production scope excludes unknown-environment records to avoid overclaiming).
includeAnomaliesbooleanInclude open anomaly records. Default true.
includeRecommendationsbooleanInclude open recommendation records. Default true.
fromstring (ISO 8601)Lower bound on event time.
tostring (ISO 8601)Upper bound on event time.
bash
curl -X POST https://api.intended.so/admin/audit-exports \
  -H "Authorization: Bearer $INTENDED_API_KEY" \
  -H "x-tenant-id: tenant_acme_prod" \
  -H "Content-Type: application/json" \
  -d '{
    "tenantId": "tenant_acme_prod",
    "from": "2026-05-01T00:00:00Z",
    "to": "2026-06-01T00:00:00Z",
    "includeAnomalies": true,
    "includeRecommendations": true
  }'
# 201 → { "id": "exp_…", "status": "completed", "artifactDigest": "...", "artifactSignature": "...", ... }

An export record contains: id, status (queued · processing · completed · failed), requestedBy, environmentKey, the filters applied, an evidenceSummary (counts and reference links for each record class), artifactUri, artifactDigest, artifactSignature, errorMessage, and timestamps (createdAt, updatedAt, completedAt).

List and fetch exports#

GET/admin/audit-exportsRequires auth

Lists the tenant's most recent exports. Requires audit:read.

tenantIdstring*Tenant identifier.
GET/admin/audit-exports/:idRequires auth

Returns a single export record. Requires audit:read. Returns 404 AUDIT_EXPORT_NOT_FOUND if it does not exist in the tenant.

idstring*Export id (path).
tenantIdstring*Tenant identifier (query).
GET/admin/audit-exports/:id/downloadRequires auth

Streams the completed artifact as application/json, with integrity headers. Requires audit:read. Returns 404 AUDIT_EXPORT_ARTIFACT_NOT_READY until the export has status: completed.

idstring*Export id (path).
tenantIdstring*Tenant identifier (query).
bash
curl -OJ "https://api.intended.so/admin/audit-exports/exp_123/download?tenantId=tenant_acme_prod" \
  -H "Authorization: Bearer $INTENDED_API_KEY" \
  -H "x-tenant-id: tenant_acme_prod"
# Response headers include:
#   x-intended-artifact-digest:    <sha256 over the canonical artifact>
#   x-intended-artifact-signature: <HMAC-SHA256 over the same canonical artifact>
#   content-disposition: attachment; filename="intended-audit-export-exp_123.json"

How integrity is established#

The platform serializes the artifact with a deterministic, key-sorted canonicalization, then computes two values over that exact byte sequence:

  • artifactDigest — a SHA-256 hash. Anyone can recompute it by canonicalizing the downloaded JSON the same way and hashing it; this detects accidental corruption or tampering.
  • artifactSignature — an HMAC-SHA256 keyed by a server-held signing secret (INTENDED_AUDIT_EXPORT_SIGNING_SECRET).

The signature is symmetric, not a public-key signature

artifactSignature is an HMAC computed with a secret held by the platform. It is not an asymmetric (RSA/EC) signature and is not independently verifiable by a third party who does not hold that secret. An external auditor can fully re-verify the artifactDigest (it is just a hash of the artifact), but verifying the signature requires possession of the signing secret. Do not describe these exports as "publicly verifiable" or "non-repudiable via public key" — they are integrity-stamped with a keyed MAC.

To independently check an artifact you received: canonicalize it with key-sorted JSON, SHA-256 the result, and compare with the x-intended-artifact-digest header (or the artifactDigest field). A match confirms the bytes are intact and unmodified since export.

Underlying audit substrate

The records summarized in an export sit on top of the per-tenant, SHA-256 hash-chained audit log (AuditEntry), where each entry links to the previous entry's hash so any insertion, deletion, or edit breaks the chain. That chain is what makes the underlying evidence tamper-evident, independent of how the export artifact itself is stamped.

Failure modes#

StatusCodeCause
400INVALID_ADMIN_AUDIT_EXPORT_CREATE_REQUESTMalformed body or invalid date range
401UNAUTHENTICATED_ACTORNo resolvable actor on the request
403TENANT_MISMATCHx-tenant-id ≠ body/query tenantId
403FORBIDDEN (+ permission: "evidence:export" or "audit:read")Role lacks the required permission
404AUDIT_EXPORT_NOT_FOUNDNo such export in this tenant
404AUDIT_EXPORT_ARTIFACT_NOT_READYExport exists but is not completed

Next Steps#

Audit Export | Intended