Compliance

The homepage says “audit trail — built in.” This page is what that sentence has to survive: the actual mechanism, the actual code, and a tool an auditor can run without asking us to trust a dashboard.

The audit record: hash-chained, on by default

Every audit event Odysseus writes is chained to the one before it. Each row stores entry_hash = SHA-256(prev_hash || canonical_json(event)), so altering or deleting a row breaks the hash of everything written after it — not just that row.

This is not an opt-in feature you have to remember to turn on. HashChainConfig's own doc comment states it plainly: “The chain is ENABLED BY DEFAULT — the zero value (Disabled: false) … omits the HashChain block gets tamper-evident audit at no extra” configuration step (pkg/audit/hash_chain.go:19-23). The control plane announces it at boot: “Audit hash chain enabled (default-on; set HashChain.Disabled=true to opt out)” (pkg/audit/postgres_logger.go:247). Turning it off is a deliberate, logged action, not a default you have to discover.

Anchoring and an external witness — both optional, both pluggable

On top of the chain, Odysseus can periodically anchor a hash to two places you don't have to trust us for:

A tool, not a screenshot

odysseus-audit-verify is a standalone binary — its own main package at cmd/odysseus-audit-verify/main.go, built and shipped separately from the control plane. Give it credentials for the audit database and it walks every row in sequence_num order, recomputes each hash, and cross-checks every anchor. It does not go through the Odysseus API, the dashboard, or anything the platform itself renders. It connects directly to Postgres, so it is not a zero-network tool, but it is independent of the running control plane: an auditor can point it at a database replica and get an answer nobody at Delta Telematics can shape.

It reports a distinct exit code for each class of problem, documented in the binary's own header comment:

Exit codeMeaning
0Chain intact, all anchors match
1Chain integrity defect — broken link, mismatched hash, missing entry
2Anchor verification failure — anchor hash mismatch or bad signature
3Operational error — database unreachable, malformed row, etc.

Source: cmd/odysseus-audit-verify/main.go, lines 12–18 (documented behavior) and 56–59 (the exit-code constants themselves).

Tenant isolation the database enforces, not just the application

Three separate boundaries, each independently checkable in code:

Where we actually stand

We do not hold a certification, and we don't imply one. What we do have is a documented, self-assessed mapping of our controls against five frameworks, carried in the security team's own audit document rather than in marketing copy:

FrameworkInternal readinessNotes
SOC 2 Type II85%Access control, audit logging
ISO 2700180%Information security controls
GDPR75%Data protection controls
PCI DSS70%Not handling payment data
HIPAA60%Not our primary use case

Source: docs/security/02-owasp-security-audit.md, “Compliance Mapping” table, lines 490–498.

No certification exists

These are self-assessed readiness percentages, not audit results from an accredited third party. We say so on the pricing page too: the wording there is “SOC 2- and ITSG-33-aligned controls and audit evidence,” not compliance itself — a wording change made specifically because no certification exists. If that changes, this page will name the certifying body and the date; until it does, treat every percentage above as our own homework, not an external attestation.

For the audit that produced the security posture these controls sit on, see the security audit page. For the day-to-day security architecture — authentication, secrets, infrastructure hardening — see Security.

How these numbers and claims were arrived at

  1. Every claim on this page was checked directly against the source at the file and line cited beside it, on 21 August 2026, rather than taken from an earlier description of the feature. Where a mechanism is optional (Vault Transit signing, the external witness), we say so explicitly rather than letting the surrounding sentence imply it always runs.
  2. The offline verifier's independence from the control plane is a real property — it is a separate binary that talks to Postgres directly — but it is not a zero-dependency tool: it still needs credentials and network access to the audit database (or a replica of it). We describe it that way rather than as fully offline.
  3. The compliance percentages are our own internal self-assessment, dated to the document that carries them, not a claim of certification by any outside body. If that document is revised, this table goes stale until it is re-checked against the new version.