# Security considerations

- All chips are free non-redeemable virtual units. Do not add real-money payment or payouts.
- Email OTP with HMAC storage/expiry/attempt limits, optional SMS when configured, optional Argon2id passwords; configure SMTP for real delivery.
- Session cookies are httpOnly and sameSite=lax; unsafe API routes require origin and session-bound CSRF check. Set HTTPS and correct `WEB_ORIGIN` in production.
- Socket.IO verifies session token on connection and per message, rate-limits action bursts and refuses blocked accounts.
- Card dealing, scoring, pot and turn actions all happen server-side. `safeRoom` hides live opponent hands.
- Private room owner spectating is an **explicit exception** with opt-in visible disclosure and confirmation; backend checks that the admin owns the room and is not playing in the active round. Never enable this on public tables or for non-admin players.
- Table chips are stored in room JSON state. Wallet ledger transfers and room stack changes are in a single PostgreSQL transaction under a single process per-room queue. Do not deploy multiple API workers without introducing distributed locking to prevent concurrent state races.
- All chip adjustments and table transfer paths validate positive integer quantities and non-negative balances. Pot chips cannot be withdrawn. Owner credit/debit, exact wallet overwrite, and chip-request approval require a reason and write append-only audit records. Pending chip requests have a unique per-player constraint and a 10-minute resubmit limit. Telegram bot credentials stay server-side.
- Run actual integration/concurrency tests, database transaction rollbacks, load/stress, logs, backup restore, and dependency vulnerability checks before Internet launch.
- No code review or third-party security certification has been performed. No real SMTP/DB/browser integration was verified during packaging due to npm dependency install timeout.
