Skip to content

HTTP domain authentication fails signature verification with matching Ed25519 key #1679

Open

Description

@chrismann040-commits

I am trying to publish a remote MCP server using HTTP domain authentication.

Environment:

  • Windows 10
  • mcp-publisher 1.8.1
  • OpenSSL 4.0.2
  • Domain: bodywise.io
  • Server name: io.bodywise/public
  • Authentication method: HTTP domain verification

The public proof is served successfully at:

https://bodywise.io/.well-known/mcp-registry-auth

With Ed25519:

  • The private key passed to mcp-publisher is exactly 64 hex characters.
  • mcp-publisher prints an "Expected proof record".
  • That expected proof record exactly matches the proof record being served by bodywise.io.
  • The keypair was independently tested locally with OpenSSL:
    "Signature Verified Successfully"

However:

mcp-publisher login http --domain "bodywise.io" --private-key "<64-char private key>"

fails with:

401 Unauthorized
HTTP authentication failed
signature verification failed

I also tested the supported ECDSA P-384 HTTP authentication method.

Again:

  • mcp-publisher derived the expected public proof record.
  • The live bodywise.io verification endpoint served that same proof record.
  • Login still failed at signature verification with 401.

The MCP server itself is live at:

https://bodywise.io/api/mcp

The prepared server.json passes mcp-publisher validate.

I have not included any private keys in this report.

Is this a current issue with HTTP domain authentication / signature verification, or is there another step required for domain authentication?

Activity

  1. basitalisandhu commented on Oct 13, 2026

    @basitalisandhu

    I checked what the registry would see for your domain today (2026-10-13 05:00 UTC), and the proof itself looks fine.

    • https://bodywise.io/.well-known/mcp-registry-auth returns 200 text/plain, 92 bytes, v=MCPv1; k=ecdsap384; p=A2FizsW8..., with no trailing newline or BOM. I get the same body when I send the registry's own request headers (User-Agent: mcp-registry/1.0, Accept: text/plain, http.go#L181-L189).
    • I fed that exact string to the registry's parser (ParseMCPKeysFromStrings on main 11b7b0e). It parses as a valid compressed P-384 key with fingerprint ecdsap384:A2FizsW8.

    So the 401 is a real mismatch: the registry verified your signature against a public key that doesn't belong to the private key you signed with. The production registry (1.8.1) tells you which key it used. The full error line should end with something like signature verification failed (tried published key ecdsap384:XXXXXXXX); if this is not the key you are signing with, the published record may be stale (common.go#L150-L155). Could you post that full line from an ECDSA attempt?

    • If the fingerprint is not ecdsap384:A2FizsW8, the registry got a different file from the one you and I see. Your response carries cache-control: public, max-age=300, so after switching keys or algorithms, wait at least five minutes before retrying, and make sure every edge or deployment serves the new file.
    • If it is A2FizsW8, the private key in that command isn't the one behind this record. Re-run mcp-publisher login http --algorithm ecdsap384 --domain bodywise.io --private-key <96 hex chars> and check that the "Expected proof record" it prints in that same run is byte-identical to the served file.

    One unrelated thing you might also hit with ECDSA: about 1 login in 140 fails (146 of 20,000 signatures in a local run) with invalid signature size for ECDSA P-384, because the publisher doesn't zero-pad r and s (cmd/publisher/auth/common.go#L130). That is fixed by the open #1457. If you see that message, just retry.

    Prepared with help from Claude Code. I made the HTTP requests and ran the registry parser myself; I did not call the production auth endpoint for your domain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions