Security Compliance Whitepaper

22 min read

TamperTrail — Security & Compliance Whitepaper

Document Type: Executive Whitepaper Classification: Public
Audience: Chief Security Officers (CSOs), Data Protection Officers (DPOs), IT Compliance Auditors, and Enterprise Procurement Teams
Version: 1.0 — March 2026 Keywords: audit log data governance, GDPR audit trail, CCPA compliance logging, privacy by design, encrypted audit log, immutable audit trail, data lifecycle management, HIPAA audit logging


Table of Contents

  1. Executive Summary & Our Unique Position
  2. Cryptographic Architecture
  3. Access Control & Defensive Engineering
  4. Data Classification & Privacy Architecture
  5. Shared Responsibility Model
  6. Compliance Framework Mapping
  7. Honest Assessment of Current Limitations
  8. Security Roadmap
  9. Incident Response Considerations

1. Executive Summary & Our Unique Position

What TamperTrail Is

TamperTrail is a self-hosted, cryptographically immutable audit vault. It is not a log aggregator, an APM dashboard, or an observability platform. It is a purpose-built compliance instrument: a system whose primary guarantee is that once an event is recorded, that record cannot be silently modified, deleted, or reordered — and that this guarantee is mathematically provable by anyone with read access to the database, at any time, without trusting TamperTrail's own reporting.

Every log entry is chained to its predecessor using SHA-256 cryptographic hashing. Every sensitive payload is encrypted with AES-128 before it touches the database. The system is deployed entirely within the customer's own infrastructure — no data ever transits to TamperTrail's servers, because TamperTrail has no servers.

How TamperTrail Differs from Traditional Observability Tools

The audit logging market is dominated by SaaS observability platforms designed for engineering teams: Datadog, Splunk, Sentry, New Relic, and similar products. These tools excel at performance monitoring, error tracking, and developer workflow. They are not compliance instruments.

CriterionSaaS Observability PlatformsTamperTrail
Data sovereigntyData leaves your infrastructure permanentlyData never leaves your infrastructure
Tamper evidenceNone — the vendor can modify recordsSHA-256 hash chain — mathematically provable
Sensitive payload protectionVaries; typically plaintextAES-128 encryption before database write
Audit data verificationRequires trusting vendor's attestationRun GET /v1/verify — self-verifiable at any time
Compliance scopeShared responsibility with a third partyEntirely within your own infrastructure boundary
GDPR third-country transfer riskPotentially applicable (vendor data centers)Not applicable — no data egress
Cost at scalePer-seat or per-GB pricingSelf-hosted — infrastructure cost only

Honest Caveat

TamperTrail is a software product, not a compliance certification. Deploying TamperTrail provides the technical controls that underpin compliance. Achieving a formal certification (SOC 2 Type II, ISO 27001, HIPAA attestation) also requires organizational policies, procedures, personnel training, and operational practices that are beyond the scope of any software product. This document does not claim otherwise.


2. Cryptographic Architecture

2.1 Data at Rest — The Encrypted Metadata Vault

Every log entry accepted by TamperTrail may carry two data payloads:

FieldStorage TypeEncryptedSearchableDashboard Visible
tagsJSONB❌ Plaintext✅ GIN indexed✅ Yes
metadataBYTEA✅ AES-128-CBC + HMAC-SHA256❌ No❌ Never

The metadata field uses the Fernet symmetric encryption scheme from the Python cryptography library (OpenSSL-backed):

  • Cipher: AES-128-CBC
  • Authentication: HMAC-SHA256 (encrypt-then-MAC — ciphertext tampering is detectable independently of decryption)
  • Key format: 32-byte URL-safe base64 — 16 bytes for AES, 16 bytes for HMAC
  • Token structure: Version byte + timestamp + IV + ciphertext + HMAC, all base64-encoded

Encryption occurs in application memory before the database driver is called. The PostgreSQL engine never receives the plaintext value of metadata under any code path. A complete dump of the audit_logs table reveals only binary ciphertext in the metadata column (stored as BYTEA). Without the encryption key, this ciphertext is computationally indistinguishable from random noise.

Frontend architectural blindness: The React dashboard is structurally prevented from receiving metadata. The LogEntryOut API response schema excludes the encrypted column — it is dropped in the Python serialization layer before the HTTP response is constructed. A complete compromise of the React application cannot expose the encrypted vault because that data is never transmitted to the browser under any code path.

