Security best practices
Credential, iframe, webhook, retry, and data-handling rules for Gate.
Keep server credentials server-side
Never expose sk_*, webhook secrets, or Account management assertions in browser bundles, URLs, mobile apps, logs, or analytics. The browser receives only pk_*, a session client_secret, and short-lived runtime credentials intended for that browser flow.
Bind the flow on your server
Create GateSession values from trusted server state. Validate amount, currency, flow, user reference, and return URL before calling Gate. Do not accept a browser-provided amount as authoritative.
Restrict origins and navigation
Configure only HTTPS origins you control. The widget validates message source and origin; your host page must do the same. Use a narrow frame-src policy and never use postMessage('*', ...).
Verify every webhook
Use the raw request bytes, parse Gate-Signature, enforce timestamp skew, compare the HMAC in constant time, and deduplicate by event id before applying state. Return 2xx only after durable acceptance.
Retry safely
Persist an idempotency key before session or rail creation and reuse it only for the same body. Use bounded backoff for 429, connection failures, and safe 5xx retries. Never retry a validation or authorization failure unchanged.
Minimize regulated data
Do not place secrets or identity documents in metadata, references, URLs, or logs. Rail creation rejects partner-supplied bank and identity fields. If authorized to submit a KYC package, keep your source copy and follow the agreed data-handling contract.
Separate modes
Keep test and live keys, webhook destinations, signing secrets, resources, and monitoring distinct. Query capabilities in the environment you will actually use.
