Deployment
Operational guide for deploying ScaiDNS. Covers required services, configuration, and the first-time setup flow.
Prerequisites#
- PowerDNS. Authoritative server with the HTTP API enabled. Tested against PowerDNS 4.7+.
- MariaDB or MySQL. For the application database. ScaiDNS uses
mysql+asyncmy. A dedicated database is recommended; do not share with PowerDNS's backend. - Redis. For rate limiting and cache. Version 6+ with ACL auth.
- ScaiKey instance. For identity. Can be shared with other ScaiLabs services or dedicated.
Configuration#
All configuration is via environment variables. See .env.example in the repository for the canonical reference.
Required#
| Variable | Notes |
|---|---|
DATABASE_URL |
mysql+asyncmy://user:password@host:3306/scaidns |
REDIS_URL |
redis://user:password@host:6379/0 |
PDNS_API_URL |
e.g., http://pdns.internal:8081 |
PDNS_API_KEY |
Shared secret for PowerDNS HTTP API |
SCAIKEY_URL |
e.g., https://scaikey.scailabs.ai |
SCAIKEY_CLIENT_ID |
OAuth client ID for ScaiDNS |
SCAIKEY_CLIENT_SECRET |
OAuth client secret |
SCAIKEY_APPLICATION_ID |
ScaiKey application ID for user assignment |
SCAIKEY_WEBHOOK_SECRET |
HMAC secret for webhook signature verification |
EXTERNAL_URL |
Public URL users hit (e.g., https://scaidns.example.com) |
SESSION_SECRET |
Cryptographic secret for session management |
API_KEY_PEPPER |
Secret added to API key hashes |
Optional#
| Variable | Default | Notes |
|---|---|---|
DEBUG |
false |
Enable in dev; never in production |
ENVIRONMENT |
production |
development, staging, production |
LOG_LEVEL |
INFO |
DEBUG, INFO, WARNING, ERROR |
LOG_FORMAT |
text |
text or json |
DATABASE_POOL_SIZE |
20 |
Connection pool size |
REDIS_MAX_CONNECTIONS |
20 |
|
ARQ_MAX_JOBS |
10 |
Background worker concurrency |
SCAIKEY_TOKEN_CACHE_TTL |
60 |
JWT validation cache TTL (seconds) |
SCAIKEY_JWKS_CACHE_TTL |
3600 |
JWKS cache TTL (seconds) |
VALIDATION_CHALLENGE_TTL |
3600 |
Validation challenge expiry (seconds) |
VALIDATION_EXPIRY_HOURS |
72 |
Max age before a challenge is expired |
VALIDATION_CHECK_INTERVAL_SECONDS |
60 |
Background check cadence |
RATE_LIMIT_USER_PER_MINUTE |
1000 |
Default per-JWT rate limit |
RATE_LIMIT_API_KEY_PER_MINUTE |
100 |
Default per-API-key rate limit |
DNSSEC_DEFAULT_ALGORITHM |
13 |
ECDSA P-256 |
DNSSEC_KSK_LIFETIME_DAYS |
365 |
|
DNSSEC_ZSK_LIFETIME_DAYS |
30 |
|
CORS_ORIGINS |
[] |
JSON array of allowed origins |
Services#
ScaiDNS runs three processes:
- API server. FastAPI + uvicorn, serves the HTTP API. Stateless, horizontally scalable.
- Worker.
arqworker, runs background jobs (validation checks, DNSSEC rotation, sync retries). - CLI.
scaidnscommands for setup and maintenance. Not a long-running process.
Typical systemd units:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
First-time setup#
1. Database migrations#
1 2 | |
Creates the schema and seeds system roles, templates, and default configuration.
2. ScaiKey registration#
Register ScaiDNS as an OAuth application in ScaiKey:
- Application name: ScaiDNS
- Redirect URI:
https://<your-external-url>/oauth/callback - Post-logout URI:
https://<your-external-url>/ - Scopes:
openid,profile,email
Take the resulting client_id and client_secret and put them in .env.
Also in ScaiKey:
- Generate a webhook signing secret. Put it in
SCAIKEY_WEBHOOK_SECRET. - Configure the webhook URL:
https://<your-external-url>/api/v1/webhooks/scaikey. - Assign users/groups to the ScaiDNS application so they receive user/group events.
There's a helper in the ScaiDNS CLI:
1 | |
3. First sync#
Pull the initial user and tenant data from ScaiKey:
1 | |
Check the output for created/updated counts. If everything shows zeros, double-check SCAIKEY_APPLICATION_ID and that users are assigned to the application.
4. Initial platform admin#
Creating your first platform admin via the API requires already being one, so use the CLI:
1 | |
Assigns platform_admin at platform scope. You can now log in via the web UI and manage further access.
5. Nameserver configuration#
Set the authoritative nameservers for ScaiDNS-hosted zones:
1 2 3 4 | |
These become NS records in every zone.
PowerDNS configuration#
Recommended PowerDNS settings (in pdns.conf):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Important: Never point ScaiDNS and PowerDNS at the same database. PowerDNS owns its backend; ScaiDNS has its own schema. They communicate via the HTTP API.
Reverse proxy / TLS#
Run ScaiDNS behind a TLS-terminating reverse proxy (nginx, Caddy, HAProxy). An nginx config sketch:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Upgrades#
For minor version upgrades:
- Deploy new code.
- Run migrations:
alembic upgrade head. - Restart API and worker services.
- Smoke-test
/api/v1/health/ready.
For major upgrades, check the release notes — schema migrations, config changes, or webhook signature format changes need explicit coordination.
What's next#
- Health and Monitoring — readiness checks, metrics, logs.