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

Enabling DNSSEC

A step-by-step guide to signing a zone with DNSSEC. For the concepts and cryptographic background, see DNSSEC.

Base path: /api/v1/domains/{domain_id}/dnssec Required permission: dnssec:* on the domain

Prerequisites#

  • Zone is active (validation completed).
  • You have access to your registrar's admin panel to publish DS records.
  • A DNSSEC-validating resolver is available for testing (1.1.1.1, 8.8.8.8, and most modern resolvers validate).

1. Check current status#

bash
1
2
curl https://scaidns.scailabs.ai/api/v1/domains/$DOMAIN_ID/dnssec \
  -H "X-API-Key: $SCAIDNS_API_KEY"
python
1
2
3
4
5
resp = httpx.get(
    f"https://scaidns.scailabs.ai/api/v1/domains/{DOMAIN_ID}/dnssec",
    headers={"X-API-Key": os.environ["SCAIDNS_API_KEY"]},
)
print(resp.json())
typescript
1
2
3
4
5
const resp = await fetch(
  `https://scaidns.scailabs.ai/api/v1/domains/${domainId}/dnssec`,
  { headers: { "X-API-Key": process.env.SCAIDNS_API_KEY! } }
);
console.log(await resp.json());

If enabled: false, proceed to step 2. If already enabled, skip ahead to rotation or verification.

2. Enable with algorithm 13#

bash
1
2
3
4
curl -X POST https://scaidns.scailabs.ai/api/v1/domains/$DOMAIN_ID/dnssec/enable \
  -H "X-API-Key: $SCAIDNS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"algorithm": 13}'
python
1
2
3
4
5
6
7
8
resp = httpx.post(
    f"https://scaidns.scailabs.ai/api/v1/domains/{DOMAIN_ID}/dnssec/enable",
    headers={"X-API-Key": os.environ["SCAIDNS_API_KEY"]},
    json={"algorithm": 13},
)
result = resp.json()
for ds in result["ds_records"]:
    print(f"{ds['key_tag']} {ds['algorithm']} {ds['digest_type']} {ds['digest']}")
typescript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
const resp = await fetch(
  `https://scaidns.scailabs.ai/api/v1/domains/${domainId}/dnssec/enable`,
  {
    method: "POST",
    headers: {
      "X-API-Key": process.env.SCAIDNS_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ algorithm: 13 }),
  },
);
const result = await resp.json();
for (const ds of result.ds_records) {
  console.log(ds.key_tag, ds.algorithm, ds.digest_type, ds.digest);
}

Algorithm selection#

Algorithm Number When to use
ECDSA P-256/SHA-256 13 Default choice. Small, fast, universally supported
Ed25519 15 Modern; use if your TLD and registrar support it
RSA/SHA-256 8 Legacy compatibility; avoid for new zones

When in doubt, use 13.

Response#

json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
  "enabled": true,
  "algorithm": 13,
  "ksk": {
    "key_tag": 12345,
    "algorithm": 13,
    "public_key": "...",
    "created_at": "2026-04-23T10:00:00Z",
    "expires_at": "2027-04-23T10:00:00Z"
  },
  "zsk": {
    "key_tag": 67890,
    "algorithm": 13,
    "public_key": "...",
    "created_at": "2026-04-23T10:00:00Z",
    "expires_at": "2026-05-23T10:00:00Z"
  },
  "ds_records": [
    {
      "key_tag": 12345,
      "algorithm": 13,
      "digest_type": 2,
      "digest": "A1B2C3D4E5F6..."
    }
  ]
}

The zone is now signed at the nameserver level. DNSSEC validation will fail until you publish the DS records at the registrar, because the chain of trust isn't established yet.

3. Publish DS records at the registrar#

Log into your registrar's admin panel and find the DS records section. It's often under "DNSSEC" or "Security."

For each DS record in the response, enter:

  • Key Tag: the integer key_tag.
  • Algorithm: the integer algorithm.
  • Digest Type: the integer digest_type (2 = SHA-256, typical).
  • Digest: the digest hex string.

Save. The registrar pushes these to the parent TLD zone on its own schedule — minutes to hours, occasionally longer.

Watch for propagation:

bash
1
dig +short DS example.com @1.1.1.1

When the digest shows up, move on.

4. Confirm DS is published#

Tell ScaiDNS that the chain is complete:

bash
1
2
3
4
5
6
7
8
curl -X POST https://scaidns.scailabs.ai/api/v1/domains/$DOMAIN_ID/dnssec/confirm-ds-published \
  -H "X-API-Key: $SCAIDNS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ds_records": [
      {"key_tag": 12345, "algorithm": 13, "digest_type": 2, "digest": "A1B2C3D4E5F6..."}
    ]
  }'

This step exists for audit purposes — the actual validation happens at resolvers, but recording confirmation gives you a trail of when DNSSEC went live for each zone.

5. Verify end-to-end#

bash
1
2
dig +dnssec +short www.example.com @1.1.1.1
dig +dnssec +multi www.example.com @1.1.1.1 | grep -E 'status|flags'

In the full response, look for:

  • Header flags containing ad — the resolver validated the answer.
  • No ad and no errors — the resolver doesn't validate (unusual), but your zone is still signed.
  • SERVFAIL — validation failed. Something in the chain is broken.

Alternatively, use an online analyzer: https://dnssec-analyzer.verisignlabs.com/example.com. Errors at each level explain where the chain breaks.

Rotating keys#

ZSK rotation (safe any time)#

bash
1
2
curl -X POST https://scaidns.scailabs.ai/api/v1/domains/$DOMAIN_ID/dnssec/rotate-zsk \
  -H "X-API-Key: $SCAIDNS_API_KEY"

Transparent to resolvers and registrars. ScaiDNS generates a new ZSK, signs the zone with both during the rollover window, then retires the old one.

KSK rotation (requires registrar coordination)#

bash
1
2
curl -X POST https://scaidns.scailabs.ai/api/v1/domains/$DOMAIN_ID/dnssec/rotate-ksk \
  -H "X-API-Key: $SCAIDNS_API_KEY"

Response includes the new DS record. Steps to complete:

  1. Add the new DS record at the registrar (keep the old one).
  2. Wait for propagation.
  3. Call /confirm-ds-published with the new DS record.
  4. After the overlap period, the old KSK is retired.
  5. Remove the old DS record at the registrar.

Do not remove the old DS record before the overlap completes. Validators may still be caching answers signed by the old key.

Disabling DNSSEC#

Remove the DS records at the registrar first. Then disable in ScaiDNS:

bash
1
2
curl -X POST https://scaidns.scailabs.ai/api/v1/domains/$DOMAIN_ID/dnssec/disable \
  -H "X-API-Key: $SCAIDNS_API_KEY"

If you disable with DS still at the registrar, resolvers see DS but no DNSKEY in the zone and return SERVFAIL.

Troubleshooting#

Symptom Check
dig +dnssec shows no ad flag Resolver may not be validating. Try 1.1.1.1 or 9.9.9.9
Online analyzer shows "no DS at parent" Registrar hasn't propagated the DS yet; wait or re-submit
Online analyzer shows "DS digest mismatch" DS at registrar doesn't match any KSK. Regenerate DS via GET /dnssec and republish
SERVFAIL from validating resolvers Broken chain. Often the DS at registrar references a retired KSK
SERVFAIL right after KSK rotation Normal briefly; resolvers still have old key cached

What's next#

Updated 2026-05-17 02:38:20 View source (.md) rev 1