Read small configuration values through an encrypted DNS transport with a namespace-scoped query token.
Applications often need a small configuration document without adding another proprietary client protocol.
Store a value of up to 2,586 decoded bytes through the REST API, mint an opaque namespace query token, and read the record over DoH or DoT. Private answers use DNS RR TTL 0 even when the TXT envelope retains a nonzero configured ttl hint.
Distribute a small JSON document to clients that can make DNS queries.
get.auth-rdbq<52>.config.your-namespace.v1.resolvedb.netUse the operator-managed Hooli fixtures to test parsing without a token.
get.dark-mode.flags.hooli.v1.resolvedb.netauth-rdbqNamespace Query TokenOpaque bearer token returned once, stored as a digest, and authorized for one private namespace.
# Query a private hosted record over DoT.
export RDBQ='rdbq...'
kdig +tls-ca +tls-hostname=dot.resolvedb.io @dot.resolvedb.io \
TXT "get.auth-${RDBQ}.config.your-namespace.v1.resolvedb.net"import base64
import json
import os
import dns.message
import dns.query
token = os.environ["RDBQ"]
name = f"get.auth-{token}.config.your-namespace.v1.resolvedb.net"
query = dns.message.make_query(name, "TXT")
response = dns.query.https(query, "https://doh.resolvedb.io/dns-query")
record = next(iter(response.answer[0]))
txt = b"".join(record.strings).decode("utf-8")
metadata_text, payload = txt.split(";d=", 1)
metadata = dict(field.split("=", 1) for field in metadata_text.split(";"))
if metadata.get("e") == "b64":
payload = base64.b64decode(payload).decode("utf-8")
config = json.loads(payload)const token = process.env.RDBQ
const name = `get.auth-${token}.config.your-namespace.v1.resolvedb.net`
const url = `https://doh.resolvedb.io/resolve?name=${encodeURIComponent(name)}&type=TXT`
const response = await fetch(url)
const dns = await response.json()
const chunks = dns.Answer[0].data.match(/"(?:\\.|[^"\\])*"/g) ?? []
const txt = chunks.map((chunk) => JSON.parse(chunk)).join('')
const marker = ';d='
const index = txt.indexOf(marker)
const metadata = Object.fromEntries(
txt.slice(0, index).split(';').map((field) => field.split('=', 2)),
)
let payload = txt.slice(index + marker.length)
if (metadata.e === 'b64') payload = Buffer.from(payload, 'base64').toString('utf8')
const config = JSON.parse(payload)token := os.Getenv("RDBQ")
name := fmt.Sprintf("get.auth-%s.config.your-namespace.v1.resolvedb.net", token)
endpoint := "https://doh.resolvedb.io/resolve?name=" + url.QueryEscape(name) + "&type=TXT"
response, err := http.Get(endpoint)
if err != nil { log.Fatal(err) }
defer response.Body.Close()
var dnsResponse struct { Answer []struct { Data string } }
if err := json.NewDecoder(response.Body).Decode(&dnsResponse); err != nil { log.Fatal(err) }
rr, err := dns.NewRR("example. 0 IN TXT " + dnsResponse.Answer[0].Data)
if err != nil { log.Fatal(err) }
txt := strings.Join(rr.(*dns.TXT).Txt, "")
parts := strings.SplitN(txt, ";d=", 2)
if len(parts) != 2 { log.Fatal("missing UQRP data") }
metadata := map[string]string{}
for _, field := range strings.Split(parts[0], ";") {
pair := strings.SplitN(field, "=", 2)
if len(pair) == 2 { metadata[pair[0]] = pair[1] }
}
payload := []byte(parts[1])
if metadata["e"] == "b64" {
payload, err = base64.StdEncoding.DecodeString(parts[1])
if err != nil { log.Fatal(err) }
}
var config map[string]any
if err := json.Unmarshal(payload, &config); err != nil { log.Fatal(err) }| Feature | ResolveDB | Alternative |
|---|---|---|
| Read transport | DNS, DoH, or DoT | Application-specific HTTP client |
| Write transport | REST API | Application-specific API |
| Private caching | DNS RR TTL 0 | Application-defined |
| Maximum decoded value | 2,586 bytes | Varies |
No. Every authenticated private answer has DNS RR TTL 0. The TXT envelope may still show the record's configured ttl hint; clients must not treat that hint as permission to cache.
No. Production DNS authorization accepts only the namespace rdbq token. Customer JWTs and API keys are REST-only.
Create or update records through the dashboard or REST API. Writes replicate to the DNS fleet through the transactional outbox.
Create an account and start storing data in under a minute.