Multi-brand & tenancy
A tenancy bug is not a UI glitch. It is a breach with your name on it.
One codebase serves every brand. The active brand is resolved per request and every brand-owned table carries a global query scope — so isolation is the default behaviour of a query rather than something each new feature has to remember.
- Resolution is per request — from an
X-Tenantheader or the request domain — so one deployment serves every brand with no per-brand build. - Sports data is shared, customer data is not. Fixtures, odds, results and currency rates are platform-wide and priced once. Players, wallets, bets, bonuses, promotions, segments, campaigns, staff and audit records are brand-owned.
- A brand's staff cannot construct a query that leaves their brand. Not "should not" — the scope is applied beneath them.
- The static shell re-themes itself by fetching the tenant, so a brand's look is configuration rather than a deployment.
Staff permissions
An audited role model, not a checkbox
Four roles — owner, manager, trader and support — across 26 capability domains, from withdrawals and trading through to campaigns, billing and staff management. The interesting part is not the matrix; it is the second lock behind it.
Money paths are bounded twice
Manual wallet adjustment is the only operation that creates money rather than moving it. Support cannot adjust at all — the capability layer refuses them, and a per-role, per-day monetary ceiling refuses them again. A ceiling that can be defeated by repetition is not a ceiling.
Writes are audited by default
Back-office writes are audited by the framework, not by each endpoint remembering to call the logger. The failure mode of the opposite design is that the one unaudited endpoint is always the one you needed.
Reporting roles read nothing extra
A reporting-only role has an empty capability list and is explicitly barred from identity documents. Read access to a reporting surface is not read access to a customer's passport scan.
A test we would encourage you to run against any vendorLog in as a brand's own staff member and try to reach another brand's player, money or audit log through the API — not the UI, the API. We have run exactly that audit against ourselves and closed what it found; the commit history says so in plain language.
Launching a brand
One command, then it is yours
PLATFORM
Provisioning
Creating a brand is a single, safely re-runnable command run by Ledgerfield — the one action that is deliberately not self-serve, because standing up a tenant touches platform-wide state.
OPERATOR
Branding
10 skin presets plus per-brand configuration. A skin is the visual layer; the brand underneath is what security isolates.
OPERATOR
Staff & policy
The brand's own team invite staff, set roles, and set the brand's security policy — including whether two-factor is mandatory. No Ledgerfield staff in the loop.
OPERATOR
Content & trading
Games, promotions, jackpots, tournaments, boosts, trading limits and settlement are all the brand's own, through the back office or the same API.
Precisely scoped, because the distinction gets blurred in this market"Every operator action is self-serve" is not what we claim. Creating a new brand requires platform staff. Everything about running an existing brand afterwards is genuinely self-serve for that brand's own team. Any vendor claiming the stronger version is either describing something narrower than it sounds, or has a tenancy model you should ask harder questions about.
Watch one back office drive four unrelated brands.
Seven brands on one instance, sharing one odds feed, looking nothing alike — plus the back office switching between genuinely isolated tenants. It is the fastest ten minutes of any demo we give.