Discovery API
Cross-language discover() options and behaviors
Discovery API (v1.2)
Cross-language parity for AID discover() wrappers with consistent security and fallback behavior.
Common behaviors
- IDNA: Normalize domains to A-label (Punycode) before DNS.
- Exact-host only: build DNS and
.well-knownlookups from the exact host the caller supplied after IDNA normalization. Do not implicitly walk to parent hosts. - DNS-first: Query
_agent.<domain>. Whenprotocolis specified, try protocol-specific names for that same exact host before base. - TXT parsing: Enforce v1.2 record rules (aliases, schemes, metadata constraints).
- Multiple TXT answers: exactly one valid AID record at a queried DNS name succeeds;
2+valid records fail as ambiguity instead of using resolver order. - PKA: When
pka/kidpresent, perform Ed25519 HTTP Message Signatures handshake with exact covered fields set. - Well-known fallback: Only on
ERR_NO_RECORDorERR_DNS_LOOKUP_FAILED. HTTPS JSON, ≤64KB, ~2s timeout, no redirects. Successful fallback usesTTL=300. - Redirect policy: Do not auto-follow redirects for handshake or well-known.
- Delegation: if operators want inheritance, they should delegate the exact
_agent.<child-host>label in DNS, for example withCNAME.
Options by language
- TypeScript/Node:
{ protocol?: string; timeout?: number; wellKnownFallback?: boolean; wellKnownTimeoutMs?: number; securityMode?: 'balanced' | 'strict'; dnssecPolicy?: 'off' | 'prefer' | 'require'; pkaPolicy?: 'if-present' | 'require'; downgradePolicy?: 'off' | 'warn' | 'fail'; wellKnownPolicy?: 'auto' | 'disable'; previousSecurity?: { pka?: string | null; kid?: string | null } } - TypeScript/Browser: same policy fields as Node, plus
dohProvider?: string - Python:
discover(domain, *, protocol=None, timeout=5.0, well_known_fallback=True, well_known_timeout=2.0)- Accepts camelCase aliases
wellKnownFallbackandwellKnownTimeoutMs(deprecated with warnings)
- Accepts camelCase aliases
- Go:
DiscoverWithOptions(domain string, timeout time.Duration, opts DiscoveryOptions)DiscoveryOptions{ Protocol string; WellKnownFallback bool; WellKnownTimeout time.Duration }
- Rust:
discover_with_options(domain: &str, options: DiscoveryOptions)DiscoveryOptions { protocol: Option<String>, timeout: Duration, well_known_fallback: bool, well_known_timeout: Duration }
- .NET:
Discovery.DiscoverAsync(string domain, DiscoveryOptions? options = null)DiscoveryOptions { string? Protocol; TimeSpan Timeout; bool WellKnownFallback; TimeSpan WellKnownTimeout }
- Java:
Discovery.discover(String domain, DiscoveryOptions options)DiscoveryOptions { String protocol; Duration timeout; boolean wellKnownFallback; Duration wellKnownTimeout }
Error codes
1000ERR_NO_RECORD– No_agentTXT record found1001ERR_INVALID_TXT– Malformed record1002ERR_UNSUPPORTED_PROTO– Unsupportedproto1003ERR_SECURITY– Security policy violation1004ERR_DNS_LOOKUP_FAILED– DNS/network failure1005ERR_FALLBACK_FAILED–.well-knownfetch invalid/failed
Notes
- Loopback relax: allowed only for
.well-knownfallback and only on loopback hosts; env/flag gated per language (never for TXT). - Rust PKA is behind the
handshakefeature; enable it to run handshake verification. balancedandstrictare the normative enterprise presets for v1.2.x.- The reference TypeScript SDK and
aid-doctorCLI currently expose the full preset/knob surface. Other SDKs should map to the same policy model as they catch up. - Test your implementation using the aid-doctor CLI tool for real-world validation.