Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

Architecture

ScaiDNS is a control-plane API that sits in front of PowerDNS. This page describes how the pieces fit together and what you're actually talking to when you make an API call.

The pieces#

flowchart TB Client["Your client<br/>(SDK / curl)"] ScaiKey["ScaiKey<br/>(identity)"] subgraph API["ScaiDNS API (FastAPI)"] direction LR Auth["Auth layer"] Zone["Zone service"] Record["Record service"] Access["Access &<br/>audit service"] end MariaDB[("MariaDB<br/>(app database)")] PowerDNS[("PowerDNS<br/>(authoritative<br/>+ API + DNSSEC)")] Redis[("Redis<br/>(cache, rate limiting)")] Resolvers["Resolvers / clients"] Client -- "HTTPS (JWT or X-API-Key)" --> API ScaiKey -. "JWKS, OAuth, webhooks" .-> API API --> MariaDB API --> PowerDNS API --> Redis PowerDNS -- "UDP/TCP 53" --> Resolvers

The API. FastAPI, async, served under /api/v1/. Stateless: all state lives in MariaDB and PowerDNS.

MariaDB. The application database. Stores tenants, users (cached from ScaiKey), groups, roles, role assignments, access grants, domain metadata, audit logs, and API keys. Zone data is not stored here — that lives in PowerDNS.

PowerDNS. The authoritative DNS server. Holds the actual zones, records, DNSSEC keys, and signed zone data. ScaiDNS talks to PowerDNS via its HTTP API for writes and serves DNS responses to resolvers directly on port 53.

Redis. Used for rate limiting, short-lived caching (JWKS, tenant lookups), and background job coordination via arq.

ScaiKey. The identity provider. Issues OAuth tokens, manages the partner/tenant/user/group hierarchy, and sends webhook events when those entities change. ScaiDNS does not manage identities directly — it stays in sync with ScaiKey.

Data plane vs control plane#

ScaiDNS has a hard split between the two:

  • Data plane. DNS queries. Served by PowerDNS. ScaiDNS is not in the request path. A typical resolver queries PowerDNS on port 53 directly.
  • Control plane. Everything you read in these docs. The HTTP API, authentication, zone provisioning, access control, audit. ScaiDNS is the control plane and does not serve DNS queries itself.

This matters for two reasons:

  1. Performance. DNS query latency is bounded by PowerDNS, not by ScaiDNS. The API being slow or down doesn't affect query resolution.
  2. Truth is PowerDNS. If you bypass the API and write to PowerDNS directly, ScaiDNS's database will be stale. Don't do that — go through the API so audit, permissions, and validation apply.

Authentication flow#

Users authenticate through ScaiKey's OAuth 2.0 authorization code flow with PKCE:

  1. Client redirects to ScaiKey's authorization endpoint.
  2. User signs in at ScaiKey, returns with an authorization code.
  3. Client calls POST /api/v1/auth/token with the code; ScaiDNS proxies to ScaiKey and returns access and refresh tokens.
  4. Client includes Authorization: Bearer <access_token> on subsequent requests.

The JWT is validated on every request using JWKS fetched from ScaiKey. Claims (sub, email, tenant_id, roles, scopes) are parsed into a CurrentUser context used for authorization.

API keys are an alternative: send X-API-Key: sdk_<secret> on requests. API keys inherit permissions from their owning user or group, can carry their own rate limit and IP whitelist, and never expire unless explicitly configured. See Authentication.

Zone lifecycle#

  1. Create. POST /api/v1/domains/ creates a domain row in MariaDB with status pending_validation. PowerDNS zone is not created yet.
  2. Validate. The client publishes a TXT record at their DNS provider proving ownership. POST /api/v1/domains/{id}/validation/check triggers DNS lookup against the authoritative nameservers. If the TXT value matches, status flips to active and PowerDNS zone is created.
  3. Manage. Records are added via POST /api/v1/domains/{id}/records, validated server-side, and written to PowerDNS.
  4. Optional: sign. POST /api/v1/domains/{id}/dnssec/enable generates KSK and ZSK in PowerDNS and surfaces DS records for publication at the registrar.
  5. Delete. DELETE /api/v1/domains/{id} soft-deletes by default (recoverable via /restore) or hard-deletes with ?hard=true, removing the PowerDNS zone.

Reverse zones follow the same flow but can be bootstrapped from a CIDR block — see Reverse Zones.

Identity sync#

Tenants, users, and groups are owned by ScaiKey. ScaiDNS keeps a local cache in MariaDB to support:

  • Fast authorization decisions without calling ScaiKey on every request.
  • Offline operation if ScaiKey is temporarily unreachable.
  • Audit log records for users after they leave the organization.

Two mechanisms keep the cache fresh:

  • Webhooks. ScaiKey sends HMAC-signed events on every change. ScaiDNS exposes POST /api/v1/webhooks/scaikey to receive them. See Webhooks Deep Dive.
  • Periodic sync. A scaidns sync CLI command pulls the full state from ScaiKey. Useful for initial setup and recovery.

What's next#

Updated 2026-05-17 23:58:50 View source (.md) rev 2