One-click enable or disable the WAB DNS Discovery TXT record on any Route 53 hosted zone. Uses the AWS Route 53 REST API via AWS SDK v2 — your credentials stay in your browser only.
route53:ChangeResourceRecordSets
and route53:ListResourceRecordSets permissions on the specific hosted zone.
Never use root account credentials.
GET /api/discovery/provider/record-template) to get TXT value: v=wab1; endpoint=https://…ListHostedZonesByName to resolve it from the domain name.ChangeResourceRecordSets with action UPSERT — creates or updates _wab.example.com TXT.ChangeResourceRecordSets with action DELETE./api/discovery/provider/status. Route 53 propagation is typically 60 s or less.// npm install @aws-sdk/client-route-53
import { Route53Client, ChangeResourceRecordSetsCommand, ListHostedZonesByNameCommand, ListResourceRecordSetsCommand } from '@aws-sdk/client-route-53';
const client = new Route53Client({ region: 'us-east-1' });
const DOMAIN = 'example.com';
const ENDPOINT = `https://${DOMAIN}/.well-known/wab.json`;
const TXT_VAL = `"v=wab1; endpoint=${ENDPOINT}"`; // Route 53 requires double-quoted TXT
async function getZoneId() {
const r = await client.send(new ListHostedZonesByNameCommand({ DNSName: DOMAIN, MaxItems: '1' }));
const zone = r.HostedZones.find(z => z.Name === `${DOMAIN}.`);
if (!zone) throw new Error(`No hosted zone found for ${DOMAIN}`);
return zone.Id.replace('/hostedzone/', '');
}
async function getCurrentRecord(zoneId) {
const r = await client.send(new ListResourceRecordSetsCommand({
HostedZoneId: zoneId, StartRecordName: `_wab.${DOMAIN}`, StartRecordType: 'TXT', MaxItems: '1'
}));
return r.ResourceRecordSets.find(rr => rr.Name === `_wab.${DOMAIN}.` && rr.Type === 'TXT') || null;
}
async function enableWAB() {
const zoneId = await getZoneId();
await client.send(new ChangeResourceRecordSetsCommand({
HostedZoneId: zoneId,
ChangeBatch: {
Changes: [{ Action: 'UPSERT', ResourceRecordSet: {
Name: `_wab.${DOMAIN}`, Type: 'TXT', TTL: 3600,
ResourceRecords: [{ Value: TXT_VAL }]
}}]
}
}));
console.log('WAB Discovery ENABLED (UPSERT applied)');
}
async function disableWAB() {
const zoneId = await getZoneId();
const existing = await getCurrentRecord(zoneId);
if (!existing) { console.log('Already disabled.'); return; }
await client.send(new ChangeResourceRecordSetsCommand({
HostedZoneId: zoneId,
ChangeBatch: { Changes: [{ Action: 'DELETE', ResourceRecordSet: existing }] }
}));
console.log('WAB Discovery DISABLED (record deleted)');
}
enableWAB().catch(console.error);
# Set credentials
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=us-east-1
# 1. Get Hosted Zone ID
ZONE_ID=$(aws route53 list-hosted-zones-by-name \
--dns-name example.com --query "HostedZones[0].Id" --output text | cut -d/ -f3)
# 2. Enable (UPSERT)
aws route53 change-resource-record-sets \
--hosted-zone-id "$ZONE_ID" \
--change-batch '{
"Changes": [{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "_wab.example.com",
"Type": "TXT",
"TTL": 3600,
"ResourceRecords": [{"Value": "\"v=wab1; endpoint=https://example.com/.well-known/wab.json\""}]
}
}]
}'
# 3. Disable (DELETE) — first fetch current record to match exactly
CURRENT_VALUE=$(aws route53 list-resource-record-sets \
--hosted-zone-id "$ZONE_ID" \
--query "ResourceRecordSets[?Name=='_wab.example.com.'].ResourceRecords[0].Value" \
--output text)
aws route53 change-resource-record-sets \
--hosted-zone-id "$ZONE_ID" \
--change-batch "{
\"Changes\": [{
\"Action\": \"DELETE\",
\"ResourceRecordSet\": {
\"Name\": \"_wab.example.com\",
\"Type\": \"TXT\",
\"TTL\": 3600,
\"ResourceRecords\": [{\"Value\": \"$CURRENT_VALUE\"}]
}
}]
}"
# terraform — manages _wab TXT record declaratively
data "aws_route53_zone" "zone" {
name = "example.com."
}
resource "aws_route53_record" "wab_discovery" {
zone_id = data.aws_route53_zone.zone.zone_id
name = "_wab.example.com"
type = "TXT"
ttl = 3600
records = ["v=wab1; endpoint=https://example.com/.well-known/wab.json"]
}
# To disable: remove the resource block and run `terraform apply`
# Or use count = 0 to toggle:
# count = var.wab_enabled ? 1 : 0
Create a dedicated IAM user / role with this policy, scoped to only the required hosted zone.
Replace ZONE_ID with your actual Zone ID.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets",
"route53:ListResourceRecordSets"
],
"Resource": "arn:aws:route53:::hostedzone/ZONE_ID"
},
{
"Effect": "Allow",
"Action": "route53:ListHostedZonesByName",
"Resource": "*"
}
]
}
← Back to Provider Onboarding · Cloudflare · cPanel · Sandbox · DNS Discovery