Signed UCP tools/call requests fail with AuthenticationFailed/key_not_found — eight independent causes ruled out, need server-side visibility

I’m building a read-only shopping-discovery agent calling the Storefront Catalog MCP endpoint (POST https://{store}/api/ucp/mcp) on individual Shopify stores using the “Signed” auth tier (RFC 9421 HTTP Message Signatures, no pre-established credential).

Every signed search_catalog/get_product call returns:

HTTP 401

{“jsonrpc”:“2.0”,“id”:1,“error”:{“code”:-32000,“message”:“AuthenticationFailed”,“data”:“HTTP signature error: key_not_found”}}

Consistent across two independently-run stores, unchanged across seven separate live tests, plus one more claim ruled out by re-checking the spec directly:

  1. Removed a non-spec alg parameter from Signature-Input.
  2. Added use: “sig” to the published JWK.
  3. Added a services/capabilities object, matching your own real example profile, including your dev.shopify.catalog extension.
  4. Published the key at both top-level keys and nested ucp.keys.
  5. Renamed the key’s kid entirely (label only, same key pair) — failed identically even with an id your system had never seen before.
  6. Signed a tools/list call as a diagnostic — got a real 200, but that’s inconclusive since tools/list succeeds unauthenticated regardless.
  7. Sent ucp-agent as a bare URL instead of the structured-field form — identical result.
  8. Considered a JWK Set wrapper object for keys — ruled out without testing, since your own spec’s literal example shows a plain array.

Current published profile is well-formed and reachable at https://walrus-app-ugbp6.ondigitalocean.app/.well-known/ucp, with a JWK confirmed to match my signing key byte-for-byte.

What I need: since content, identifier, and header-format changes all produce the identical error, I can’t narrow this further from my side. Could someone check server-side logs for my profile URL or either kid? Two things I can’t verify externally: the storefront endpoint may only fully support Anonymous/Token tiers right now, with Signed-tier attempts misrouted into a “key lookup failed” error; or the verifier may read a different profile field than the public docs describe.

I can provide a full raw request/response capture if useful.

1 Like