Skip to content

feat: multi-tenant — isolated zones, policies and API keys per tenant #23

Description

@redlemonbe

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestenterpriseEnterprise / commercial featurev1.2Enterprise features

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions