Skip to content

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.

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.

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.

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.

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.

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.

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.

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.