OGuardAI
Security

Compliance Controls Mapping

Article-by-article mapping of OGuardAI controls to GDPR, HIPAA, SOC 2, and PCI DSS requirements

GDPR Alignment

GDPR ArticleRequirementOGuardAI ControlHow to Verify
Art. 5(1)(c)Data minimizationTokenization removes PII from LLM contextTransform API returns safe_text with detected, non-whitelisted PII tokenized or removed
Art. 5(1)(e)Storage limitationSealed sessions auto-expire, no server-side retentionCheck session TTL configuration
Art. 25Data protection by designTrust boundary model, sealed sessionsSecurity whitepaper Section 1
Art. 28Processor obligationsSelf-hosted, no subprocessors in sealed modeDeployment guide
Art. 30Records of processingStructured audit events per operationAudit module, diagnostics endpoint
Art. 32Security of processingAES-256-GCM encryption, key rotationSecurity whitepaper Section 2
Art. 17Right to erasureSessions auto-expire, no server-side retentionData retention doc
Art. 20Data portabilitySealed sessions are portable (client-held)Session model
Art. 35Data protection impact assessmentAudit trail, policy validation, shadow (dry-run) mode for staging evaluationAdmin endpoints

Note on shadow mode: shadow (dry-run) mode returns a redacted comparison (a fingerprint hash plus aggregate deltas), not raw PII, and is a dev-only diagnostic rejected as a fatal production-validation error. It is a staging-only evaluation aid for previewing detection and tokenization behavior, not a production compliance control.

HIPAA Alignment

HIPAA SectionRequirementOGuardAI ControlImplementation Detail
SS 164.312(a)(1)Access controlJWT/API key auth + scope modelAuth middleware with per-endpoint scopes (Transform, Rehydrate, Detect, Policy, Batch, Rag, Revoke, Global Revoke, Session, Detect Values, Admin)
SS 164.312(a)(2)(iv)Encryption/decryptionAES-256-GCM sealed sessionsSession crate with AEAD encryption
SS 164.312(b)Audit controlsStructured audit eventsAudit module emits events via tracing
SS 164.312(c)(1)Integrity controlsAEAD authentication tag on session blobsTamper detection built into AES-GCM
SS 164.312(e)(1)Transmission securityTLS support, encrypted session stateDeployment guide covers TLS setup
SS 164.502(b)Minimum necessaryTokenization + policy-based restore modes6 restore modes: full, partial, masked, formatted, abstract, none
SS 164.308(a)(5)(ii)Security awarenessPolicy validation and dry-run endpointsAdmin can preview impact before changes

SOC 2 Type II Alignment

ControlDescriptionOGuardAI FeatureEvidence
CC6.1Logical accessAuth middleware with scopesAPI key/JWT validation on every request
CC6.3Role-based accessPer-endpoint scopes (Transform, Rehydrate, Detect, Policy, Batch, Rag, Revoke, Global Revoke, Session, Detect Values, Admin)Scope-based authorization checks
CC6.6System boundary protectionTrust boundary modelDetected, non-whitelisted PII tokenized before leaving the runtime boundary
CC6.7Restrict data mobilityPolicy engine controls entity exposurePer-entity-type action rules
CC7.1Detect security eventsPrompt security engine, output guardInput/output scanning for injection and PII leaks
CC7.2System monitoringStructured audit events, diagnostics endpointAudit trail, health checks
CC8.1Change managementPolicy diffing, validation endpointPreview impact of policy changes before deployment
CC9.1Risk mitigationMulti-layer detection (regex + NLP)Builtin + advanced detector modes

PCI DSS Alignment (Where Applicable)

PCI DSS RequirementOGuardAI Control
3.4 -- Render PAN unreadableCredit card tokenization with Luhn validation
3.5 -- Protect cryptographic keysSession key derived from configured secret, key rotation supported
10.1 -- Audit trailsStructured audit events per operation
10.3 -- Record audit trail entriesTimestamp, tenant, entity types, policy, duration in every event

Audit Event Schema

