Operations

Evidence Vault

The system of record for compliance evidence. Every policy decision, HITL approval, DLP finding, and CI/CD run is captured as an immutable, signed, hash-chained event — queryable across all frameworks from a single store. No cloud required.

Core principle: the vault has exactly one write path (append a new EvidenceEvent) and many read paths. There is no update or delete on an event. Current state — like whether a HITL request is still pending — is always computed by reading the append-only log.

Architecture

Evidence Vault v2 is an event-sourced ledger applied to compliance evidence. Tamper-evidence is an architectural property, not a policy checkbox.

Where data lives

FileContents
~/.iris/evidence/<agent_id>/events.jsonlLegacy runtime log (policy evaluations, violations)
~/.iris/evidence/<agent_id>/evidence_events.jsonlv2 append-only signed event log (system of record)
~/.iris/evidence/<agent_id>/control_mappings.jsonlEvent → control many-to-many index
~/.iris/evidence/<agent_id>/assessments.jsonlImpact assessments (never pruned)

Override the root with --vault-dir on CLI commands or set a custom path in SDK integrations.

Event types

Each event type has a strict payload schema — unknown fields are rejected at write time.

event_typeWhen it fires
cedar_decisionEvery Cedar policy evaluation (PERMIT / BLOCK / HITL)
hitl_requestedHuman review queue opened
hitl_resolvedReview approved, rejected, or timed out
dlp_findingSSN, PHI, credit card, or prompt-injection detected
drift_detectedPolicy intent vs compiled Cedar drift
agent_registeredAgent passport created or updated
policy_compiledIntent compiled to Cedar in CI or locally
rotation_eventAPI key or secret rotation
org_policy_changediris-security.yaml or org policy repo change
cicd_runPipeline run recorded from CI/CD (see below)
event_expiredTombstone when retention elapses or erasure completes

Payloads never contain raw prompt content — only hashed identifiers (user_id_hash, rule IDs, metadata). pii_redacted is always true.

CLI commands

Record CI/CD evidence

Write a signed cicd_run event from any pipeline. Runs even when the governance gate failed — a failed check is evidence.

iris evidence record-cicd \
  --system github_actions \
  --run-id "${{ github.run_id }}" \
  --pipeline-url "https://github.com/org/repo/actions/runs/123" \
  --triggered-by "developer@company.com" \
  --outcome success

Supported --system values: github_actions, gitlab, jenkins, terraform, argocd. Returns signed event_id and sequence_number as JSON.

Audit reports

iris evidence report --agent loan-processor
iris evidence report --agent loan-processor --format markdown
iris evidence report --agent loan-processor --since 2026-01-01

Includes passport snapshot, compliance status, violation summary, retention window, and integrity check — ready for regulatory review.

List and export

iris evidence list --agent loan-processor
iris evidence list --agent loan-processor --violations-only
iris evidence query --decision deny
iris evidence query --agent loan-processor --regulation AIUC-1 --risk-min 70
iris evidence export --agent loan-processor --output audit.json
iris evidence export --agent loan-processor --output aiuc1.json --format aiuc1
iris evidence stats

evidence query is the signal command — filter by agent, decision, regulation, date range, and risk instead of scrolling the full vault. Export formats: json, csv, aiuc1, pdf, oscal. The aiuc1 format pulls from the same ControlMapping table as iris certify --format aiuc1-export — one code path, not a separate scan.

GDPR erasure

iris vault redact --agent loan-processor --user-id <id>

Erasure writes a tombstone event and scrubs user-identifying payload fields while preserving control mappings (so "we satisfied CO-004 on this date" remains provable).

Evidence lifecycle

  1. Capture — governed action writes exactly one signed EvidenceEvent. The only stage where new facts enter the vault.
  2. Index — async, non-blocking. Updates ControlMapping and chain views. Index failure does not lose the event — call rebuild_from_events() to recover.
  3. Query — read-only. Reports, iris certify, AIUC-1 export, and auditor packages operate here. Unscoped queries above 500 events are rejected.
  4. Retention check — daily job marks events past eligible_for_deletion_at. Legal holds skip deletion and log a retention_extended event.
  5. Disposition — expired events get an event_expired tombstone; payload is scrubbed but the hash chain and timeline remain gap-free.

