FDE On-Prem. Real-time fraud decisioning
that runs entirely inside your bank.
Your data stays on your infrastructure. Your PKI stays under your control. Your auditors get evidence, not promises.
Two install paths, one codebase
Pick the one that fits your bank's infrastructure team. Same decisioning engine, same dashboard, same audit evidence — different runtime.
Docker Compose
Single-host deployment. 5-service stack: engine, dashboard, PostgreSQL, Redis, nginx. Fastest way for bank infra teams to stand up a full evaluation environment.
- 1Drop the release tarball onto the host
- 2Pick
plain(HTTP) ortls(TLS 1.3 + mTLS) compose overlay - 3
gen-certs.shfor Mode A, or drop a bank-signed bundle for Mode B - 4
docker compose up -d— live
Ansible / bare-metal
No Docker required. 7 Ansible roles deploy engine, dashboard, PostgreSQL, Redis, nginx, pgbouncer, plus shared TLS role. Validated on a 2-VM topology (app VM + dedicated PG VM).
- 1Define your inventory (app host + PG host)
- 2Set
fde_tls_internal: truefor full-mesh mTLS - 3Mode A: Ansible generates CA. Mode B: drop bank bundle into
fde_tls_source_dir - 4
ansible-playbook -i inventory.ini site.yml
Architecture topology
The Ansible 2-VM reference layout. Every internal hop carries TLS 1.3 when fde_tls_internal: true.
nginx is not optional in multi-worker mode. Without it, HTTP keep-alive pins TCP connections to single uvicorn workers and throughput collapses. Auto-installed by the fde-nginx role.
pgbouncer is disabled by default. Benchmarks showed it added 5–20 ms with no throughput benefit because FDE workers maintain warm long-lived asyncpg pools. Enable only at >8 app-tier nodes.
pgbouncer + fde_tls_internal: true is incompatible in v1 — the Ansible role fails that combination intentionally. pgbouncer + TLS is on the roadmap.
Validated banking-tenant performance
Every number below runs the full banking rule chain on every request — over a TLS 1.3 mutual-TLS service mesh, with PII-encrypted decision snapshots and synchronous zero-data-loss persistence — on a single 8-core KVM lab machine. Zero errors in every run. Lab measurements only — not a performance guarantee. Your hardware, network, tenant config, and rule mix will affect results.
/v1/risk/evaluate by RTD's open benchmark harness (JWT + HMAC auth, concurrency 1→40, plus a 60 s sustained run at c=20; database truncated before each run). The engine is stateless and scales linearly per core, so server-class hardware will exceed these numbers. These are lab measurements — not a performance guarantee, and not an extrapolated per-server capacity claim.
Every event, all rule triggers, the audit outbox, and the PII-encrypted decision snapshot are durably committed before the API responds. We re-verify the invariants after every run — events equal requests, rule-trigger rows equal 33 × events, snapshots map 1:1 — and recorded zero errors in every published run.
Profiling-driven engine optimization on identical hardware — hot-path CPU elimination, configuration caching, and connection-pool tuning. No safety posture was relaxed: the full 33-rule chain, mutual-TLS mesh, PII-encrypted snapshots, and synchronous zero-data-loss persistence stayed on for every run.
Looking for horizontal scale-out across nodes? See the cloud multi-node benchmark — 1,000+ TPS, rule engine → A different test on different hardware — read the two side by side, not added together.
Security & TLS posture
Zero-trust by default when you flip fde_tls_internal: true. Every internal hop is mutually authenticated.
| Hop | Protocol | Cert | Auth |
|---|---|---|---|
| Bank client → nginx | TLS 1.3 | Server (edge) | Server auth |
| nginx ↔ engine | TLS 1.3 | EC P-256 leaf | mTLS |
| engine → PostgreSQL | TLS 1.3 | EC P-256 leaf | mTLS sslmode=verify-full |
| engine → Redis | TLS 1.3 | EC P-256 leaf | mTLS rediss:// |
| dashboard → engine | TLS 1.3 | EC P-256 leaf | mTLS |
Two PKI modes
Audit evidence auditors can paste into their tooling
PostgreSQL emits a tls_connection event per connection with version, cipher, and verified status. Redis emits tls_handshake_verified at startup and on every reconnect (redis-py does not expose per-socket SSL metadata, so cipher/version are recorded as unknown for Redis).
# Count TLS 1.3 PostgreSQL connections over the last 24h jq -r 'select(.event=="tls_connection" and .tls_version=="TLSv1.3" and .verified==true)' \ /var/log/fde/audit.ndjson | wc -l # Any failed TLS verifications? jq -r 'select(.event=="tls_connection" and .verified==false) | {ts, peer, reason}' \ /var/log/fde/audit.ndjson
Queries map directly to FFIEC CAT, MAS TRM §10, and BNM RMiT §11 audit asks.
ansible-playbook --tags common,tls-rotate; Mode B banks reissue their bundle and operator reruns --tags common,tls (--tags tls-rotate is explicitly not supported in Mode B). Reload-not-restart where supported.
FDE TLS & Audit Pack
PDF posture summary, audit-query catalog (sample jq queries mapped to FFIEC CAT / MAS TRM §10 / BNM RMiT §11), and cert lifecycle runbook. Share it internally — no form gate, no lead capture.
Compliance posture
FDE ships with built-in rule-to-regulation mappings. We don't claim certification — we produce the evidence auditors use to certify your deployment.
FDE supports requirements such as those listed above. Consult your own counsel for formal compliance mapping. Data residency is a deployment property — FDE runs inside your data-residency boundary; cross-region data movement is your choice and your network fabric.
Talk to us about an on-prem PoC
30-minute technical walkthrough with the team that built it. We'll cover topology, TLS posture, cert lifecycle, and what an evaluation deployment looks like in your environment.
Talk to Us