This guide covers security recommendations for integrating with the Developer API. Follow these practices to protect your API keys, user data, and integration endpoints.
API Key Storage
Your API key and secret are the credentials for all server-to-server communication with the poker engine. Treat them with the same care as database passwords.
Do
- Store API keys and secrets in environment variables or a secrets manager (AWS Secrets Manager, HashiCorp Vault, etc.)
- Restrict access to key storage to only the services that need it
- Use different keys for staging and production environments
Do Not
- Hard-code API keys in source code
- Commit keys to version control (even in private repositories)
- Include keys in client-side code (JavaScript bundles, mobile apps)
- Share keys over unencrypted channels (email, Slack, etc.)
- Log API keys or secrets in application logs
// GOOD: Load from environment
const API_KEY = process.env.POKER_API_KEY;
const API_SECRET = process.env.POKER_API_SECRET;
// BAD: Hard-coded in source
const API_KEY = 'pk_live_YOUR_KEY_HERE';
const API_SECRET = 'sk_live_YOUR_SECRET_HERE';
IP Allowlisting
Configure an IP allowlist on your API key to restrict which servers can make API calls. This prevents stolen keys from being used from unauthorized locations.
How It Works
- When an API key has no IPs in its allowlist, all IPs are allowed (default behavior)
- When one or more IPs are listed, only requests from those IPs are accepted
- CIDR notation is supported for IP ranges (e.g.,
10.0.0.0/24)
Recommendations
- In production, always configure an IP allowlist
- Use your server’s static IP addresses or CIDR ranges
- If you deploy to cloud providers with dynamic IPs, use the provider’s IP range (e.g., AWS NAT Gateway IP)
- Update the allowlist before deploying to new servers
# Example allowlist entries
203.0.113.10 # Single server
203.0.113.0/24 # Entire subnet
2001:db8::1 # IPv6 address
Scope Minimization
Only request the scopes your integration actually needs. This limits the damage if a key is compromised.
Available Scopes
| Scope | Permissions | Use Case |
|---|---|---|
user:create | Create and update user accounts | User provisioning and profile management |
user:read | Read user information | Displaying user data on your platform |
auth:code | Generate login codes | SSO authentication |
balance:read | Read user balances | Displaying balance information |
balance:write | Credit and debit balances | Managing funds |
webhooks:manage | Subscribe to events | Real-time notifications |
Examples
- SSO-only integration:
auth:code(code generation auto-provisions new users without needinguser:create) - Balance display:
balance:read - Full integration: All scopes
If you only need to authenticate users, do not request balance:write. If you only need to read balances, do not request balance:write.
Webhook Verification
Always verify the X-Signature header on incoming webhook deliveries, and make sure a webhook secret has been generated for your partner account, because deliveries are unsigned until one exists. This ensures the payload came from the poker engine and was not tampered with in transit.
Verification Steps
- Read the raw request body (before JSON parsing)
- Compute HMAC-SHA256 of the raw body using your webhook secret
- Compare the computed signature with the
X-Signatureheader using a timing-safe comparison - If signatures do not match, reject the request with 401
Common Mistakes
- Parsing before verifying: JSON.parse modifies whitespace and key ordering. Always verify against the raw bytes.
- Non-timing-safe comparison: Using
===to compare signatures leaks timing information. Usecrypto.timingSafeEqual(Node.js),hmac.compare_digest(Python), orhash_equals(PHP). - Wrong secret: The webhook verification secret is separate from your API key secret. Use the
whsec_...secret generated for your partner account.
See the Webhooks guide for complete code examples in Node.js, Python, and PHP.
Key Rotation
Rotate your API key secrets regularly to limit the impact of any undetected compromise. The Developer API supports graceful key rotation with a configurable grace period.
How Rotation Works
- Ask the platform admin to rotate the secret through the admin panel or admin API. The API key itself does not change
- A new secret is generated and returned (shown once)
- The old secret continues to work during the grace period (default: 24 hours, up to 720)
- After the grace period, only the new secret is accepted
Rotation Procedure
- Trigger rotation and receive the new secret
- Update your server configuration with the new secret
- Deploy the new configuration to all server instances
- Verify requests succeed with the new secret
- The old secret automatically expires after the grace period
Recommendations
- Rotate secrets at least every 90 days
- Use a shorter grace period (e.g., 4 hours) if you can deploy quickly
- Rotate immediately if you suspect a key compromise — use a 0-hour grace period for immediate invalidation
- Test the rotation process in staging before doing it in production
- Keep a log of when rotations occur for audit purposes
HMAC Signature Security
The HMAC-SHA256 signing mechanism protects against several attack vectors.
What It Prevents
- Tampering: Any modification to the HTTP method, path/query, request ID, timestamp, or raw request body invalidates the signature
- Replay attacks: The timestamp in the signing string limits the replay window to 5 minutes, and the required
X-Request-Idprevents authenticated request reuse inside that window - Request forgery: Without the secret, attackers cannot generate valid signatures
What It Does Not Prevent
- Key compromise: If your API secret is leaked, an attacker can forge valid requests. Use IP allowlisting as an additional layer.
- Man-in-the-middle on plaintext: Always use HTTPS. HMAC signing does not replace transport encryption.
Signing Best Practices
- Generate the timestamp immediately before signing (do not cache)
- Serialize JSON once and use the same string for signing and sending
- Use a unique
X-Request-Idfor each authenticated request; it is part of the HMAC signing string - Handle clock skew — if you get
TIMESTAMP_EXPIREDorTIMESTAMP_FUTUREerrors, synchronize your server clock via NTP
Transport Security
All API requests must be made over HTTPS. In production the poker engine answers plaintext HTTP requests with a 301 redirect to HTTPS rather than processing them, so always call the https:// URL directly.
Requirements
- Use TLS 1.2 or higher
- Verify the server’s SSL certificate (do not disable certificate verification)
- For webhook endpoints: use a valid SSL certificate from a trusted certificate authority (not self-signed)
CORS and Browser Security
The code exchange endpoint (POST /api/v1/auth/exchange) is called from the user’s browser. Ensure:
- Your frontend domain is in the poker engine’s CORS allowed origins
- For cookie mode, your site and the poker platform are on the same site, because the session cookies are
SameSite=Strict - Cookie mode exchanges include
credentials: 'include'in fetch requests - Token mode responses are handled securely — store tokens in memory or secure storage, not in
localStorage
Auth Code Security
Auth codes are one-time-use, short-lived credentials for SSO authentication.
Built-in Protections
- 60-second expiry: Codes expire quickly to minimize the window of misuse
- Single use: Once exchanged, a code cannot be reused
- SHA-256 storage: Only the hash of the code is stored in the database — plaintext codes exist only in transit
- Rate limiting: Code exchange is rate-limited to 10 attempts per minute per IP
Recommendations
- Exchange codes immediately after generation — do not store them
- Never include auth codes in URLs (use POST body only)
- Never log auth codes in application logs
- Generate codes only when the user is about to be signed in
Monitoring and Alerting
Use the admin panel and audit logs to monitor for suspicious activity.
What to Watch For
- Unusual 401/403 error spikes in your own client logs: May indicate a brute-force attack or compromised credentials being tested
- Requests from unexpected IPs: If IP allowlisting is not configured, watch for requests from unusual geographic locations
- High rate of code exchange failures: May indicate an attacker trying to brute-force auth codes
- Unexpected balance operations: Monitor credit/debit activity for anomalies
- Webhook delivery failures: Sudden delivery failures may indicate your endpoint is down or your webhook secret is out of sync
Audit Log
The Developer API logs every request that passes authentication, and every successful code exchange, with:
- Partner ID and API key ID (no API key on code exchanges)
- Action performed: the HTTP method and URL, or
auth:exchange - Target user (code exchanges only)
- Source IP address
- Request ID
- HTTP status code
Requests rejected during authentication are not in this log.
The platform admin can review it on the admin panel’s Audit Log page.
Incident Response
If you suspect your API key or webhook secret has been compromised:
- Have the platform admin immediately revoke the compromised key through the admin panel — this takes effect instantly with no grace period
- Generate a new key with the same scopes and IP allowlist
- Review audit logs for unauthorized activity during the suspected compromise period
- Have the admin generate a new webhook secret if it may also be compromised. The old one stops working immediately
- Notify the platform admin of the incident
- Update all server configurations with the new credentials
- Review your key storage practices to prevent future incidents
Related Guides
- Authentication — HMAC signing implementation details
- Webhooks — Webhook signature verification
- Errors — Error codes for security-related failures
- API Reference — Complete endpoint specifications