AACWorkflow Docs

OAuth Protected Resource Metadata

RFC 9728 protected-resource metadata endpoint for MCP client authorization discovery.

The OAuth Protected Resource Metadata endpoint (RFC 9728) allows MCP clients to discover which OAuth authorization server protects AACWorkflow's API, without requiring prior configuration. This enables seamless integration with Claude, ChatGPT, and other MCP hosts.

Discovery endpoint

GET /.well-known/oauth-protected-resource

Returns:

{
  "resource": "https://aacworkflow.example.com/mcp",
  "authorization_servers": ["https://aacworkflow.example.com"],
  "scopes_supported": [
    "issues:read",
    "issues:write",
    "comments:read",
    "comments:write",
    "agents:read",
    "agents:write",
    "runtimes:read",
    "autopilot:run",
    "dashboard:read"
  ],
  "bearer_methods_supported": ["header"]
}
FieldMeaning
resourceThe MCP resource URL that is protected
authorization_serversArray of OAuth authorization server URLs that can issue access tokens for this resource
scopes_supportedList of scopes the resource recognizes
bearer_methods_supportedHow tokens are passed (header = Authorization: Bearer <token>)

WWW-Authenticate header discovery

When an MCP client makes a request to the protected resource without a token or with an invalid token, the server responds with a 401 Unauthorized and includes a WWW-Authenticate header:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://aacworkflow.example.com/.well-known/oauth-protected-resource"

This header tells the client: "This resource is protected by OAuth. Fetch the metadata at this URL to learn how to authenticate."

The client then:

  1. Fetches the metadata from the URL in resource_metadata
  2. Reads the authorization_servers to find where to register and obtain tokens
  3. Completes the OAuth flow using the metadata
  4. Retries the request with the new access token

Flow: zero-configuration client

A client that knows only the AACWorkflow API URL can bootstrap authentication:

Client: GET /api/issues
        (no Authorization header)

Server: 401 Unauthorized
        WWW-Authenticate: Bearer resource_metadata="https://aacworkflow.example.com/.well-known/oauth-protected-resource"

Client: GET /.well-known/oauth-protected-resource
Server: 200 OK
        {
          "authorization_servers": ["https://aacworkflow.example.com"],
          "scopes_supported": ["issues:read", "issues:write", ...],
          ...
        }

Client: Initiates OAuth with https://aacworkflow.example.com
        (discovers AS metadata from /.well-known/oauth-authorization-server)
        Completes auth-code + PKCE flow
        Receives access token

Client: GET /api/issues
        Authorization: Bearer <access_token>
Server: 200 OK
        [list of issues]

Compliance with RFC 9728

The metadata endpoint conforms to RFC 9728 — OAuth 2.0 Protected Resource Metadata:

  • Required fields: resource, authorization_servers, scopes_supported
  • Optional fields: bearer_methods_supported (for clarity; only header is used)
  • Cache headers: responses include appropriate cache-control directives

Integration with authorization-server metadata

The protected-resource metadata endpoint works in tandem with the authorization server metadata endpoint:

EndpointRFCPurpose
/.well-known/oauth-protected-resource9728Discover the AS protecting the resource
/.well-known/oauth-authorization-server8414Discover the AS endpoints and capabilities

A complete bootstrap flow:

1. Try to access /api/issues → 401 + WWW-Authenticate header
2. Fetch /.well-known/oauth-protected-resource → learn the AS URL
3. Fetch /.well-known/oauth-authorization-server → learn the endpoints
4. Complete OAuth flow at those endpoints
5. Retry with token

Use cases

Claude (via MCP)

Claude plugin in Claude.ai or Claude Desktop:

  1. User provides only the AACWorkflow URL
  2. Claude fetches the protected-resource metadata
  3. Claude presents the OAuth login
  4. User authorizes; Claude receives the token
  5. Claude can now call MCP tools on behalf of the user

ChatGPT

ChatGPT connector setup:

  1. User enters the AACWorkflow URL in ChatGPT settings
  2. ChatGPT fetches protected-resource metadata to discover the AS
  3. ChatGPT handles OAuth flow (user sees login)
  4. ChatGPT stores the token securely
  5. ChatGPT can invoke tools in subsequent conversations

Custom MCP servers

A custom MCP server that wraps AACWorkflow:

  1. Reads the protected-resource metadata
  2. Verifies the resource URL matches
  3. Checks that all required scopes are in scopes_supported
  4. Knows exactly where to send OAuth requests

No manual configuration of authorization server URLs is needed. Clients read it from the metadata.

Security

  • Metadata is public — it does not require authentication
  • Metadata is cacheable — CDN/browser caching is fine
  • Metadata is static — authorization server URL does not change frequently
  • Token validation still requires full scope and signature checks; metadata is discovery-only