Caelum — Security Overview
A buyer-friendly summary of how Caelum protects your data. Hand this to your InfoSec team during a vendor security assessment.
Document ID: CAELUM-LEGAL-SEC-001 Version: 1.0-draft Last updated: 2026-04-30 Companion documents: DPA, BAA, Sub-processors
TL;DR
| Question | Answer |
|---|---|
| Where is my data? | Default: EU (Frankfurt, eu-central-1). Alternate regions on Enterprise election. |
| Is data encrypted at rest? | Yes — AES-256 by Neon (database) and underlying object storage. |
| Is data encrypted in transit? | Yes — TLS 1.2+ enforced; HSTS; HTTPS-only. |
| Is data isolated between tenants? | Yes — Postgres Row-Level Security with FORCE ROW LEVEL SECURITY + per-transaction app.tenant_id GUC. Cross-tenant access is structurally impossible at the DB layer. |
| Is the audit log tamper-evident? | Yes — hash-chained per tenant. The application database role lacks DELETE on audit_event. Tampering breaks the chain and is detectable. |
| Are e-signatures Part 11 compliant? | Yes — re-auth at signing, WebAuthn step-up, signed manifestation per §11.50, non-transferable per §11.70. |
| Do you have SOC 2 / ISO 27001? | SOC 2 Type I in scoping; Type II planned. Sub-processors (AWS, Vercel, Stripe, Anthropic) are SOC 2 Type II + ISO 27001 attested. |
| Will you sign a DPA / BAA? | Yes — both are available, drafts here. |
| Do you train AI on my data? | No — training-on-inputs is disabled in our enterprise agreements with Anthropic and OpenAI. |
| Do you allow penetration testing of my tenant? | Yes — coordinate with security@caelum.app at least 14 days in advance. |
Data protection
Encryption at rest
All Customer Data is encrypted at rest with AES-256 by the underlying database (Neon Postgres) and object storage providers. Key management is delegated to the cloud provider; rotation is automatic per the provider's KMS schedule.
Encryption in transit
TLS 1.2 or higher is enforced for all connections. HSTS is set with a 1-year max-age and includeSubDomains. HTTP requests are 308-redirected to HTTPS.
Tenant isolation
Postgres Row-Level Security is enabled with FORCE ROW LEVEL SECURITY on every tenant-scoped table (40+ tables). Every database transaction sets a per-transaction GUC app.tenant_id that the RLS policies use to filter rows. The application database role is non-superuser and cannot bypass RLS. Without a tenant id set, the application sees zero rows.
Audit trail
Every state-changing action emits an audit_event row containing the tenant id, actor user id, entity type, entity id, action, before/after payloads, reason, ULID, and a SHA-256 chain hash computed from the prior chain hash + tenant id + payload hash + ULID. A per-tenant advisory lock is taken before each insert to ensure the chain is unbroken under concurrency.
The audit log is append-only:
- The application database role lacks DELETE and UPDATE privileges
on audit_event
- No application code path issues UPDATE or DELETE against this table
- A chain-verifier utility re-computes the chain end-to-end and flags
any inconsistency
Electronic signatures (21 CFR Part 11)
Approvals, document promotions, and other signed actions require an electronic signature. The signature workflow:
- The user is prompted with the entity hash and a free-text reason
field
- The system verifies the user's session is fresh (per a tenant-
configurable inactivity threshold) and prompts for WebAuthn step-up if not
- The signature manifestation captures: signer name, role, ISO
timestamp, reason, entity id, entity version, and the SHA-256 hash of the entity payload
- The manifestation is rendered into the audit-ready PDF export
Signatures are non-transferable: the manifestation hash binds the signature to the specific entity id and version.
Identity and access
Sign-in
- OIDC SSO supported with Google Workspace, Microsoft Entra ID, Okta
- Demo / fallback password sign-in available in non-production only
- Passwords (where used) are stored as bcrypt hashes with cost ≥ 10
- Failed sign-in attempts are rate-limited and audit-logged
Authorisation
- Role-based access control enforced server-side
- Roles: SUPER_ADMIN, QA_ADMIN, RA, RD, MFG, CLINICAL, AUDITOR
- Client-side gating is a UX courtesy; every action re-validates
authorisation server-side
- Platform-operator access (
/backend) is a separate auth realm with
no shared credentials
Public API
- Bearer-token authentication
- Tokens stored as bcrypt hashes; the plaintext token is shown to the
user once at creation
- Tokens are tenant-scoped; they cannot read data from another tenant
- Read-only — no POST/PUT/PATCH/DELETE paths on
/api/v1 - Per-token rate limit (60 requests / minute by default)
- Revocation is immediate (within 60-second cache window)
Application security
Secure development lifecycle
- Code review required for every PR
- Type-checking, lint, unit tests, automated IQ + OQ subset on every
PR
- Dependency vulnerability scanning (
npm audit, Dependabot) - Secret scanning enabled at the SCM layer
- Annual third-party penetration test (results summarised; full report
available under NDA)
HTTP hardening
- HSTS, CSP, X-Frame-Options DENY, X-Content-Type-Options nosniff,
Referrer-Policy strict-origin-when-cross-origin
- Cookies: Secure + HttpOnly + SameSite=Lax
- Stripe webhooks: signature-verified before processing
Input handling
- ORM-mediated queries (Prisma) — no string-concatenated SQL
- Strict input validation on every server action via Zod schemas
- HTML sanitisation on rendered Customer Data via DOMPurify
AI safeguards
- Provenance captured on every AI generation (model, prompt hash,
retrieved chunk ids, output hash, latency, cost)
- AI output is labelled DRAFT and cannot auto-promote to EFFECTIVE
- Helpdesk Autopilot mode sends only when AI confidence ≥ tenant-
configured threshold; both threshold and confidence are persisted
- Training-on-inputs is disabled with Anthropic and OpenAI
Operations
Hosting
- Application runtime: Vercel (multi-region, EU edges preferred for
EU tenants)
- Database: Neon Postgres on AWS (eu-central-1 default)
- All providers: SOC 2 Type II + ISO 27001 attested
Backups and recovery
- Continuous backup with point-in-time recovery (Neon, RPO ≤ 60 s)
- PITR window: ≥ 7 days
- Cross-AZ redundancy at the database layer
- Annual disaster-recovery exercise (restore from PITR into a
recovery instance, verify hash-chain integrity, signed by SRE Lead + QA Lead)
- Recovery Time Objective: ≤ 4 hours for primary-region failure
Monitoring
- Application errors: Sentry (with PII scrubbing)
- Uptime: external synthetic monitor + status page at status.caelum.app
- Anomaly alerts to the on-call engineer
Incident response
- 24×7 on-call rotation for P0 / P1 incidents
- Documented runbook in
docs/runbooks/ - Personal Data Breach: customer notification within 24 hours of
awareness per the DPA
- HIPAA Breach: customer notification within 60 days per the BAA
Compliance posture
| Framework / Regulation | Status |
|---|---|
| EU GDPR | DPA available; EU SCCs + UK Addendum incorporated |
| HIPAA | BAA available; safeguards per 45 CFR §§164.308, .310, .312 |
| 21 CFR Part 11 | Compliant (audit trail, e-signature, controls) |
| EU MDR / IVDR | The platform is not a regulated device; the platform supports Customer's MDR/IVDR compliance |
| ISO 13485 | Caelum operates its own QMS using Caelum (eats own dog food); not yet ISO 13485 certified |
| ISO 27001 | Pursuing in 2026 |
| SOC 2 Type I | Scoping in progress |
| SOC 2 Type II | Planned for 2026 |
| EU AI Act | Provenance + human-oversight architecture aligned with Articles 12–14, 16 |
| Cyber Essentials Plus (UK) | Considering, dependent on UK customer pull |
Data residency and regional posture
| Region | Hosting | Default for |
|---|---|---|
| EU (Frankfurt) | Vercel EU edges + Neon eu-central-1 | All EU/UK/CH/NO tenants |
| US (East) | Vercel US edges + Neon us-east-1 | US tenants on election |
| Multi-region active-active | Available on Enterprise | On request |
Data does not transit outside the customer's elected region except through the AI sub-processors (Anthropic / OpenAI), which today operate from the US. Customers concerned about US AI processing can disable AI features per tenant.
Vulnerability disclosure
If you believe you have found a vulnerability, email security@caelum.app with details. We acknowledge within 24 hours, triage within 72 hours, and provide a remediation timeline within 7 days. We do not currently operate a paid bug-bounty program but offer responsible-disclosure recognition on https://caelum.app/security.
Customer-side responsibilities
This security model assumes Customer:
- Provisions Authorised Users with appropriate roles
- Disables accounts for terminated employees promptly
- Configures the identity provider with MFA and conditional access
per Customer's own policy
- Reviews the audit log periodically
- Performs the Performance Qualification (PQ) on its tenant per the
Validation Pack
- Notifies Caelum of any suspected security event affecting
Customer's tenant
Document version
| Version | Date | Change |
|---|---|---|
| 1.0-draft | 2026-04-30 | Initial overview |