Security isn't a feature we bolt on.
It's how every line is written.
Twelve disjoint encryption keys. Per-route RBAC against sixty-one permissions. A hash-chained audit log enforced by database triggers. Single-tenant infrastructure on dedicated hardware. The MoonFactory security posture is engineered — and documented.
Section A
Encryption Architecture
No master key. No shared secrets. Compromise one slice, not the platform.
- Twelve AES-256-GCM keys with disjoint per-column scoping. Each key protects one specific data type — credentials, session tokens, lead-capture payloads, OAuth tokens, payout details — and one only.
- Rotation CLI with a CI guardrail that fails the build if a column is encrypted with an undeclared key.
- Keys live in a single registry (KEY_REGISTRY) that the application reads at boot. No keys hardcoded, no keys in source control.
- The blast radius of any one key compromise is the column it protects — not the database.
Section B
Authentication & Access Control
Six roles, sixty-one permissions, zero global auth middleware.
- Six-role RBAC: viewer → support → financial admin → admin → owner → engineer. Each role is a strict superset of the one below it, except engineer (which carries owner + technical permissions).
- 61 named permissions enforced per-route. Every protected endpoint declares its required permission explicitly. There is no global middleware to bypass (ADR-002).
- TOTP-based MFA on every staff and affiliate account.
- Sensitive operations (payouts, tax data export, account deletion) re-challenge if your last MFA verification is older than 15 minutes.
- Magic-link login for clients — no passwords to store, leak, rotate, or remember.
- Admin and affiliate credentials hashed with bcrypt at cost 12.
- Atlas embed API keys: prefix-indexed for fast lookup, bcrypt-hashed at rest, raw value shown exactly once.
Section C
Audit Integrity
Tamper-evident by construction, not by policy.
- Append-only ledger enforced by database triggers. The audit_log table physically rejects UPDATE and DELETE — at the engine level, not the application.
- Hash-chain linking: every row's entry_hash is SHA-256 of the previous row's hash plus the new row's payload. Insert a fake row in the middle, the chain breaks, the tampering is visible.
- 180+ tracked action types across every surface — admin actions, system actions, webhook actions, cron actions.
- A serial in-process tail guards concurrent writes against racing into the same previous-hash.
- System-driven events use a sentinel SYSTEM_ACTOR_ID so cron, webhook, and worker events are first-class in the audit trail.
Section D
Data Privacy
GDPR-aligned by design. Not a banner. A lifecycle.
- GDPR lifecycle: soft delete → 30-day cooldown → automatic anonymisation. Restorable until the cooldown elapses; cryptographically erased after.
- Data export endpoint serves right-of-access requests in a machine-readable format.
- Consent-gated analytics — no Umami tracking pixel until the visitor opts in.
- Per-column encryption of all PII: names, emails, addresses, tax IDs, payout details, OAuth tokens.
- 7-year invoice retention for tax/legal compliance; everything else erasable on request.
- Self-hosted Umami means no third-party analytics processor — your visitor data does not leave our infrastructure.
Section E
Infrastructure
Single-tenant. SSH-key only. No public database port.
- Single-tenant Hetzner dedicated server (CCX33). Not shared hosting. Not a VPS pool.
- SSH key-only access — password authentication is disabled at the sshd level.
- Postgres has no public port. The database is reachable only from inside the container network.
- Cloudflare proxy fronts every public hostname with TLS termination and DDoS shielding.
- Backups via pgBackRest: full, differential, and incremental schedules with point-in-time recovery to three destinations — local, Hetzner Storage Box, and Cloudflare R2.
- EasyPanel-managed Docker Swarm for orchestration; rolling deploys with health-gated promotion.
Section F
Compliance Posture
Regulation is engineering work. We treat it as such.
- GDPR — Articles 6, 7, 12–17, 20, 25, 30, 32, 33 mapped to code-level evidence in our compliance matrix.
- FTC 16 CFR Part 255 — automated weekly disclosure audit for affiliate program. First flag is a notice; sustained non-compliance escalates to commission holds and program termination.
- IRS 1099-NEC — automated annual generation pipeline via Track1099, threshold-driven.
- CCPA — same controls as GDPR, with California-specific opt-out surfaces where required.
- WCAG 2.2 AA — accessibility treated as security of access. Lighthouse 100% enforced in CI on every build.
Section G
Monitoring
Watch the watchers. Then watch them again.
- GlitchTip self-hosted error tracking. No third-party error processor; no exception data leaves our infrastructure.
- 25+ scheduled jobs each monitored by a Healthchecks.io dead-man switch. If a cron misses its window, on-call gets paged.
- Uptime monitoring via Checkmate with a public status page.
- Privacy-first analytics — self-hosted Umami, consent-gated, cookieless.
- Per-cron success and failure pings via pingHealthcheck — the absence of success is a failure, by design.
Questions about our security posture?
We're happy to walk a CTO, compliance officer, or curious operator through the architecture. Send a message — we'll set up a call.
Let's talk