Skip to content

TRX-008Buy

OAuth protected resource metadata published

Checks whether your shop publishes OAuth protected resource metadata, which tells an agent how to get permission to call your APIs.

What we check

RFC 9728 (April 2025) defines a JSON document at /.well-known/oauth-protected-resource that describes an API protected by OAuth. Its one required field, resource, must be exactly the address the document belongs to, which for this root path is your shop's origin. The optional authorization_servers field lists the sign-in servers an agent should use to obtain a token. It is also the starting point the Model Context Protocol (MCP) uses for authorization.

Why it matters

If agents call your APIs or an MCP server for your shop on a customer's behalf, this document is how they find out which authorization server to ask for a token. Without it, an agent has to be configured for your shop by hand. Shopify appears to publish this document at the platform level, though that has not been verified for every store.

How we check

We request /.well-known/oauth-protected-resource once and never follow or call anything it lists. PASS when it answers 200 with a JSON object whose resource equals your origin (a trailing slash and host capitalisation are ignored), whose authorization_servers, if present, is an array, and which is served as application/json. A document without authorization_servers still passes, and the result says none are listed. WARN when the body is not JSON or not an object, when resource is missing, when resource names a different address (the usual sign of a copied template), when authorization_servers is not an array, or when the media type is wrong. FAIL when there is no document (404, 410, or your own HTML page). We SKIP when the path is blocked by bot management, refused, or answered with an error such as 429 or 5xx.

How to fix it

  1. If agents can call your shop's APIs or MCP server with OAuth tokens, publish RFC 9728 metadata at /.well-known/oauth-protected-resource.
  2. Set "resource" to your shop's origin exactly, for example https://shop.example, and list the issuers agents should use in "authorization_servers".
  3. Serve it as application/json with status 200.

What good looks like

GET /.well-known/oauth-protected-resource
Content-Type: application/json

{
  "resource": "https://shop.example",
  "authorization_servers": ["https://auth.shop.example"]
}

Sources