Security & data protection overview
This page describes what is actually built and enforced in the current version of Railflo — not a roadmap. Where something is a stated intention rather than a live, checked guarantee, it’s labelled as such.
Tenant isolation
Section titled “Tenant isolation”Every table holding tenant data has row-level security enforced at the database level, not just in application code — a query that somehow forgot its tenant filter still cannot see another tenant’s rows, because Postgres itself refuses. This is tested generically: a real test suite enumerates every RLS-protected table via the database’s own policy catalogue and proves cross-tenant isolation on each one, so a newly added table without its own isolation policy fails that test rather than silently shipping unprotected.
Encryption
Section titled “Encryption”Patient identifiers (IHI, MRN) and demographic fields are encrypted at rest with AES-256-GCM, under a per-tenant data-encryption key that is itself wrapped by a master key — never a single shared key across all tenants. Lookups (e.g. “find the patient with this IHI”) work via a blind index, so matching doesn’t require decrypting every candidate row.
Where AI models are and aren’t used
Section titled “Where AI models are and aren’t used”Railflo’s document classification and extraction pipeline is designed to enforce EU data residency for any model call at boot time — the application refuses to start if a configured model provider’s region isn’t on an explicit EU-region allowlist. This is a mechanical check, not a policy document.
Today, no live third-party model credential is configured in this build — extraction runs against a deterministic test double in every environment that exists right now. The residency enforcement is real and already active; the live model connection it will apply to is not yet provisioned. This page will be updated the day that changes.
Audit trail
Section titled “Audit trail”Every exchange, every consent decision, every document pipeline stage, and every access to a patient’s protected identifier is written to an append-only audit ledger — including denied actions, not only successful ones. Nothing in Railflo, including Railflo’s own internal tooling, writes clinical data without a corresponding audit entry.
What never appears in logs
Section titled “What never appears in logs”Application logs go through a shared, allowlist-based redaction layer — a field has to be explicitly named as safe to log before it can appear at all, rather than being redacted after the fact by a denylist. Patient names, dates of birth, and identifiers are not on that allowlist.
Authentication
Section titled “Authentication”Console access requires email + password + mandatory TOTP two-factor for every account — there is no way to disable the second factor. Sensitive actions (revealing a masked identifier, minting an API key) require a fresh re-authentication (“step-up”) even within an already-valid session.
Hosting and residency — honestly, this section is not finished
Section titled “Hosting and residency — honestly, this section is not finished”No production hosting environment, region, or account has been provisioned yet. The application is built to be deployed into an EU region (and the model-residency enforcement above is one concrete piece of that), but there is currently no live production infrastructure to make a residency claim about. This section will be replaced with real, verifiable hosting details once a production environment exists — not before.
Questions
Section titled “Questions”If you’re evaluating Railflo as part of a DPO or security review and need something not covered here, ask — this page is deliberately conservative about what it claims, and a direct question usually gets a faster, more precise answer than trying to infer it from this document.