Skip to content
PokerEnginePro
Security & compliance

Secure from the start.
Ready for the regulator.

Delegated identity, locked-down workloads, regulator-grade records and responsible gaming by design. Built for the regulator who reads the records, the laboratory that tests the changes, and the player who asks for their data.

Identity

Identity, delegated.
No passwords held.

Players and staff sign in through any OpenID Connect provider — Keycloak by default — in separate realms; the platform never holds a password.

Multi-factor for players and staff

TOTP and brute-force protection from the identity provider, enforced for every staff account.

A session outlives no token

An open connection closes when its token expires or the account is suspended; the client renews its token on the open connection instead.

No development shortcuts in production

Development sign-in works in Development only; anywhere else, a service without an identity provider refuses to start.

Players

realm
poker
client
poker-web · public, PKCE S256
audience
poker-platform
role
Player
policy
TOTP · brute-force protection

Staff

realm
poker-staff
client
poker-backoffice · public, PKCE S256
audience
poker-admin-api
roles
Ops · Finance · Risk · Compliance · Support · Marketing · Auditor · SuperAdmin
policy
TOTP · brute-force protection
Two realms in the identity provider — players and staff never share one. As the platform ships its identity provider’s configuration.

Private PKI

Your own CA.
Strict by default.

Trust an in-house identity provider's private CA without relaxing anything, and refuse a revoked certificate — strict by default.
  • Strictthe default

    Refuses a certificate that is revoked — and one whose status cannot be learned within ten seconds.

  • RevokedOnlyfor a private CA

    Refuses a revoked certificate; accepts an unknown status with a warning on every fetch, for a CA that publishes no CRL or OCSP responder.

  • Offsaid out loud

    Checks nothing, and says so once at startup.

values.yaml · staffAuth
staffAuth:
  # The staff identity provider for the admin API: a realm apart from the players', with MFA
  # and session policy set there. Empty means the development header scheme — and outside Development the
  # admin API refuses to start without it, so a real install sets this whenever adminApi is enabled.
  authority: ""
  audience: poker-admin-api
  # As auth.ca, for the staff provider: mounted into the admin API and passed as
  # StaffAuth__CaCertificatePath. The same Secret as auth.ca when one CA issued both.
  ca:
    secretName: ""
    key: ca.crt
  # As auth.certificateRevocation, for the staff provider: StaffAuth__CertificateRevocation on the admin API.
  # Empty means Strict.
  certificateRevocation: ""
packaging/helm/pokerenginepro/values.yaml — the staff provider's settings, as the chart ships them. The CA is a Secret, never a ConfigMap: whoever can change it decides which provider is trusted.

Workloads

Locked-down workloads.
Least privilege, per pod.

Non-root, no capabilities, default seccomp, NetworkPolicies per workload and secrets only from Kubernetes Secrets.
  • Secrets from Secrets. Database, cache, bus and archive-key credentials, and identity-provider CAs, are read only from Kubernetes Secrets — never from values files.
  • Hardened web apps. A Content-Security-Policy, nosniff, frame denial, referrer and permissions policies — and cross-origin access off unless an origin is listed.
  • Hole cards stay hidden. A hole card never appears in a broadcast, a log line or a staff view of a live hand.
values.yaml · security contexts
# Every workload runs unprivileged: the images run as a non-root user (packaging/docker/Dockerfile:
# USER $APP_UID) and need no capabilities, so the rendered pods meet the restricted Pod Security
# Standard. Kept as values for a runtime that insists on its own (OpenShift assigns the user itself).
podSecurityContext:
  runAsNonRoot: true
  seccompProfile:
    type: RuntimeDefault
containerSecurityContext:
  allowPrivilegeEscalation: false
  capabilities:
    drop: [ALL]
packaging/helm/pokerenginepro/values.yaml — every pod, as the chart renders it.

111 / 111

checks on a production-shaped cluster

real sign-in, autoscaling, failover, network policies — zero pod restarts

Records and retention

Records kept for the regulator.
For as long as they ask.

