Context
For provider or enterprise deployments, a single Runbound instance must serve multiple isolated customers (tenants) with independent DNS zones, blocklist policies, and API credentials. This is the missing piece for Runbound to power a managed DNS or parental-control-as-a-service product.
Architecture
Each tenant gets:
- An isolated set of
local-data DNS entries (their private zone)
- Independent blocklist/feed subscriptions
- A scoped API key (read/write only their own data)
- Optional per-tenant rate limiting and access-control
- Independent statistics (their own QPS, cache hit rate, blocked count)
The DNS resolution engine is shared — only data and policies are isolated.
Configuration
[[tenant]]
id: "customer-acme"
name: "ACME Corp"
api-key: "sha256:..."
zone: "acme.internal."
access-control: 10.0.1.0/24 allow # only ACME's subnet can query this tenant's zone
rate-limit: 120 # req/min, independent from global rate-limit
[[tenant]]
id: "customer-beta"
name: "Beta SRL"
api-key: "sha256:..."
zone: "beta.lan."
access-control: 10.0.2.0/24 allow
API scoping
A tenant API key can only access its own resources:
| Endpoint |
Global key |
Tenant key |
GET /stats |
All tenants aggregated |
Own tenant only |
GET /dns |
All entries |
Own entries only |
POST /dns |
Any zone |
Own zone only |
GET /blacklist |
Global list |
Own list |
POST /reload |
Global reload |
Tenant reload only |
GET /tenants |
List all tenants |
403 |
DNS resolution
Query routing by source IP (matched against each tenant's access-control):
- Client from
10.0.1.0/24 → resolves against ACME's zone + ACME's blocklist + global blocklist
- Client from
10.0.2.0/24 → resolves against Beta's zone + Beta's blocklist + global blocklist
- Unknown subnet → falls back to global zone only
Per-tenant statistics
GET /stats?tenant=customer-acme
{
"tenant": "customer-acme",
"total": 48291,
"blocked": 1203,
"cache_hit_rate": 87.4,
"qps_1m": 13.2
}
Also exposed as Prometheus labels: runbound_queries_total{tenant="customer-acme"}
Use cases
- ISP / managed DNS provider: each customer gets their own private zone and filtering policy
- Enterprise multi-site: each site/VLAN has isolated DNS with its own records
- Parental control SaaS: each family/account has their own blocklist profile
- MSP: manage DNS for multiple clients from a single Runbound instance
Related
Context
For provider or enterprise deployments, a single Runbound instance must serve multiple isolated customers (tenants) with independent DNS zones, blocklist policies, and API credentials. This is the missing piece for Runbound to power a managed DNS or parental-control-as-a-service product.
Architecture
Each tenant gets:
local-dataDNS entries (their private zone)The DNS resolution engine is shared — only data and policies are isolated.
Configuration
API scoping
A tenant API key can only access its own resources:
GET /statsGET /dnsPOST /dnsGET /blacklistPOST /reloadGET /tenantsDNS resolution
Query routing by source IP (matched against each tenant's
access-control):10.0.1.0/24→ resolves against ACME's zone + ACME's blocklist + global blocklist10.0.2.0/24→ resolves against Beta's zone + Beta's blocklist + global blocklistPer-tenant statistics
Also exposed as Prometheus labels:
runbound_queries_total{tenant="customer-acme"}Use cases
Related