Skip to content
← back to home

Security & regulatory posture

How Caelith protects regulated fund-manager data, evidences its claims, and constrains its AI surface. This page is maintained alongside the codebase. Last updated: 2026-04-25.

IsolationRow-Level Security on every query

  • PostgreSQL SET LOCAL app.tenant_id binds every connection to its tenant before any data query runs. Cross-tenant reads are refused by the database tier under Row-Level Security policies — not relied on at the application tier alone. Verified by the unit invariant suite + cross-tenant e2e specs.
  • Application-level helpers queryWithTenant() and executeWithTenant() enforce a tenant clause and set the RLS context together. Direct pool.query() calls are forbidden for tenant data.
  • JWT auth middleware rejects any token missing tenantId. There is no anonymous path to tenant data.
  • RLS is enforced by default in every environment. Local development requires an explicit RELAX_RLS_ON_STARTUP=1 opt-out.

Tamper-detectabilitySHA-256 append-only audit chain

Every sealed compliance decision is hashed and linked to its predecessor. The structure is identical to a blockchain primitive: integrity_hash = SHA-256(canonical_record + previous_hash).

  • A single edit to any record breaks every downstream hash and is detected on the next chain verification pass.
  • Internal control, not third-party-attested. The chain is an internal tamper-detection primitive: an honest verifier with read access can re-compute SHA-256 to detect post-hoc modification. It is not externally timestamped (no RFC 3161 TSA anchor, no eIDAS-qualified electronic signature per Reg. (EU) 910/2014 Arts. 25-34 and no qualified electronic timestamp per Art. 42) and is not, on its own, regulator-admissible without independent third-party attestation. We expose per-tenant verification via GET /integrity/verify (authenticated, scoped to the caller's tenant). A public anonymous verification endpoint with anchored timestamping is on the roadmap; until it ships we do not assert public verifiability.
  • The genesis block uses an explicit zero-hash so the chain has no implicit anchor. Records cannot be retroactively prepended.
  • PII fields in audit records are pseudonymized (logged as {changed: true} rather than full values) per GDPR Art. 32(1)(a).

AuthenticationCookies, rotation, lockout

  • JWT access token (30 min) plus rotated refresh token (7 days). Both delivered via httpOnly SameSite=Lax cookies, secure flag in production. JavaScript cannot read them.
  • Passwords hashed with bcrypt (cost ≥ 10). No plaintext storage; no reversible derivation.
  • Account lockout: 5 attempts per IP, 25 globally per email within 15 minutes.
  • Sandbox sessions issue a per-visit sandboxSessionId embedded in the JWT for audit attribution. Sandbox tokens expire after 2h and the tenant is auto-cleaned on the next login.

ResidencyEU-West only

  • Application and database hosted on Railway in the EU-West region (Netherlands (EU-West region)). Data does not leave the EU.
  • Postgres connections enforce SSL/TLS; the PG_SSL_REJECT_UNAUTHORIZED=false exemption is required only because Railway internal proxies use self-signed certs — the underlying transport is still encrypted.
  • Sub-processors are listed in a single canonical registry at docs/legal/sub-processors.md (authoritative for this page, /privacy, /dpa, /trust, and docs/legal/dpa-template.md). Currently active: Anthropic (AI inference, USA endpoint, EU-US DPF), Railway (hosting, EU-West Netherlands (EU-West region)), OpenAI (optional embeddings only), Sentry (conditional error monitoring), OpenSanctions (sanctions screening, EU-based — mocked in sandbox), Plausible (cookieless analytics, EU). Previously evaluated but no longer active: MiniMax (reverted 2026-05-17 before any production data was processed); full audit trail and re-disclosure conditions per GDPR Art. 28(2) recorded in canonical registry §2.

AI governanceEU AI Act Art. 13/14 transparency

  • Caelith's agent provides assistive automation for compliance workflows. It does not constitute legal, regulatory, or compliance advice. All outputs require independent verification by a qualified professional.
  • Destructive or irreversible actions (create filing, submit filing, mutate task) require explicit human confirmation via a four-tool gate before execution.
  • Every agent action is recorded in the tamper-detectable audit chain with the prompt, the model, the inputs considered, and the outcome.
  • The agent does not train on tenant data. Anthropic is configured for zero-retention inference where supported.
  • Sanctions screening output carries explicit _provider_mode, _match_type, and _disclaimer fields so consumers can't accidentally treat heuristic matches as authoritative.

NetworkEdge controls

  • HSTS preload, Content-Security-Policy, Permissions-Policy, Referrer-Policy, X-Content-Type-Options, X-Frame-Options DENY, COOP same-origin, X-Request-Id are all set on every response. Verifiable from any browser DevTools tab.
  • Rate limits run on a shared DB-backed store so they hold consistently across Railway replicas, not per-process memory.
  • The /api/auth/me endpoint distinguishes 401/403 (genuine auth failure) from 5xx/network errors so a transient backend blip does not silently log a visitor out.

Filing pipelineState machine + four-eyes gate

  • Workflow states: draft → validated → pending_approval → ready_to_submit → submitted → acknowledged → accepted/rejected. Every transition is recorded with actor, timestamp, and hash entry.
  • Annex IV XML is validated against the official ESMA schema (AIFMD_DATAIF_V1.2.xsd) before any submission attempt.
  • BaFin filing uses WS-Security SOAP with a dryRun mode for non-production tenants. Sandbox tenants always operate in dryRun; outputs are valid XML but never reach a real regulator.
  • Eight NCAs supported: DE and LU automated; AT, FR, NL, IE, IT, ES manual XML upload.

Open sourceAnnex IV serializer

The Annex IV XML serializer (Zod schemas, XSD validation, 107 unit tests) is published as an Apache-2.0 standalone package at packages/open-annex-iv. Any AIFM, vendor, or regulator can audit, reuse, or fork it independently of Caelith.

Last verified against code on 2026-05-20.

ReportingVulnerability disclosure

Security issues: security@caelith.tech. We commit to acknowledging receipt within 48h. Coordinated disclosure preferred; we will not pursue legal action against good-faith research that respects user data and service availability.

This page is maintained alongside the codebase. Specific claims can be verified by inspecting the referenced files and endpoints. For an executable trust check, the TrustFooter on any agent surface verifies the SHA-256 hash chain live.