13 months live, a searchable history database, then SHA‑256-checked archive files encrypted with AES‑256‑GCM on write-once storage.
  1. Months 1–13

    Live database

    Every hand, entry and result, read by players, the game and the back office — never under twelve months.

  2. Month 14

    Archived, after a clean reconciliation

    Exported, read back, hashed and encrypted; copied row for row to the history database; only then dropped from the live one.

  3. Months 14–24

    History database

    Hands with their replays, entries and results, still searchable; the records stay for the legal period.

  4. Retention period

    Archive files

    SHA‑256-checked, AES‑256‑GCM encrypted, on write-once storage — players by id only.

Nothing leaves unreconciled

A month leaves the live database only after a clean reconciliation that started after it ended, and only once its copy matches row for row.

Tamper-evident archives

Every archive file is SHA‑256-hashed and its manifest's hash kept in the database; a changed byte, a moved chunk or the wrong key and the file does not read.

Players by id only

The history database and the archive files hold players by id, never by name, so closing an account never has to touch write-once storage.

Evidence a laboratory can read

Rake recorded per player, voids and refused settlements as significant events, every reconciliation run kept, and hand logs that replay to the same state.

The player

Protect the player.
Keep the books.

Limits that only tighten, self-exclusion enforced at the seat, a player's whole record on request — and an account closed without a hole in the ledger.

01

Responsible gambling

Deposit, loss and wager limits and a session length, cool-off, self-exclusion and reality checks — each at the market's own settings, enforced at the gateway and again at the table.

02

National self-exclusion registers

GAMSTOP, Spelpaus, ROFUS, OASIS, RGIAJ, CRUKS, BetStop and six US state lists, checked before real money with the operator's own list — a register that cannot be asked fails closed.

03

Player data on request

One player's whole record, across every tier, exported in one audited step.

04

Account closure that keeps the books

A grace period, then anonymisation — and the ledger still balances.

Closing an account

  1. 01

    Asked

    The player asks to close their account.

  2. 02

    Grace period

    The account waits, pending deletion — the player can still change their mind.

  3. 03

    Anonymised

    The name, email and sign-in subject are removed; hands they played lose the name too.

  4. 04

    Books intact

    Ledger entries and the id stay, so every account still balances.

Markets

Every market, its own rules.
Configuration, not code.

Who the player is, where they are, and what that jurisdiction allows — checked before a seat, a tournament entry or a lobby listing.

KYC, AML and sanctions

Identity verified in tiers, money watched by the platform's own monitoring rules, and every player screened against sanctions and PEP lists — through at least two vendors for identity and for screening.

Geolocation and geofencing

The player's location checked at connect, on an IP change and every 20 or 30 minutes as the market requires — with certified device geolocation where a regulator asks for it.

Jurisdiction rule packs

Each market's rules as a signed rule pack — Great Britain, Malta, Curaçao, the US online-poker states, Ontario and more — configuration, not code, reviewed by the licensee's counsel before real money.

Vendor adapters

Payments, identity, geolocation, sanctions, AML, self-exclusion, messaging and ads behind interfaces with contract tests — swap vendors without touching the game.

Collusion and bot detection

Soft play, team play, multi-accounting, bot and real-time-assistance signals, worked as cases in one integrity queue.

Change control

Built to be certified.
Every change, classified.

Every regulated change classified major or minor in a change record with its evidence and lab-submission fields.
  • Major or minor, with the reasoning in the record — a change to the ledger or to how the rules are implemented goes to the laboratory.
  • Why it changes, what changes, the evidence, and how to deploy and roll it back.
  • Fields for the operator's laboratory submission and release authority, so the record travels with the release.
change record · CR-2026-09-27-B
| Change id | CR-2026-09-27-B |
| Date | 2026-09-27 |
| Classification | **Major — submit to the test laboratory before production use** (see below) |
| Depends on | CR-2026-09-27-A (deployed first) |
| Laboratory submission | _to be completed by the operator: laboratory, reference, date_ |
| Authorised by | _to be completed by the operator's release authority_ |

## Classification and justification
The header of a major change record, as the platform keeps it for the regulator.

Bring your compliance team.
We will bring the evidence.

A live walkthrough of the engine, the back office and a production-shaped cluster — with the numbers behind every claim on this site.