Key rotation (MultiFernet): Multiple encryption keys can be configured simultaneously — new entries encrypt with the current primary key; all configured keys are tried for decryption. Zero-downtime rotation: prepend a new key, deploy, and historical entries remain readable indefinitely via the old key.

Envelope encryption (Enterprise): When a MASTER_KEY is configured, the data encryption key (DEK) is itself encrypted before storage — a standard KEK/DEK pattern. Enables integration with AWS KMS, HashiCorp Vault, GCP Cloud KMS, or any compatible external key management system. The plaintext DEK never persists to disk in this configuration.


2.2 The Immutable Ledger — SHA-256 Hash Chaining

Every row in audit_logs carries:

FieldContent
prev_hashSHA-256 hash of the immediately preceding entry (same tenant, chronological order)
hashSHA-256 digest of this entry's canonical representation

Hash input (deterministic concatenation):

hash = SHA-256(prev_hash + created_at + actor + action + target_type + target_id + hex(metadata_ciphertext))

Including the raw encrypted bytes of metadata in the hash means modifying the ciphertext — even without the decryption key — immediately breaks the chain. The first entry per tenant anchors to a fixed GENESIS_HASH (SHA-256 of the string "GENESIS").

Tamper detection (GET /v1/verify): Reads every entry in chronological order, recomputes the expected hash, and asserts entry.prev_hash == previous_entry.hash. Any deletion, modification, insertion, or reordering produces a detectable chain break at that position — the system reports the exact location.

Auditor note: The verification algorithm can be independently reimplemented using only a database connection and the hash rules above. It does not require trusting any TamperTrail API response.

Retention-safe verification — Monthly Checkpoints: POST /v1/checkpoints creates a cryptographic snapshot of the chain state at a monthly boundary. Verification anchors to the most recent checkpoint rather than GENESIS, preserving full chain verifiability even after historical entries are pruned under a retention policy.


2.3 Data in Transit

TamperTrail does not terminate TLS. This is a deliberate architectural boundary — TLS termination belongs in the customer's infrastructure layer, upstream of the application.

Customer Requirement: All production deployments MUST place a TLS-terminating reverse proxy (Caddy, Traefik, AWS ALB, Cloudflare, or equivalent) in front of TamperTrail. Without TLS, API keys and session tokens transit the network in plaintext.

Recommended production topology:

[ Internet ] → HTTPS → [ Customer TLS Proxy ] → HTTP → [ Nginx :80 ] → [ FastAPI :8000 ]

TamperTrail's responsibility begins at the Nginx listener.


3. Access Control & Defensive Engineering

3.1 Authentication — Strict Principal Separation

PrincipalCredentialTransportScopeStorage
Machine (services, scripts)API Key (X-API-Key header)Stateless per-requestPOST /v1/log ingestion onlyArgon2id hash
Human (admin/viewer)JWT session cookie (tampertrail_token)HTTPOnly cookieDashboard & management APIsMemory — 24h expiry

A leaked API key cannot authenticate a dashboard request. A stolen session token cannot authenticate a log ingestion request. The credential types are structurally incompatible at the routing layer — not merely insufficient-scope-checked.

API key properties: Generated from cryptographically secure random source. Raw value returned once and never stored in plaintext. Stored as Argon2id hash (GPU/ASIC-resistant). Revocation is immediate.

Session JWT properties: HS256 signed. HTTPOnly (XSS-resistant). SameSite=Lax (CSRF-resistant). Single active session per user — new login invalidates all prior sessions. Session records include IP and User-Agent for forensic review.

Password hashing: Argon2id (memory-hard, OWASP-recommended). Automatic parameter upgrade on next login if cost parameters have been increased.


3.2 The Network Boundary — Nginx as Enforcer

Only the Nginx container binds a host port. FastAPI and PostgreSQL are reachable exclusively within the internal Docker network.

Per-IP rate limits (enforced before Python executes):

