Security Architecture
This page describes the security mechanisms behind the archive promises: what protects stored content, how tampering is detected, who can see and do what, and what happens in a disaster. Every claim here names its mechanism, and anything that is not yet deployed is labeled as roadmap rather than implied. Talonic does not currently hold formal certifications; a control-by-control mapping against SOC 2 TSC and ISO 27001:2022 Annex A is maintained alongside the codebase and is available on request.
Content integrity: fixity at ingest and on schedule
Every document is hashed (SHA-256 over the original bytes) at ingest, and the hash is persisted with the document. Integrity is then continuously re-proven, not assumed: a daily verification cycle streams stored content back out of object storage, recomputes the hash, and compares it against the ingest-time value. The batch size adapts so the entire corpus is re-verified within a configurable window (30 days by default), least-recently-checked documents first, and documents uploaded through presigned URLs get a priority first check. A mismatch quarantines the document (it is flagged, not silently served), writes a check record, and lands in the audit trail; every completed cycle is also recorded. A weekly sweep reconciles the blob store against database references in both directions and reports orphans.
# Recent checks, mismatches first
curl "$API_URL/records/fixity-checks?status=mismatch" \
-H "Authorization: Bearer $TOKEN"
# On-demand check of one document
curl -X POST "$API_URL/records/fixity-checks/run" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"document_id": "<doc-id>"}'Tamper evidence: hash chain plus external anchors
The audit trail is a per-workspace hash chain: each event carries a SHA-256 fingerprint of its contents combined with the previous event's fingerprint, written in strictly serialized order. The chain alone makes any in-place edit, deletion, or insertion detectable at the exact first altered event. Its known limit is an attacker with full database write access, who could rewrite an entire chain consistently. That is what anchoring addresses: every day, each workspace's chain head (latest event ID plus head hash, linked to the previous anchor) is written to external object storage, outside the database. Verification cross-checks every stored anchor against the live chain, so a consistent rewrite no longer verifies. Anchors currently land in the encrypted, versioned object store with application-level write-once protection; anchoring to storage-level WORM follows the archive storage rollout.
Storage protection: write-once, encrypted, versioned
- Application-level write-once. Canonical storage keys are written with an existence guard: an attempt to overwrite a stored object is rejected with a conflict error. There is no code path that legitimately rewrites stored bytes.
- Server-side encryption on every write. Every object put carries server-side encryption. Deployments configured with a customer-managed KMS key encrypt under that key; otherwise AES-256 managed encryption applies.
- Reasoned, hold-checked deletion. Storage-level delete endpoints require an explicit recorded reason and pass the fail-closed legal hold check before removing anything.
- Versioning and infrastructure protection. Production buckets are versioned (deleted or overwritten objects are recoverable from prior versions) and protected against bucket deletion at the infrastructure level.
- Storage-level WORM: roadmap. S3 Object Lock (governance mode, per-object retention driven by the record's retention date) plus cross-region replication with a 15 minute replication SLA exist as validated infrastructure templates. The archive bucket is not deployed and no Object Lock claim applies to the current release.
Access control: isolation, roles, compartments, MFA
Access is layered. Workspace isolation scopes every query to the tenant. Role-based access control fails closed: a route that mutates state is denied unless it is explicitly opened to a role tier, so a forgotten permission check results in denial, not exposure. Compartments add need-to-know inside a workspace: named user groups are bound to sources, document types, or individual documents, and restricted members and viewers see only uncompartmented documents plus their own compartments, enforced through a single SQL predicate applied at every document query path (list, detail, file access, export, and the AI agent's search). Owners and workspaces without compartments are unaffected.
Authentication supports TOTP multi-factor authentication (standard authenticator apps; the secret is encrypted at rest, and login becomes a two-phase exchange once MFA is confirmed). Workspaces can additionally require step-up verification: with the setting on, the highest-impact archive actions (hold release, disposition approval, erasure scoping and execution, tenant export, and the superadmin hold override) demand a fresh TOTP code in the X-Step-Up-Code header, so a hijacked session alone cannot destroy or exfiltrate records. Failed step-up attempts are audited. User lifecycle can be driven by your identity provider through SCIM 2.0: users are provisioned and deprovisioned by the IdP, deprovisioning blocks the next request at the membership gate, group sync maps to org roles or compartments, and SCIM tokens are shown once and stored only as hashes.
Erasure, export, and disaster recovery
GDPR erasure requests run through a locate, scope, approve, execute workflow with per-document redact or destroy modes; retention duties and legal holds block destruction and are reported as certificate exemptions rather than silently skipped. Full-workspace data comes back as a verifiable export bundle with a per-file SHA-256 manifest (see Export Bundle Format). For disaster recovery: the database has continuous backup with point-in-time recovery, storage is versioned, and a finalized restore procedure with a quarterly drill checklist exists. The committed recovery objectives are 15 minutes for storage, 5 minutes for the database, and 4 hours to full service; a quarterly restore drill validates them against measured wall-clock times.