Why custom-domain isolation is a regulated-market requirement, not an aesthetic one

When an operator runs bet.operator.com in front of a Sporbet Soft iframe and a sister operator runs bet.competitor.com in front of the same vendor infrastructure, the regulator in the UK, Malta, Sweden, Australia or Ontario does not see a vendor problem — they see two operators whose security postures must be independent. If a UK Gambling Commission audit on operator A surfaces a session-isolation defect that affects operator B, both operators get sanctioned, not the vendor.

That regulatory framing is why custom-domain isolation is not just a nice-to-have brand feature; it's a structural compliance requirement. Every partner-facing surface — cookies, local storage, CSP, CORS, X-Frame-Options, COOP — has to behave as if each partner were on its own dedicated infrastructure, even though the underlying compute, storage and WebSocket fleet are shared across all partners.

The architectural pieces that get us here are summarised in our integration anatomy; this article zooms in on the isolation primitives themselves and the operational discipline around them.

Custom-domain self-service and automatic SSL provisioning

An operator pointing their bet.operator.com CNAME at Sporbet Soft's edge gateway is, today, a five-minute self-service flow inside the partner panel. The operator pastes the domain, picks the matching API key from their account, and the panel walks through DNS validation (TXT record verification), TLS provisioning (ACME-compatible automated issuance via Let's Encrypt or ZeroSSL), and CSP-header configuration. The end-to-end flow resolves in under 90 seconds in the happy path; the slowest step is DNS propagation on the operator's side.

Under the hood, the certificate authority issues a SAN certificate scoped to the operator's hostname. The certificate is stored in our edge fleet's TLS-termination layer keyed by hostname, so the first TLS handshake on the operator's domain serves the operator's certificate — not a vendor wildcard, not a shared SNI fallback. Cert rotation is automated on a 30-day cadence; the panel surfaces expiry warnings 14 days out and auto-renewal events in the audit log.

Operators who need bring-your-own certificates (rare but it happens — typically multi-region operators with their own corporate CA) can upload PEM files through the same flow, with the panel validating chain integrity and matching the private key before activation. Sporbet Soft never stores private keys outside the TLS-termination layer's KMS-encrypted volume — see why iframe absorbs this complexity and an API-only build forces the operator to own it.

Content-Security-Policy scoped per partner

CSP is the headline isolation primitive. Every response the iframe serves on a partner's custom domain ships a CSP header scoped to that partner — default-src 'self', script-src 'self' 'wasm-unsafe-eval', connect-src 'self' wss://gw.sporbetsoft.com, frame-ancestors https://*.operator.com, plus partner-specific extensions configured in the panel. The header is composed at request time from a partner-keyed policy template, not from a shared default with per-tenant overrides — that distinction matters because policy templates compose cleanly while overrides accumulate footguns.

The frame-ancestors directive is the load-bearing one. It tells the browser which parent origins are allowed to embed the iframe; an operator setting frame-ancestors https://*.operator.com ensures the iframe will refuse to render if a third-party site tries to clickjack it. The partner panel exposes a friendly UI for the directive and validates that the configured ancestors match the partner's known domains on the operator allow-list.

When an operator adds a new marketing subdomain — promo.operator.com, say — they update the frame-ancestors through the panel, and the new policy is in effect on the very next request. No deploy, no ticket, no waiting for the vendor's release window. Operators in fast-moving regulated markets (Ontario, in particular, ships policy changes weekly during the run-up to NHL playoffs) lean on this.

X-Frame-Options, COOP and the sandbox attribute

X-Frame-Options is the legacy cousin of frame-ancestors and we still ship it for older browsers (mostly enterprise Windows fleets stuck on outdated browser versions). The header is set to SAMEORIGIN on the iframe's HTML responses by default, with a per-partner ALLOW-FROM override available when the partner panel detects an embedding parent that requires it.

Cross-Origin-Opener-Policy is the more interesting modern header. Sporbet Soft's iframe ships Cross-Origin-Opener-Policy: same-origin-allow-popups, which isolates the iframe's browsing context from the operator's parent page (so the parent page's JavaScript cannot reach into the iframe's window object via opened popups) while still allowing the iframe to open OAuth-style popups for KYC providers or payment processors. The 'allow-popups' part is non-negotiable for operators integrating with PSPs that use popup-based 3DS flows.

The iframe's sandbox attribute, when the operator wants belt-and-braces isolation, can be set to sandbox="allow-scripts allow-same-origin allow-popups allow-forms" — the explicit allow-list documents exactly which capabilities the iframe needs and locks down everything else. Operators in regulated markets typically set this and let the auditor walk through the allow-list at review time. The partner panel exposes a one-click toggle that emits the right attributes.

CORS allow-list and the WebSocket origin check

CORS is where multi-tenant platforms most often slip up. The temptation is to set Access-Control-Allow-Origin: * on the vendor's API endpoints so partner storefronts can call back into the platform from anywhere. That works for one tenant and breaks badly for many — any malicious site can now hit your APIs with credentialed requests from a victim's browser.

Sporbet Soft's APIs (the partner-panel REST surface, the postMessage callback receivers, the analytics ingestion endpoint) honour a strict per-partner CORS allow-list derived from the partner's configured domains. A request from https://promo.operator.com only succeeds against partner-A endpoints if promo.operator.com is on partner A's allow-list. The check is enforced at the edge, before any compute runs, so a misbehaving client never reaches application code.

The same allow-list governs the WebSocket origin check. Our WebSocket gateway inspects the Origin header on the upgrade request and rejects connections from origins that don't match the partner's allow-list with HTTP 403. This is how we stop a third-party site from opening a covert WebSocket to our gateway using a stolen session cookie — see our odds latency architecture piece for why the WebSocket gateway is the most attacker-attractive surface in the stack.

What the auditor actually checks

When a UKGC, MGA, Spelinspektionen, ACMA or AGCO auditor reviews Sporbet Soft as a B2B vendor on behalf of an operator, the script is predictable. They pull the iframe over the operator's custom domain, dump every response header, walk through CSP and COOP/COEP, dump the cookies, dump the local storage, and check that nothing on the response surface references another operator's tenant ID or shared session.

The audit also walks through the operational discipline: how is a partner's domain added? Who has access to the partner panel? How are admin actions logged? Can a vendor employee silently impersonate a partner? On Sporbet Soft the answers are: through the self-service flow with DNS+CSP validation; only the operator's role-scoped panel users; every admin action emits an immutable audit event with operator+actor+target; impersonation requires explicit consent and emits a customer-visible event in the operator's audit log.

Operators landing in regulated markets typically share this article and the corresponding security runbook with their auditor during the procurement phase. It cuts weeks off the licence-review timeline. See the iframe overview for the full feature set and pricing for how this isolation work folds into the flat fee — it is part of the platform, not a per-tenant add-on.