Skip to content

Setup guide

Amazon Route 53 setup guide for sslcertificates.io

Connect Amazon Route 53 to sslcertificates.io to automate DNS-01 validation: hosted zone discovery, ChangeResourceRecordSets for acme-challenge TXT records, GetChange until INSYNC, read-back verification, public DNS propagation checks, safe cleanup, and credential rotation.

What this integration does

Route 53 DNS-01 uses AWS Signature Version 4. The connector lists hosted zones, selects the best match for the hostname being validated, submits ChangeResourceRecordSets with an UPSERT of the exact TXT value from the ACME order, polls GetChange until the change status is INSYNC, reads the resource record set back, waits until public resolvers return the TXT, and after validation deletes only the TXT value the platform created. Alias records, traffic policies, and unrelated RRsets are never modified.

Public integration page: /integrations/route53.

AWS prerequisites

You need an AWS account with Route 53 hosted zones for the domains you will validate. Each public hostname must live in a hosted zone whose name matches the apex or a parent of the name being issued. For www.example.com, the zone is usually example.com.. For delegated subdomains, the challenge may appear in the child zone — discovery selects the longest matching zone.

Create or identify a disposable test zone before your first Live order if you are experimenting with IAM policies. Production zones work once IAM is correct; mistakes in ChangeResourceRecordSets affect real DNS.

Enable CloudTrail in the account if your security team requires an audit trail of DNS changes. sslcertificates.io does not need CloudTrail access — it is your governance choice.

Authentication approaches

The workspace connection form accepts either long-term IAM user access keys or role assumption (Role ARN plus optional External ID). Prefer role assumption when sslcertificates.io publishes a fixed External ID for your organization — you grant sts:AssumeRole to that principal in your account and avoid distributing access keys.

IAM user access keys

Create a dedicated IAM user such as sslcertificates-io-dns-test with no console login. Attach an inline or managed policy scoped to the hosted zones you intend to automate. Store access_key_id and secret_access_key in the integration form once; they are encrypted at rest and never displayed again.

Rotate keys by creating a second key, updating the integration, running Test connection, deleting the old key at AWS, and revoking the old material in your password manager.

IAM role assumption

Create a role trust policy allowing sslcertificates.io to call sts:AssumeRole (exact principal is shown in the workspace when you choose role-based auth). Attach the same Route 53 policy to the role. Provide role_arn, optional external_id, and default region if your zones are regional (Route 53 is global; region still affects SigV4 endpoint selection for the SDK).

External ID prevents confused-deputy problems when multiple customers use similar role names. Treat it like a shared secret between you and sslcertificates.io.

IAM least privilege

Grant only what DNS-01 automation requires on the zones you select:

  • route53:ListHostedZones — discovery
  • route53:ListResourceRecordSets — read-back after UPSERT
  • route53:ChangeResourceRecordSets — UPSERT and DELETE of owned TXT values
  • route53:GetChange — poll until INSYNC

Do not attach AdministratorAccess or AmazonRoute53FullAccess account-wide unless your security exception process requires it and you accept blast radius. Prefer a policy resource list of arn:aws:route53:::hostedzone/ZONEID for each zone.

Example policy skeleton (replace hosted zone IDs):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "route53:ListHostedZones",
        "route53:ListResourceRecordSets",
        "route53:ChangeResourceRecordSets",
        "route53:GetChange"
      ],
      "Resource": [
        "arn:aws:route53:::hostedzone/ZZZZZZZZZZZZZ"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "route53:ListHostedZones",
      "Resource": "*"
    }
  ]
}

The second statement is often required because ListHostedZones is evaluated on *. Restrict ChangeResourceRecordSets to specific zone ARNs.