Every OGuardAI operation emits a structured audit event: text, JSON, and chat transform; rehydrate; the RAG ingest/query/context/answer/delete pipeline; detection (/v1/detect, /v1/batch/detect); revocation (/v1/revoke, /v1/revoke/bulk); and image redaction (/v1/redact/image). Each event carries only PII-free type and count metadata. A structured event looks like:

{
  "timestamp_unix": 1700000000,
  "event_type": "transform",
  "tenant_id": "tenant_acme",
  "session_id": "550e8400-...",
  "policy_applied": "gdpr-strict",
  "entity_types": ["email", "phone"],
  "entity_count": 3,
  "entities_blocked": 1,
  "entities_tokenized": 2,
  "duration_ms": 12.5,
  "detector_mode": "builtin_regex",
  "output_guard_triggered": false,
  "prompt_security_triggered": false
}

Key property: No raw PII values appear in audit events.

The event schema also reserves three optional GDPR Art. 30 record-of-processing fields: purpose (a processing-purpose label), legal_basis (an Art. 6(1) lawful basis from a closed set: consent, contract, legal_obligation, vital_interests, public_task, legitimate_interests), and data_category (a category-of-data label). They are PII-free controlled labels, never sourced from request content, and each is omitted from the event when unset. The runtime does not currently populate them (there is no policy/config wiring yet), so today they are absent from every event; if a future release wires them, they would be controller-supplied labels only, never derived from data. The full Records of Processing (retention, data-subject categories) remains organizational and lives in your RoPA.

Audit Export

Audit events are emitted as structured tracing events on the guardai::audit target. They can be collected by any log aggregation system:

  • ELK Stack: Filebeat -> Logstash -> Elasticsearch -> Kibana
  • Datadog: Datadog Agent with JSON log parsing
  • Splunk: Universal Forwarder with JSON sourcetype
  • AWS CloudWatch: CloudWatch Logs agent
  • Google Cloud Logging: Fluentd/Fluent Bit

Configure your tracing subscriber to output JSON format for easy parsing:

RUST_LOG=guardai::audit=info oguardai-server

Policy Governance Events

In addition to operational audit events, OGuardAI emits policy governance events:

Event TypeWhen EmittedWhat It Records
policy_loadedServer startupEach policy loaded from the policies directory
policy_validatedAdmin validation endpointProposed policy validation result

These events are emitted as structured log records (no raw PII) and create a record of policy state changes over time. With the default log backend, durability and tamper-resistance depend on the operator's log sink. The optional file audit backend adds a local append-only, HMAC-chained store with one tamper-evident hash chain per tenant, so each tenant's records verify independently; route it to durable, access-controlled storage for retention.

To enable durable, fail-closed audit in one step, start the server with --compliance (or set GUARDAI_COMPLIANCE=1 for an env/Helm deployment that cannot pass a flag; it accepts 1, true, yes, or on). The preset only tightens: it forces the file audit backend and strict (fail-closed) audit on the data path, so a transform, rehydrate, detect, RAG, session, or revoke operation whose audit event cannot be recorded is rejected (HTTP 503) rather than acknowledged unaudited. For a revocation, which persists before it is audited, a failed audit rolls the erasure back so no unaudited state change survives. The file sink is enqueue-based: record hands the event to a bounded in-process queue that a background task writes to disk, so strict mode rejects when the event cannot be enqueued (the queue is full or its writer has stopped), which is the fail-closed signal on the write path. Fail-closed does not extend to every event. Failure audits (a request that is already erroring), admin diagnostics, and startup events are recorded fail-open (a sink error is logged, not propagated), and the transparent proxy records its PII-safe failure audits to the log sink only. Those paths never carry raw PII, so a dropped record loses a log line, not customer data. The audit file path stays operator-configured (audit.file.path); startup fails closed if it is unset, so a compliance deployment must point the durable log at a real, access-controlled path. The gate runs regardless of auth.mode, so it holds even in dev mode where the general config validation is skipped.

# Durable, fail-closed audit; audit.file.path must be set in the config.
oguardai-server --compliance --config oguardai.yaml

# Same preset via env (Helm/container deployments).
GUARDAI_COMPLIANCE=1 oguardai-server --config oguardai.yaml