EndpointLimitBurstProtection Target
POST /v1/auth/login5 req/min3Brute-force credential attacks
POST /v1/log100 req/min20Log flooding, runaway services
All other /v1/*200 req/min50General API abuse

Request size limiting: Oversized payloads are rejected by Nginx before any Python memory is allocated — prevents memory exhaustion attacks.

OpenAPI suppression: /docs, /redoc, and /openapi.json are blocked at the Nginx layer.

Security response headers on every response: X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Content-Security-Policy, Strict-Transport-Security, Referrer-Policy: no-referrer, Permissions-Policy.


3.3 Multi-Tenant Data Isolation — Defense in Depth

Layer 1 (Application): Every query is constructed with an explicit WHERE tenant_id = :tid extracted from the authenticated JWT. Not from query parameters or request bodies.

Layer 2 (Database): PostgreSQL Row-Level Security (RLS) with FORCE ROW LEVEL SECURITY on audit_logs and chain_checkpoints. If the application-level tenant context is not set, no rows are returned — fails closed, not open.

Cross-tenant exposure requires simultaneously bypassing two independently implemented controls at different layers.


3.4 SQL Injection Prevention

All database queries use SQLAlchemy parameterized expressions. Raw SQL string interpolation is not used anywhere in the codebase. SQL injection is eliminated by construction.


3.5 Server-Side Attribution (Anti-Spoofing)

source_ip, user_agent, and device_type are captured server-side from the HTTP request context — not from client-supplied payload fields. Nginx injects X-Real-IP from the TCP connection level. Clients cannot suppress or falsify these fields.


4. Data Classification & Privacy Architecture

4.1 The Two-Tier Data Model

┌──────────────────────────────────────────────────────────────┐
│                      AUDIT LOG ENTRY                         │
│                                                              │
│  ┌─────────────────────────┐  ┌──────────────────────────┐  │
│  │      TIER 1: TAGS       │  │    TIER 2: METADATA      │  │
│  │  Plaintext JSONB        │  │  AES-128 Ciphertext      │  │
│  │  GIN-indexed            │  │  BYTEA binary blob       │  │
│  │  Dashboard visible      │  │  Never transmitted       │  │
│  │  Export included        │  │  Export excluded         │  │
│  │  Searchable             │  │  Unsearchable            │  │
│  │                         │  │                          │  │
│  │  Non-sensitive context  │  │  Sensitive forensic data │  │
│  └─────────────────────────┘  └──────────────────────────┘  │
└──────────────────────────────────────────────────────────────┘

4.2 Data Residency

TamperTrail makes zero outbound network connections at runtime. No telemetry, no analytics beacons, no license validation calls, no automatic update checks. All data resides exclusively in the Docker volumes on the customer's host machine.

GDPR Articles 44–49 (International Data Transfers): TamperTrail makes cross-border data transfers structurally impossible. Data cannot leave the jurisdiction in which the host machine resides because TamperTrail contains no mechanism for outbound data transmission.


5. Shared Responsibility Model

This section defines with precision what TamperTrail guarantees and what the customer is responsible for. Security gaps most commonly arise from assumed — not stated — responsibilities.


5.1 TamperTrail's Security Guarantees

GuaranteeMechanism
Cryptographic chain integritySHA-256 hash chain on every write — GET /v1/verify provides mathematical proof
Metadata never stored in plaintextAES-128 in application memory before DB write
Brute-force login protectionNginx: 5 req/min per IP
API key plaintext never storedArgon2id hash only
Cross-tenant isolationApp-layer tenant_id filter + PostgreSQL RLS
Frontend metadata blindnessmetadata excluded from all API response schemas
No outbound data transmissionZero external network calls at runtime
SQL injection preventionSQLAlchemy parameterized queries only
Session credential securityHTTPOnly + SameSite=Lax JWT cookies
Auto-generated cryptographic secrets/dev/urandom source on first boot — no user-defined defaults

5.2 Customer Responsibilities

The following describes where TamperTrail's software controls end and customer operational responsibility begins. These are not gaps — they are the correct responsibility of the infrastructure operator.


5.2.1 Encryption Key Custody — CRITICAL

The encryption key stored in TamperTrail's configuration file is the sole key for the metadata vault. TamperTrail holds no escrow copy. There is no recovery mechanism.

ScenarioConsequence
Key lost (volume deleted, disk failure)All metadata ciphertext is permanently and irrecoverably unreadable. All other fields (tags, actor, action, timestamps) remain fully intact.
Key leaked (config file exposed)All historical metadata can be decrypted offline with no detection mechanism.

Treat the TamperTrail configuration file with the same operational controls as a TLS private key: restricted file permissions, regular off-host backups, and storage in a secrets management system (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault) for any production deployment of consequence.


5.2.2 TLS / HTTPS Termination

Without a TLS-terminating proxy in front of TamperTrail, all API keys, session tokens, and log payloads transit the network in plaintext. This is not acceptable for any production deployment.

Customer responsibilities: Provision and maintain valid TLS certificates. Configure a terminating proxy upstream of TamperTrail. Enforce TLS 1.2 minimum (1.3 recommended). Manage certificate renewal.


5.2.3 Host & Network Security

ResponsibilityRisk if Neglected
Host OS patchingContainer escape via kernel exploit yields host root
Docker socket access controlDocker socket access is equivalent to root on the host
Network firewall configurationPort 80 exposed without TLS proxy allows plaintext credential interception
Volume access controlDirect volume access bypasses all application authentication

5.2.4 Data Sanitization — The tags Field

TamperTrail encrypts what it is given. It cannot protect data it does not know is sensitive. Data misclassification is the customer's liability.

The tags field is plaintext JSONB — fully visible in the dashboard, returned in API responses, and included in data exports.

Data CategoryIncorrect FieldCorrect Field
User email addresses, phone numberstagsmetadata
User IP addresses (GDPR scope)tagsmetadata
Authentication tokens, session IDstagsmetadata
Stack traces with internal pathstagsmetadata
Any PII under your data classification policytagsmetadata

Enforce correct field routing in integration code via code review checklists or static analysis rules auditing all POST /v1/log call sites.


5.2.5 Access Control Lifecycle

  • Revoke API keys when services are decommissioned or credentials rotate.
  • Deactivate or delete user accounts when personnel change roles or leave.
  • Rotate API keys on a schedule consistent with your security policy.
  • Review GET /v1/sessions regularly for anomalous login patterns.

6. Compliance Framework Mapping

Disclaimer: This mapping represents an honest, good-faith assessment of controls TamperTrail provides. It does not constitute a compliance certification or legal advice. Formal attestation requires an independent auditor's assessment of your complete environment, including organizational policies outside TamperTrail's scope.


6.1 SOC 2 Type II (Trust Services Criteria)

CriteriaRequirementTamperTrail ControlGap / Customer Action
CC6.1Logical access controlsRole-based auth, API key isolation, session management
CC6.3Access based on authorizationTenant-scoped access, per-user allowed_tenantsCustomer must manage user provisioning lifecycle
CC6.7Restrict confidential data transmissionEncrypted metadata; tags requires customer data classificationCustomer must provision TLS
CC7.2Monitor for unauthorized changesSHA-256 hash chain — tampering mathematically detectable
CC7.3Evaluate security eventsGET /v1/verify for on-demand chain integrity reports
CC9.2Third-party risk managementSelf-hosted — no third-party vendors in data path

6.2 HIPAA Security Rule (45 CFR Part 164)

SafeguardSpecificationTamperTrail ControlGap / Customer Action
§164.312(a)(1)Access controlRole-based auth, API key isolation
§164.312(a)(2)(iv)Encryption and decryptionFernet AES-128-CBC for metadata at restCustomer must not store ePHI in tags
§164.312(b)Audit controlsImmutable hash-chained audit log
§164.312(c)(1)IntegritySHA-256 chain — alteration is detectable
§164.312(e)(1)Transmission securityCustomer responsibility — TLS proxy requiredCustomer must provision TLS
§164.316(b)(2)RetentionConfigurable retention with checkpoint-safe pruning

6.3 GDPR (Regulation (EU) 2016/679)

ArticleRequirementTamperTrail RelevanceGap
Art. 5(1)(f)Integrity and confidentialityFernet encryption + hash chain integrity
Art. 25Data protection by designTwo-tier model separates searchable and encrypted fields by architectureCustomer must classify data correctly
Art. 32Appropriate technical measuresAES-128, Argon2id, rate limiting, RLSCustomer must provision TLS
Art. 44–49Transfers to third countriesNot applicable — zero data egress
Art. 17Right to erasureRetention policy enables time-bound deletionCustomer must configure retention appropriately

Honest note on GDPR scope: If personal data appears in audit records (actor email addresses, user IDs in tags), TamperTrail itself becomes a system processing personal data. The customer is the data controller and must assess proportionality and lawful basis independently.


6.4 ISO/IEC 27001:2022

ControlTamperTrail Implementation
A.8.15 — LoggingImmutable, tamper-evident audit log
A.8.16 — MonitoringGET /v1/verify for continuous chain integrity monitoring
A.8.24 — CryptographyAES-128, SHA-256, Argon2id, HS256 JWT
A.5.18 — Access rightsRole-based access, tenant isolation
A.8.9 — Configuration managementAuto-generated secrets, Alembic schema migrations

6.5 PCI DSS v4.0

RequirementTamperTrail ControlGap
Req. 10.2 — Implement audit logsCore TamperTrail function
Req. 10.3 — Protect logs from modificationSHA-256 hash chain — modifications detectable
Req. 10.5 — Retain logs 12+ monthsConfigurable; Pro tier supports 365 days / unlimitedFree tier: 30-day limit
Req. 8.3 — Strong authenticationArgon2id passwords, session management
Req. 4.2 — Encrypt data in transitCustomer responsibilityTLS proxy required

7. Honest Assessment of Current Limitations

This section documents known limitations of the current TamperTrail release. We believe transparency here is itself a security control — organizations should make deployment decisions with full knowledge of the current state.

LimitationDetailMitigation / Roadmap
No built-in TLS terminationNginx listens on HTTP. TLS must be provisioned by the customer upstream.Deploy a TLS-terminating proxy (Caddy, Traefik). This is standard architecture for self-hosted software.
No Hardware Security Module (HSM) supportEncryption keys are stored in config.json on the server_data volume — not in dedicated key hardware.Envelope encryption with MASTER_KEY enables AWS KMS / HashiCorp Vault integration. Native HSM support is on the roadmap.
No SSO / SAML / OIDCAuthentication is username/password only. No integration with enterprise identity providers.SSO (SAML 2.0 + OIDC) is on the near-term roadmap.
No formal compliance certificationTamperTrail has not undergone a third-party SOC 2 audit. We are a software product that enables compliance; we are not ourselves certified.This document provides the technical controls mapping to assist your auditors.
tags field is plaintextThe GIN-indexed search field is unencrypted by design (encryption would make it unsearchable). Organizations must enforce data classification in integration code.Clear documentation and tooling guidance are provided. Encryption of specific tag keys is under consideration for a future release.
Verification is eventually consistentGET /v1/verify reads the database at verification time. A sufficiently sophisticated attacker with database-level write access and hash-computation capability could, in theory, forge a consistent chain. This requires both database access and server code access simultaneously.Defense-in-depth: the database is not directly accessible from outside the Docker network. PostgreSQL is not exposed on any host port.
Log injection via compromised API keyA leaked API key allows writing false log entries — it does not allow reading, modifying, or deleting existing entries.Rotate API keys regularly. Monitor for anomalous ingestion patterns via GET /v1/stats.
WAL file stores data in plaintextIncoming log entries are temporarily buffered to a local WAL file (queue.wal) in plaintext JSON on the server_data Docker volume for crash recovery, before the background worker encrypts the metadata field and flushes the batch to PostgreSQL. This is standard practice — identical to how PostgreSQL's own WAL operates. The WAL file resides on the same server that holds the encryption key in memory, so encrypting the WAL independently provides no additional security boundary.Ensure the Docker host volume backing server_data is encrypted at the filesystem or block-device level (LUKS, BitLocker, encrypted EBS). This provides transparent at-rest encryption of the WAL, config, and all temporary files without application-layer overhead.
Single-worker processTamperTrail runs as a single Uvicorn worker (--workers 1). Concurrency is handled via Python's asyncio event loop, and hash chain integrity is enforced at the database level via PostgreSQL advisory locks. This is intentional — a single worker eliminates inter-process state contention and keeps memory usage predictable.No action required. Do not increase the worker count — it increases memory usage without throughput benefit, as the bottleneck is disk I/O and database commit latency, not Python concurrency.

8. Security Roadmap

The following capabilities are planned for future TamperTrail releases. They represent our commitment to continuous security improvement and enterprise-grade feature parity.

Near-Term

  • SSO Integration (SAML 2.0 + OIDC): Native integration with enterprise identity providers — Okta, Microsoft Entra ID (Azure AD), Google Workspace, and any SAML 2.0-compatible IdP. Enables centralized identity management and immediate access revocation via the IdP.

  • Granular Role-Based Access Control (RBAC): Per-resource permission scoping beyond the current admin/viewer model. Planned permissions: read-only log access scoped to specific tenants or date ranges, export permission gate, verification access control.

  • Forensic Export CLI: A standalone command-line tool for external auditors. Connects directly to the database with read-only credentials, decrypts metadata with a provided key, and outputs a fully verifiable, cryptographically signed export — independent of the running TamperTrail server. Designed specifically for evidence preservation in incident response and legal proceedings.

Medium-Term

  • Hardware Security Module (HSM) Support: Native integration with dedicated HSM hardware (Thales, Entrust, AWS CloudHSM) for organizations requiring FIPS 140-2 Level 3 key storage. The DEK would be generated and stored within the HSM — the plaintext key material never exists in software memory.

  • Audit Trail Self-Logging: TamperTrail logs its own administrative operations (API key creation, user provisioning changes, login events, retention policy changes) as tamper-evident system-tagged audit entries — a self-referential audit trail for the audit system itself.

  • Compliance Report Generation: Pre-formatted PDF/Excel reports for SOC 2, GDPR, and HIPAA auditors. Reports include chain verification summary, access control summary, key rotation history, and retention policy compliance — with admin password re-confirmation and full audit logging of the report generation action.

Long-Term

  • Webhook & SIEM Integration: Real-time alerts to SIEM platforms (Splunk, Microsoft Sentinel, IBM QRadar) and webhook endpoints (Slack, PagerDuty) when critical-severity events are detected or when chain verification fails.

  • Immutable Append-Only PostgreSQL Enforcement: Database-level write-once enforcement via PostgreSQL triggers — preventing UPDATE and DELETE operations on audit_logs at the database layer, independent of application behavior.

  • Cross-Instance Chain Federation: Cryptographic linking of audit chains across multiple TamperTrail instances — enabling enterprise deployments to maintain a single verifiable ledger across distributed infrastructure regions.


9. Incident Response Considerations

If You Suspect Log Tampering

  1. Run chain verification immediately: GET /v1/verify/deep performs a full re-hash of every entry and reports all broken links with precise timestamps and positions.
  2. Preserve the database: Take a PostgreSQL dump of the audit_logs table before any remediation. The ciphertext record is evidence.
  3. Review session history: GET /v1/sessions shows all login events with IP addresses and User-Agents. Anomalous logins from unexpected IPs may indicate credential compromise.
  4. Check WAL files: The Write-Ahead Log (/app/data/queue.wal) contains a sequential record of all ingested log items prior to database commit. It provides an independent record to compare against the database state.

If You Suspect Encryption Key Exposure

  1. Do not delete or rotate immediately — rotation without backup forfeits all historical metadata decryptability.
  2. Assess exposure scope: Determine which systems had access to the server_data volume or the configuration file.
  3. Generate a new encryption key using TamperTrail's key rotation mechanism — this key becomes the primary key for all new entries.
  4. Keep the old key in the rotation chain to preserve readability of existing records.
  5. Re-encrypt historical metadata during a maintenance window if re-encryption is required by your security policy.
  6. Audit GET /v1/sessions for any unexpected administrative access during the exposure window.

If You Suspect a Compromised API Key

A compromised API key enables log injection (writing false entries). It does not grant:

  • Read access to any log entries
  • Access to the dashboard or management APIs
  • Access to the metadata encryption key
  • Ability to modify or delete existing entries

Immediate response: Revoke the key via DELETE /v1/keys/{id}. The key becomes invalid for any new requests within milliseconds. Review recent ingestion activity for false entries using the time range filter in GET /v1/logs.


This whitepaper describes the security architecture of TamperTrail as of the version current at the document date. For the latest security information, consult the project repository.

Share this doc𝕏 Twitterin LinkedIn

Help improve these docs

See a typo or outdated information? Open a GitHub issue and we'll update it.

View Raw Markdown on GitHub