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

DNS Providers

Endpoint reference for the DNS provider integrations used by ACME DNS-01 challenges. ScaiVault writes and cleans up _acme-challenge TXT records on your behalf; you configure once which providers manage which zones.

Base path: /v1/dns/providers/

Supported providers#

Provider Type ID Recommended for
ScaiDNS scaidns ScaiLabs-stack-native deployments (preferred)
Cloudflare cloudflare Zones already on Cloudflare
AWS Route 53 route53 AWS-resident deployments
Azure DNS azure Azure-resident deployments
Google Cloud DNS google GCP-resident deployments
DigitalOcean digitalocean DO Networking
PowerDNS powerdns Self-hosted PowerDNS with API enabled

Each provider has a config schema and a credentials schema; the credentials half is encrypted and never returned in responses.

ScaiDNS#

Native ScaiLabs integration. Preferred when ScaiDNS is already in your stack.

Credentials:

Field Description
base_url ScaiDNS endpoint (https://scaidns.scailabs.ai or self-hosted)
api_key ScaiDNS API key starting with sdk_. Scopes needed: domains:read, records:read, records:write

Obtain the key from the ScaiDNS admin UI under Settings → API Keys. Show-once at creation.

Cloudflare#

Credentials:

Field Description
api_token API token with Zone:DNS:Edit on the relevant zones

Generate at Cloudflare dashboard → My Profile → API Tokens → Create Token → "Edit zone DNS" template.

AWS Route 53#

Credentials:

Field Description
access_key_id IAM access key ID (optional if the host runs with a Route 53–capable role)
secret_access_key IAM secret access key
region Optional, defaults to us-east-1

Minimum IAM policy:

json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "route53:ListHostedZones",
      "route53:GetHostedZone",
      "route53:ListResourceRecordSets",
      "route53:ChangeResourceRecordSets"
    ],
    "Resource": "*"
  }]
}

Azure DNS#

Credentials:

Field Description
subscription_id Azure subscription
resource_group Resource group containing the DNS zone
tenant_id Azure AD tenant
client_id Service principal client ID
client_secret Service principal client secret

The service principal needs the DNS Zone Contributor role on the zone resource.

Google Cloud DNS#

Credentials:

Field Description
project_id GCP project
service_account_json Full JSON content of a service account key

The service account needs the DNS Administrator role on the project (or roles/dns.admin scoped to specific zones).

DigitalOcean#

Credentials:

Field Description
api_token Personal access token with read/write scope

PowerDNS#

Credentials:

Field Description
api_url PowerDNS API endpoint, e.g. http://pdns.local:8081
api_key Value of api-key= from pdns.conf
server_id Server identifier, default localhost

Endpoints#

GET /v1/dns/providers/types#

Catalog of supported provider types and their credential schemas. Use for building UIs.

json
1
2
3
4
5
6
7
{
  "types": [
    {"id": "scaidns", "name": "ScaiDNS", "credentials_schema": {...}},
    {"id": "cloudflare", "name": "Cloudflare", "credentials_schema": {...}},
    ...
  ]
}

Scope: authenticated.

GET /v1/dns/providers#

List configured providers in the current tenant.

Response:

json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
  "data": [
    {
      "id": "dnsp_abc",
      "name": "ScaiDNS Production",
      "provider_type": "scaidns",
      "managed_zones": ["acme.example", "*.acme.example"],
      "description": "...",
      "is_active": true,
      "last_verified_at": "...",
      "created_at": "..."
    }
  ],
  "has_more": false
}

Credentials are never returned. Use POST /verify to confirm they work.

Scope: pki:admin.

POST /v1/dns/providers#

Add a provider.

Body:

Field Required Description
name Yes Tenant-unique
provider_type Yes One of the IDs above
credentials Yes Provider-specific shape
managed_zones No Array of zones this provider serves; empty = auto-discover
description No
verify No Default true — refuse to create if credentials fail

Response 201 Created: the new provider (no credentials echoed).

Scope: pki:admin.

GET /v1/dns/providers/{id}#

PATCH /v1/dns/providers/{id}#

Update name, managed zones, description, or credentials.

DELETE /v1/dns/providers/{id}#

Refuses if active ACME orders reference this provider. Disable, complete or cancel orders, then delete.

POST /v1/dns/providers/{id}/verify#

Test the credentials by listing zones from the provider.

Response:

json
1
2
3
4
5
{
  "valid": true,
  "discovered_zones": ["acme.example", "scaivault.example"],
  "checked_at": "..."
}

On failure:

json
1
2
3
4
{
  "valid": false,
  "error": "401 Unauthorized — API key invalid or expired"
}

GET /v1/dns/providers/{id}/zones#

List zones the provider has access to. Useful when populating managed_zones.

Managed zones#

managed_zones is an ordered list of glob patterns. On an ACME challenge for a domain, ScaiVault picks the first provider whose managed_zones includes a matching pattern.

Pattern Matches
acme.example Exact acme.example only
*.acme.example All subdomains (api.acme.example, www.acme.example) — but not acme.example itself
**.acme.example All subdomains plus acme.example
(empty list) Whatever the provider auto-discovers via its API

For wildcards (*.acme.example) ACME requires dns-01 and the provider must support managing records at the zone apex.

How challenges flow#

sequenceDiagram participant SV as ScaiVault participant ACME as ACME server participant Picker as Provider selector participant DNS as DNS provider participant NS as Authoritative NS SV->>ACME: order cert for api.acme.example ACME-->>SV: TXT _acme-challenge.api.acme.example = token SV->>Picker: match api.acme.example against managed_zones Picker-->>SV: first match wins SV->>DNS: create TXT record DNS-->>SV: ok loop until propagated or 300s SV->>NS: dig TXT _acme-challenge... NS-->>SV: not yet / found end SV->>ACME: challenge ready ACME-->>SV: order valid + cert SV->>DNS: delete TXT record
  1. ScaiVault asks the ACME server for a challenge on api.acme.example.
  2. ACME returns: "Create TXT _acme-challenge.api.acme.example = <token>".
  3. ScaiVault checks active DNS providers' managed_zones against api.acme.example. First match wins.
  4. ScaiVault calls the provider's API to create the TXT record.
  5. ScaiVault polls authoritative nameservers for the TXT (timeout: 300 seconds by default).
  6. ScaiVault tells ACME the challenge is ready.
  7. ACME validates, issues the cert.
  8. ScaiVault deletes the TXT record.

Audit log entries cover provider creation, credential verification, every record create/delete, and challenge completion. Look under action=dns_record_create / dns_record_delete.

Failure modes#

"No DNS provider configured for domain." Add a provider with managed_zones covering the domain, or expand an existing one.

Verification keeps failing. Use POST /verify directly to see the upstream error. Common: expired API key, missing scope, region/zone-resource-group mismatch.

Propagation timeout. Either the provider isn't actually writing the record (check audit), or the recursive resolver path between ScaiVault and the authoritative nameserver is broken. Reduce the zone's NS TTL during testing to speed up debugging.

DNSSEC denial. Some ACME validators perform DNSSEC validation. If the zone has DNSSEC enabled but signing is misconfigured, challenges fail with NXDOMAIN. Verify with dig +dnssec _acme-challenge.<domain> @<authoritative>.

  • ACME — issuing certificates with DNS-01 challenges.
  • PKI Reference — full PKI endpoints.
Updated 2026-05-17 14:30:20 View source (.md) rev 4