Skip to content

fix(auth): better DNS verification errors and wrong-selector hint#1202

Merged
rdimitrov merged 2 commits intomainfrom
fix/dns-auth-wrong-selector-error
Apr 25, 2026
Merged

fix(auth): better DNS verification errors and wrong-selector hint#1202
rdimitrov merged 2 commits intomainfrom
fix/dns-auth-wrong-selector-error

Conversation

@rdimitrov
Copy link
Copy Markdown
Member

Summary

DNS auth users have repeatedly hit two failure modes that both produce the same opaque "Ed25519 signature verification failed" error, making them indistinguishable to debug. This PR makes both diagnosable end-to-end without changing the auth protocol or any successful path.

The two recurring failure modes:

  1. Wrong placement — TXT record put under a selector (_mcp-auth.<domain> or _mcp-registry.<domain>) instead of the apex. DKIM-style intuition, but MCP DNS auth uses SPF-style apex placement. See Issues authenticating with custom domain for MCP registry #385 (PR docs: fix DNS authentication to use root domain instead of _mcp-registry subdomain #388 fixed the docs but the failure recurred), Request: Reset signing key for dev.agentsim namespace #1103, DNS authentication always fails: Ed25519 signature verification failed #1126.
  2. Stale apex record — old TXT record left behind after a key rotation, silently tried first and rejected.

Changes

internal/api/handlers/v0/auth/dns.go — when the apex has no v=MCPv1 record, probe _mcp-auth.<domain> and _mcp-registry.<domain> in parallel (2s individual timeout). If a record is found there, return a targeted error pointing the user at the apex. Costs zero extra DNS work in the success path.

internal/api/handlers/v0/auth/common.go — when verification fails against records that are present, include short fingerprints of every key the registry tried (ed25519:YJLsHFhu-style 8-char prefix). A new ErrSignatureMismatch sentinel keeps structural errors (wrong signature size, unsupported algorithm) passing through unchanged via errors.Is, so existing assertions on those messages still hold.

docs/modelcontextprotocol-io/authentication.mdx — anti-pattern <Warning> callout in the DNS section explicitly warning against selector placement and stale records.

Tests — two new tests:

  • TestDNSAuthHandler_WrongSelectorProbe — verifies the probe surfaces records found at _mcp-auth. / _mcp-registry. and falls through to the standard error when nothing is found anywhere
  • TestDNSAuthHandler_StaleKeyFingerprintInError — verifies the fingerprint hint appears in the failure message for DNS authentication always fails: Ed25519 signature verification failed #1126's exact scenario

One existing test assertion was updated from a generic "signature verification failed" substring to the more specific "invalid signature size for ECDSA P-384" it should always have been asserting; the new sentinel-based logic surfaces structural errors verbatim.

Test plan

  • make lint — clean
  • make test-unit — all auth tests pass (existing + 2 new)
  • Verified existing single-key and multi-key paths preserve their original (more specific) error messages where they were already specific
  • Reviewer to sanity-check the docs callout renders well in the Mintlify theme

Out of scope

The publisher-side preflight DNS check (cross-link in #845) is intentionally not in this PR — that belongs in the broader CLI UX work tracked by #845.

Refs #845, #385, #1103
Fixes #1126

DNS auth users repeatedly hit two failure modes that produce identical,
unhelpful "Ed25519 signature verification failed" errors (#385, #1103,
#1126):

1. TXT record placed under a selector (_mcp-auth./_mcp-registry.)
   instead of the apex — DKIM intuition, but MCP DNS auth uses SPF-style
   apex placement.
2. Stale TXT record left at the apex after a key rotation, silently
   tried first and rejected.

Server changes:
- When the apex has no MCPv1 record, probe common wrong selectors and
  return a targeted error pointing the user at the apex.
- When verification fails on records that *are* present, include short
  fingerprints of every key the registry tried so the user can tell a
  stale record from a real signing problem. Structural errors (wrong
  signature size, etc.) still pass through unchanged via a new
  ErrSignatureMismatch sentinel.

Docs:
- Anti-pattern callout in authentication.mdx warning explicitly against
  selector placement and stale records.

Refs #845, #385, #1103
Fixes #1126
A loose strings.Contains(r, "v=MCPv1") check at the apex would
suppress the misplaced-selector probe whenever a malformed MCPv1
string was present, hiding the helpful "record is at _mcp-auth"
hint from the user.

Share the strict proof-record regex with the parser so presence
detection and parsing agree on what counts as an MCPv1 record.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rdimitrov rdimitrov merged commit c5f50e8 into main Apr 25, 2026
6 checks passed
@rdimitrov rdimitrov deleted the fix/dns-auth-wrong-selector-error branch April 25, 2026 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DNS authentication always fails: Ed25519 signature verification failed

2 participants