Multi-tenancy
One Mockifyr host can serve several independent sets of stubs. A tenant is chosen per request with the
X-Mockifyr-Tenant header, and a tenant can never see another tenant’s stubs.
curl -X POST http://localhost:8080/__admin/mappings \ -H 'X-Mockifyr-Tenant: team-payments' \ -d '{"request":{"method":"GET","url":"/hello"},"response":{"status":200,"body":"payments"}}'
curl http://localhost:8080/hello -H 'X-Mockifyr-Tenant: team-payments'# → paymentsThe header is honoured on every /__admin/* route, on the mock-serving facade, in the
gRPC middleware and in the WebSocket facade. When the header is absent the
request goes to the default tenant — which is what a host that never sets the header uses for
everything.
Isolation is structural, not a filter applied late: every store and engine entry point takes an explicit tenant, so a code path that forgot to scope itself would not compile.
Listing tenants
curl http://localhost:8080/__admin/tenants{ "tenants": ["default", "team-payments"] }This reports the tenants that currently hold stubs. A tenant is not created or registered up front — it exists because something was stored under it.
What is not tenant-scoped
Some admin surfaces are deliberately host-level: they configure the process, not a set of stubs.
Sending X-Mockifyr-Tenant to these routes changes nothing.
| Route | Scope |
|---|---|
/__admin/recordings/* | Host-level |
/__admin/git/* | Host-level |
/__admin/outbound-trust* | Host-level |
/__admin/ext/* | Host-level |
/__admin/health | Host-level |
/__admin/tenants | Host-level |
Loading stubs into a named tenant
Stub files read from disk at startup go into the default tenant. There is no per-directory tenant convention at load time.
To populate a named tenant, either use the dashboard’s Import while that tenant is selected, or post the bundle with the header:
curl -X POST http://localhost:8080/__admin/mappings/import \ -H 'X-Mockifyr-Tenant: team-payments' \ --data-binary @mappings.jsonWhat follows the tenant
- Scenario state is keyed by (tenant, scenario name), so two tenants running the same scenario name advance independently.
- Environments are tenant-scoped — each tenant owns its own keys and active values.
In the dashboard
The sidebar has a tenant switcher. Selecting a tenant scopes the whole UI — stubs, scenarios, environments and imports all act on that tenant until you switch again.
No per-user identity
Tenancy separates stubs; it does not separate people. Authentication is a single host-level admin credential, so anyone who can log in can switch to any tenant. Tenants are an isolation boundary for data, not a security boundary between users — see securing the admin API.
Related
- Environments — tenant-scoped configuration values.
- Admin API — the full endpoint reference.