Verifying audit-log integrity

The file backend is tamper-evident; the audit verify command makes it operator-provable. It re-derives the chain key from the configured session secret (never from the file), re-walks every per-tenant sub-chain, and reports whether the log is intact.

# Verify the audit file named in the config (uses the config session secret).
oguardai-server audit verify --config oguardai.yaml

# Verify an archived or relocated copy on a forensic host.
oguardai-server audit verify --config oguardai.yaml --path /backups/audit-2026-06.jsonl

# Machine-readable result for monitoring; --tenant scopes the per-chain breakdown.
oguardai-server audit verify --config oguardai.yaml --json --tenant acme

Exit codes are distinct so monitoring can act on them: 0 intact, 2 broken (a definitive tamper or corruption verdict; any break in any tenant fails the whole file), 1 cannot verify (a missing or unreadable file, or audit.backend is not file). A 1 is a misconfiguration; a 2 is an integrity incident.

The output is PII-free (chain keys, counts, sequence ranges, head hashes, timestamps, and a closed set of break reasons; never event content). The audit HMAC key is never printed, only a domain-separated 8-character fingerprint so two runs can be confirmed to use the same key.

Verifying policy integrity

The policy directory itself can be signed and verified fail-closed at startup, so a modified, added, removed, or swapped policy file refuses to start the server. A policy can never be silently weakened on disk. Sign the directory with a dedicated key, then enable verification in the config.

# Sign the policy directory (writes <dir>/.signatures.json).
oguardai-server policy sign-dir --dir policies --secret "$GUARDAI_POLICY_SIGNING_KEY" --kid v1
policy:
  directory: policies
  integrity:
    manifest: policies/.signatures.json
    secret: "${GUARDAI_POLICY_SIGNING_KEY}"
    kid: v1

The signing key is HMAC-derived and independent of the session secret, so policy governance can hold a different key than the runtime. Verification covers exactly what the server loads (each <subdir>/policy.yaml and each root-level *.yaml), rejects symlinks, and reports the first failing file as modified, unexpected, or missing. Both manifest and secret must be set; setting exactly one is a startup error, and both absent disables it (the default). Re-sign after any intentional policy change.

Notes:

  • The audit key derives from the base session.secret, independent of the session sealing keyring, so rotating sealing keys does not affect verification. Rotating session.secret itself invalidates prior records, so start a fresh audit file when you rotate it.
  • Tail truncation (deleting the most recent records) leaves a valid prefix; publish each chain head_hash between audits as an external anchor to detect it.
  • For a portable evidence copy, audit export produces an integrity-attested, PII-free NDJSON bundle (or a --tenant / --since / --until slice) to hand a DPA or auditor:
# The whole log, attested. Refuses (exit 2) if the chain is broken.
oguardai-server audit export --config oguardai.yaml --out evidence.ndjson

# A tenant + time slice; the header still carries every chain's head hash so a
# slice cannot be passed off as the whole log.
oguardai-server audit export --config oguardai.yaml --tenant acme --since 1717200000

The export verifies the whole file first and fails closed (a broken chain emits nothing, exit 2). The first line is an attestation (whole-file head hashes, totals, key fingerprint, the applied filter); the body is the PII-free events; the last line is a trailer with the exported count and a completion marker. --out writes a 0600 file and never overwrites. The exported events would carry the per-event Art. 30 label fields (purpose, legal_basis, data_category) if the runtime populated them; today those fields are unset. The complete Records of Processing (data-subject categories, retention schedules) is organizational and lives in your RoPA template, not in this runtime export.

Verification Checklist

Use this checklist to verify OGuardAI compliance controls in your deployment:

  • Sealed session mode enabled (default)
  • Session TTL configured appropriately
  • TLS enabled for all endpoints
  • Auth mode set to ApiKey, Jwt, or Oidc (not Dev)
  • Audit events routed to SIEM/log aggregator
  • Log rotation and retention configured
  • Policy directory version-controlled (git)
  • Policy validation run before deployments
  • Encryption key rotation schedule established
  • Output guard enabled for sensitive workflows
  • Prompt security enabled (default)