cifraHQ Enterprise
Compliance

SOC 2 isn't a checkbox. It's in the schema.

Audit evidence lives at the SQL principal layer, not in application code. Four mechanisms ensure no one — not even an engineer — can alter history.

The four mechanisms

How we guarantee immutability

Traceability

Dual audit trail

Temporal tables on every mutable business entity + append-only <code>AuditEvents</code> table. Unified in a single "Changes…" view.

Immutability

DENY UPDATE/DELETE

The application SQL principal has <code>DENY</code> on <code>AuditEvents</code>. Only <code>audit_admin</code> can purge.

Secrets

Azure Key Vault

Connection strings, API keys, SMTP credentials — never in code, never in appsettings, never in the database.

Dual audit trail

Two records, two purposes

  • SQL Server temporal tables on every mutable entity. Each UPDATE leaves a historical row with ValidFrom/ValidTo. Transparent to application code.
  • Append-only AuditEvents for discrete business events: "Invoice 12345 posted", "Period 2026-03 closed", "User X granted Approve permission". No UPDATE, no DELETE.
  • Unified UI view. Every document detail has "Changes…" that merges both sources chronologically.
  • Required reasons. Reverse transitions (reverse-close, void) require a minimum 20-character reason string, logged to AuditEvents.
DENY at the principal layer

Why this matters

A system that trusts application code to block writes is not defensible under SOC 2. An engineer with database access can rewrite history. We close that door at the engine.

  • Three SQL principals per tenant: app_rw (normal reads/writes), audit_admin (the only one that can purge audit), readonly_investigator (investigation console).
  • Investigation console. Every admin query in the dashboard runs through readonly_investigator and is logged to AuditEvents.
  • Irreversible posting. A posted invoice isn't edited; it's voided and a credit note is issued. The posting engine checks ActualPostingDate and rejects UPDATEs.
SOC 2 posture

Concrete controls, not promises

  • CC6.1 Logical access. RBAC model with permissions as named constants (Permissions.Invoice.Approve). No magic strings.
  • CC7.2 Monitoring. Dual audit trails + Hangfire logs. Azure Monitor integration with per-tenant health alerts.
  • CC8.1 Change management. Signed CI/CD pipeline. Schema migrations versioned; each deploy records its version in CiferaHQ_master.
  • A1.2 Processing integrity. Temporal tables + AuditEvents + DENY UPDATE prove integrity without trusting the application.
  • P1/P3 Privacy. Per-tenant database = physical isolation of personal data. Customer offboarding deletes the database.

Let's review your security questionnaire

We answer your SIG Lite, CAIQ or vendor review in a 30-minute meeting.

Schedule