Retention model

When an event satisfies multiple controls, retention takes max() across all attached requirements — never the shortest period.

ControlFrameworkDays
CO-RR-001Colorado AI Act1095 (3 years)
LL144-005NYC Local Law 144730 (2 years)
PIPL-006China PIPL1095 (3 years)
CCPA-006CCPA/CPRA ADMT1095 (3 years)
HIPAA-001HIPAA (general)2190 (6 years)
FEDRAMP-CONMONFedRAMP1095 minimum
AIUC-1AIUC-1365 minimum (annual recert cadence)
unmapped365 default (never 0)

Free tier prunes legacy events.jsonl after 30 days. Pro unlocks unlimited retention for long-horizon controls like HIPAA and Colorado's 3-year requirement.

Integrity verification

Every event is HMAC-signed over event_id + sequence_number + payload_hash + prev_event_hash. Tampering with event N breaks the chain for every subsequent event.

iris evidence report --agent loan-processor
# Integrity section shows hash chain status

# Programmatic check (Evidence Vault API):
GET /v1/agents/<agent_id>/integrity
# → {"valid": true, "events_checked": N}
# or {"valid": false, "first_broken_link": "<event_id>"}

Query responses include a signed integrity proof (query_signature) so callers can prove they received exactly the result set returned.

Query API

Hosted and Enterprise deployments expose a read-heavy REST API. There is exactly one write endpoint and no DELETE or PATCH on events.

MethodEndpointPurpose
POST/v1/eventsAppend one event (server signs — client signatures ignored)
GET/v1/agents/:id/eventsList events (scoped by date range, event type)
GET/v1/agents/:id/chainsHITL and rotation lifecycle chains
GET/v1/controls/:id/evidenceAll events satisfying a control — one query, all frameworks
GET/v1/frameworks/:id/coverageFULL / PARTIAL / NONE breakdown for iris certify
GET/v1/agents/:id/integrityWalk hash chain, return validity
GET/v1/agents/:id/exportAuditor package on demand (pdf, json, oscal, aiuc1)

Admin scope (security team): POST /v1/erasure-requests, POST /v1/legal-holds, DELETE /v1/legal-holds/:id. Even admins cannot delete events — only request erasure through the lifecycle.

CI/CD integrations

Every integration writes cicd_run events at meaningful pipeline moments. Pipelines never read from the vault during deploy — evidence recording never blocks deployments.

Copy-ready templates live in the repo under docs/gha/:

PlatformTemplateKey pattern
GitHub Actionsdocs/gha/developer.ymlif: always() — records evidence even on failure
GitLab CIdocs/gha/gitlab-ci.ymlrules: when: always
Jenkinsdocs/gha/Jenkinsfilepost { always { ... } }
Terraformterraform/evidence_record.tfnull_resource on policy hash change
ArgoCDdocs/gha/argocd-evidence-hook.yamlPostSync hook after actual deploy

GitHub Actions example

- name: Record CI evidence to vault
  if: always()
  run: |
    iris evidence record-cicd \
      --system github_actions \
      --run-id "${{ github.run_id }}" \
      --pipeline-url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
      --triggered-by "${{ github.actor }}" \
      --outcome "${{ job.status }}"

Compliance as Code, Evidence as Code

These are architectural properties, not separate features:

Compliance as Code declares what should happen. Evidence as Code proves what did happen. The gap between them is what iris drift check and iris sentinel monitor continuously.

Pair with certification

iris certify --agent loan-processor --framework colorado-ai-act
iris certify --agent loan-processor --framework aiuc-1 --format aiuc1-export
iris evidence export --agent loan-processor --format aiuc1 --output auditor-package.json

Certification readiness scores plus Evidence Vault exports form the auditor package. All framework reports query the same ControlMapping index — generate evidence once, satisfy many frameworks.

Environment variables

VariableDescription
IRIS_ENVResolved environment stamped on every event (dev, staging, production, …)
IRIS_AGENT_IDDefault agent for record-cicd when --agent is omitted
IRIS_VAULT_SIGNING_KEYHMAC signing key override (default: derived per agent for local dev)