#!/usr/bin/env bash
# atproto-handle-resolution-test.sh — empirically validate how bsky resolves a
# handle, and prove whether a TLS cert on the handle hostname is required.
#
# Thesis under test (issue #85): a *subdomain* handle can be verified by a
# `_atproto.<handle>` DNS TXT record ALONE — no A record, no web server, no TLS
# cert on the subdomain. Only the shared PDS host (named in the DID doc) needs
# TLS. So wildcard DNS + apex-only cert is sufficient for unlimited pretty
# verified handles.
#
# Usage: ./atproto-handle-resolution-test.sh <handle> [<handle> ...]
set -u
DNS=1.1.1.1
APPVIEW=https://public.api.bsky.app
PLC=https://plc.directory
check () {
h="$1"; echo "══════════════════════════════════════════════"; echo "HANDLE: $h"
# 1. What bsky's OWN resolver returns (this is the arbiter)
did=$(curl -s --max-time 8 "$APPVIEW/xrpc/com.atproto.identity.resolveHandle?handle=$h" \
| sed -n 's/.*"did":"\([^"]*\)".*/\1/p')
echo " [1] bsky resolveHandle → ${did:-<FAILED>}"
[ -z "$did" ] && { echo " (bsky does not resolve this handle)"; return; }
# 2. Which mechanism backs it?
txt=$(dig +short TXT _atproto.$h @$DNS 2>/dev/null | tr -d '"' | tr '\n' ' ')
a=$(dig +short A $h @$DNS 2>/dev/null | tr '\n' ' ')
echo " [2] _atproto.$h TXT → [${txt:-<none>}]"
echo " $h A record → [${a:-<NONE — hostname has no web endpoint>}]"
# 3. Is the HTTPS well-known / TLS path even usable?
wk=$(curl -sS --max-time 8 "https://$h/.well-known/atproto-did" 2>&1 | head -c 80)
echo " [3] https://$h/.well-known/atproto-did → ${wk:-<empty>}"
# 4. Bidirectional half: does the DID doc claim this handle back?
aka=$(curl -s --max-time 8 "$PLC/$did" | sed -n 's/.*"alsoKnownAs":\[\([^]]*\)\].*/\1/p')
echo " [4] DID doc alsoKnownAs → ${aka:-<none>}"
# 5. Where is the actual data (PDS)? — should be a SHARED host, not this handle
pds=$(curl -s --max-time 8 "$PLC/$did" \
| sed -n 's/.*"serviceEndpoint":"\([^"]*\)".*/\1/p' | head -1)
echo " [5] PDS serviceEndpoint → ${pds:-<none>}"
# verdict
if [ -n "$txt" ] && [ -z "$a" ]; then
echo " ⇒ VERDICT: verified by DNS TXT ONLY. No A record, no server, NO TLS cert on '$h'."
elif [ -n "$txt" ]; then
echo " ⇒ VERDICT: DNS TXT present (authoritative; resolver tries it first). Cert on '$h' not required."
else
echo " ⇒ VERDICT: no TXT — this handle uses the HTTPS well-known method (needs a cert on '$h')."
fi
}
for h in "$@"; do check "$h"; done
echo "══════════════════════════════════════════════"