OverviewFilesCommitsIssuesDocsReleasesPeers

atproto-bridge / tools / atproto-handle-resolution-test.sh

56 lines · bash ref:
#!/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 "══════════════════════════════════════════════"