Connect in sslcertificates.io

  1. Sign in and open Workspace → Integrations → Amazon Route 53 (or /workspace/integrations/route53).
  2. Enter region (if prompted), Role ARN or access keys, and External ID when using roles.
  3. Click Test connection. Authentication must succeed before discovery runs.
  4. Run Discover and select hosted zones this organization may manage. Do not paste opaque zone IDs unless discovery cannot list them.
  5. Issue a Test certificate (Let's Encrypt Staging) with DNS-01 before Live.

Hosted zone discovery

Discovery calls ListHostedZones and matches zone names to the hostname on the order. If you operate many zones, select only those this organization should touch. A credential that lists zones in another AWS account usually means the wrong keys or role.

If discovery is empty, widen ListHostedZones temporarily, confirm you are in the intended AWS account, and verify the IAM user or role is in the same account as the zones.

ChangeResourceRecordSets and TXT lifecycle

When an order presents DNS-01, the platform computes the _acme-challenge label relative to the zone apex. It submits a change batch with action UPSERT and the exact token from Let's Encrypt Staging or Production — never a guessed value.

TXT lifecycle:

  1. UPSERT TXT at _acme-challenge.example.com with the order token.
  2. Poll GetChange until status INSYNC.
  3. ListResourceRecordSets read-back confirms the value on the authoritative Route 53 servers.
  4. Wait for public DNS resolvers (propagation check from sslcertificates.io).
  5. POST /api/v1/certificate-orders/{id}/validate when resolvers match.
  6. After issuance or failure cleanup, DELETE only the TXT RRset value this automation added.

The connector never deletes pre-existing TXT records it did not create. If you manually added _acme-challenge TXT for another CA, cleanup must not remove unrelated values — the implementation tracks owned values.

GetChange and INSYNC

Route 53 applies changes asynchronously. GetChange returns PENDING then INSYNC. Do not call validate immediately after UPSERT without either INSYNC or a positive propagation check — orders may fail with dns_propagation_timeout or acme_validation_failed.

Read-back and DNS propagation

Authoritative Route 53 data can differ from what public resolvers cache. sslcertificates.io queries public DNS after INSYNC. TTL on existing TXT records affects how long old values linger. Lower TTL on _acme-challenge only when you operate manual DNS alongside automation.

Use /tools/dns-propagation or dig TXT _acme-challenge.example.com @8.8.8.8 from your workstation as a second opinion.

Wildcard certificates

Wildcards such as *.example.com require DNS-01. The challenge name is still _acme-challenge.example.com for a wildcard on that apex (same as non-wildcard apex validation). HTTP-01 cannot validate wildcards — the API returns wildcard_requires_dns if you request otherwise.

Ensure the selected hosted zone is the apex zone that holds the _acme-challenge name Let's Encrypt expects.

CAA interaction

If CAA records at the apex restrict which CAs may issue, fix CAA before ordering. sslcertificates.io does not bypass CAA. Add issue "letsencrypt.org" (and issuewild for wildcards) or remove restrictive tags. Failed CAA checks surface as CA errors on the order with stable codes — not as Route 53 failures.

Test vs Live

Test orders use Let's Encrypt Staging. Route 53 changes are real in your zone — only the CA trust differs. Prove IAM, discovery, UPSERT, validate, and cleanup on Staging before Live.

Live orders use Let's Encrypt Production or another CA you selected. Rate limits are stricter. Use separate API keys labeled Test and Live.

Safe cleanup

After validation succeeds or the order is abandoned, automation removes the owned TXT value. If cleanup fails, delete the stale _acme-challenge TXT manually in Route 53 to avoid confusing the next order. Never delete legitimate SPF/DKIM/DMARC TXT at the apex while cleaning challenges — only the _acme-challenge name should be touched.

Credential rotation

Schedule rotation every 90 days for IAM users. For roles, rotate by updating trust or External ID policy on your side, then Test connection. Disconnect removes stored credentials from sslcertificates.io but does not delete IAM users in AWS — deprovision AWS-side principals when offboarding.

Disconnect

Workspace → Integrations → Route 53 → Disconnect removes encrypted credentials for this organization. It does not delete hosted zones or unrelated records. Run disconnect before offboarding a contractor who had integration access.

Errors and troubleshooting

Symptom Likely cause Action
AccessDenied on Test connection IAM missing actions or wrong resource ARN Fix policy; include ListHostedZones on * if required
Discovery empty Keys for wrong account Switch role or keys; confirm account ID in ARNs
Change batch rejected Zone ID mismatch Rediscover; select correct zone
Stuck pending validation Validate called too early Wait for INSYNC and public TXT
dns_propagation_timeout TTL/cache Wait and retry validate with backoff
Cleanup left TXT DELETE denied Grant ChangeResourceRecordSets on same zone
Live rate limit Too many failed tests on Production Return to Test environment

Include X-Request-Id from API responses when contacting support.

Examples

Test order (curl sketch):

curl -sS -X POST "$BASE/api/v1/certificates" \
  -H "Authorization: Bearer $TEST_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domains":["www.example.com"],"validation":"dns-01","environment":"test"}'

After challenges appear, confirm TXT in Route 53, then:

curl -sS -X POST "$BASE/api/v1/certificate-orders/$ORDER_ID/validate" \
  -H "Authorization: Bearer $TEST_TOKEN"

Official vendor documentation

Related reading

  • /integrations/route53 — public integration summary
  • /docs/test-vs-live — Staging vs Production issuance
  • /docs/dns-01 — validation overview
  • /academy/route53-dns-01 — Academy explainer