Security & compliance
How the platform protects data, and the compliance tooling it ships. Relevant to iGaming operators handling player PII and financial history.
Isolation
- Row-Level Security (RLS) enforces multi-tenant/brand isolation in the database — not only in application code. Every brand-scoped table has policies that constrain reads/writes to the caller’s assigned brands. See Database & RLS and RBAC & permissions.
- The Platform Owner operates cross-tenant through the same RLS, via super-aware helper functions — no separate bypass path.
Authentication & secrets
- Operator API keys are stored as SHA-256 hashes — the raw
plq_…value is shown once and never persisted. Keys can be brand-pinned and carry least-privilege scopes (events:writefor ingestion). See PAM Integration → Authentication. - The service-role API-key backdoor is off unless
ALLOW_SERVICE_ROLE_API_KEY=true— never enabled in production. - Operator sessions use Supabase Auth with cookie-based SSR sessions.
- Outbound webhooks are HMAC-SHA256 signed (
X-PlaylogiQ-Signature); receivers verify against the shared secret. See Outbound webhooks.
Transport & network
- All external traffic is HTTPS; Caddy terminates TLS and auto-renews certificates. Internal services talk over the Docker network; Postgres, Redis, and the Supabase internals are not publicly exposed.
Data residency & ownership
The stack is self-hosted (see Deployment) — the
database, including append-only player_events and balance_transactions, lives
on the operator’s own server, backed up off-site to a Hetzner Storage Box.
Nothing is sent to a managed third-party data plane.
GDPR tooling
The platform ships right-to-access and right-to-erasure for players (Players → a player → GDPR actions):
-
Data export — gathers the player’s rows (identity, profile, events, sessions, transactions, consent) for a subject-access request.
-
Erasure —
gdpr_erase_player()anonymizes the PII-bearing rows (email, phone, name, gender, metadata cleared; status set toclosed;external_idreplaced with an opaque token) and removes contact channels and delivered messages, while retaining financial/event history keyed by an opaque UUID for regulatory retention. The player is marked witherased_at. The function is tenant-guarded (SECURITY DEFINER+ explicitp_tenant). -
Consent — a master marketing consent plus per-channel consent is respected by all outbound messaging; suppression lists and frequency caps add further guardrails.
Responsible gaming
RG enforcement (limits, self-exclusion, cooling-off) is owned by the operator’s
PAM. PlaylogiQ consumes those signals as events (limit_set,
self_exclusion, cooling_off, status_changed) and reflects them on the
player, but does not itself act as the RG controller.
Audit
Sensitive actions are recorded in the audit log (Settings → Audit log), readable by tenant admins and above.
Go-live hygiene
Rotate any keys/secrets shared during development, confirm production .env
values, keep .env backups out of world-readable paths, and re-tighten the
server deploy key to read-only. The authoritative checklist is in the project
CLAUDE.md. See also Deployment.