Recipe: run a multi-tenant streaming agency
One server, one app per client, a scoped token each, per-tenant quotas and an IP firewall. How to carve a StreamHub node into isolated tenants you can bill, cap and secure independently.
Why multi-tenant
If you resell streaming — to clients, to franchisees, to internal departments — you need clean walls between tenants: separate data, separate credentials, separate limits, and a way to offboard one without touching the others. StreamHub is built for exactly this. One node carries many apps, each an isolated tenant, and every seam (tokens, quotas, network rules) is per app.
Architecture in words
Each client gets an app with its own config, S3 bucket, database and room namespace. You mint one app-scoped token per client, so a leaked credential only exposes that client. Quotas are enforced per tenant (apps, concurrent streams, recording minutes, egress, storage), and a network security layer applies IP allow/blocklists and auto-ban before any request reaches auth.
1. Create an app per client
export BASE="https://your-server.example.com/api/v1"
export TOKEN="sk_...." # a global token
curl -s -X POST $BASE/apps -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name":"acme","displayName":"ACME Corp"}'
Rooms are namespaced under the app prefix, so acme's room launch is acme-launch — no collision with another client's launch.
2. Mint a scoped token per client
curl -s -X POST $BASE/tokens -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name":"acme-integration","scope":"app","appId":"acme","allowedIps":["203.0.113.0/24"]}'
The plaintext token is returned once — store it immediately. The optional allowedIps whitelist (exact IP or CIDR) restricts where the token can be used. Hand this token to the client; it can never touch another tenant's data.
3. Set per-tenant quotas
RBAC and quotas share one enforcement switch, STREAMHUB_AUTHZ_ENFORCE (off | log | on; fresh installs default on). The free-plan defaults are deliberately small — maxApps 2, maxConcurrentStreams 2, maxRecordingMinutesMonth 300, maxEgressGbMonth 5, maxStorageGb 5. Lift a paying client to a bigger plan:
curl -s -X PATCH $BASE/tenants/<tenantId>/quotas -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' -d '{"plan":"broadcaster"}'
Over-limit calls are rejected with 429 quota_exceeded (with metric, limit, used), and usage is visible at GET /tenants/<tenantId>/usage and as the Prometheus gauges streamhub_tenant_quota / streamhub_tenant_usage.
4. Lock down the network
Turn on the IP layer and, optionally, auto-ban:
STREAMHUB_IP_ACCESS_MODE=enforce
STREAMHUB_AUTOBAN_ENABLED=true
STREAMHUB_AUTOBAN_MAX_OFFENSES=10
STREAMHUB_AUTOBAN_WINDOW_S=300
Manage rules over the (superadmin-only) security API:
curl -s -X POST $BASE/security/ip-rules -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"cidr":"198.51.100.7/32","action":"block","note":"abusive scraper"}'
Precedence runs allow-before-block, with loopback and private ranges always permitted; an allowlisted IP is also shielded from bans. Repeated auth failures trip a time-boxed ban that persists across restarts.
What you should see
Each client operates in its own app with its own token and bucket, invisible to the others. A client hitting its plan limit gets a clean 429; you see every tenant's usage against quota in one place; and blocked or banned IPs are rejected before they ever reach authentication.
Troubleshooting
- A client can see another's data — check the token was minted with
scope: "app"and the rightappId; a global token bypasses tenant scoping by design. - Quotas not enforced — confirm
STREAMHUB_AUTHZ_ENFORCE=on(or runlogfirst in staging to preview denials); superadmin and unscoped tokens are never limited. - Legit traffic getting 403/429 — the security middleware does not cover the
/hls,/samples,/sdkand/livestatic mounts; media-port protection (RTMP, WHIP, WebRTC UDP) is your reverse proxy and OS firewall's job. Behind a proxy, make suretrust proxyis set so the client IP is read correctly.
Closing
A single StreamHub node becomes a clean multi-tenant platform you can bill, cap and secure per client — with none of the media leaving your control. If you are standing up an agency or a reseller offering, our team does the tenant model, the billing hooks and the hardening as a managed-ops or consulting engagement.