Skip to content

feat(agents): auth.md, Web Bot Auth, A2A Agent Card, OAuth discovery - #1244

Merged
riderx merged 2 commits into
mainfrom
t3/auth-md-agent-discovery
Oct 21, 2026
Merged

riderx merged 2 commits into
mainfrom
t3/auth-md-agent-discovery

Conversation

@riderx

@riderx riderx commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Summary

Agent-readiness discovery surfaces on capgo.app (isitagentready checks), each describing something that actually exists:

  • /auth.md: how agents get credentials: OAuth 2.1 + PKCE for the hosted MCP server (api.capgo.app/mcp), API keys, and CLI login. Also lists the headers to send. Linked from llms.txt guidance and the markdown 404.
  • Web Bot Auth: /.well-known/http-message-signatures-directory serves an Ed25519 JWKS (application/http-message-signatures-directory+json). The response is signed (tag="http-message-signatures-directory") when the WEB_BOT_AUTH_PRIVATE_JWK secret is set. The worker's outbound fetches (GitHub sponsors, status.capgo.app) are signed via Cloudflare's web-bot-auth library. Without the secret, behaviour is unchanged (unsigned).
  • A2A Agent Card: /.well-known/agent-card.json (+ legacy /.well-known/agent.json) describes the hosted MCP server. The interface uses a custom binding URI (A2A spec §5.8) for MCP Streamable HTTP, so A2A clients don't send JSON-RPC calls to an endpoint that can't answer them. Skills come from the same tool groups as mcp.json. Security schemes are OAuth (PKCE) and a Bearer API key.
  • RFC 9728: /.well-known/oauth-protected-resource with resource: https://capgo.app (must match the origin), authorization_servers: [https://capgo.app], scope capgo.
  • RFC 8414, capgo.app as issuer: /.well-known/oauth-authorization-server serves the hosted MCP authorization server's metadata. The API generates it (feat(mcp): use https://capgo.app as the OAuth issuer capgo.app#3803 sets MCP_OAUTH_ISSUER=https://capgo.app). The response is cached for 1h with a stale fallback, and is only served when issuer === "https://capgo.app"; until then it returns 503. Endpoints stay on api.capgo.app. No jwks_uri: access tokens are opaque API keys, so nothing is signed.

Not implemented on purpose: ACP, AP2, UCP and x402 (no agent checkout or payment flow exists), and DNS-AID (Cloudflare DNS, not in this repo).

Deploy order

Deploy this PR before Cap-go/capgo.app#3803. That PR points MCP clients at https://capgo.app as the issuer, so this route must already be live.

Deploy follow-up

Enable Web Bot Auth signing with the matching private key (kept outside the repo):

cd apps/web && bunx wrangler secret put WEB_BOT_AUTH_PRIVATE_JWK < ~/.config/capgo/web-bot-auth-ed25519.private.jwk

A key that doesn't match the published public key is ignored.

Test plan

  • bun test apps/web/test apps/web/src/worker: 254 pass
  • bun run lint
  • astro check: 0 errors
  • astro build emits dist/auth.md
  • Request signatures verified with web-bot-auth verify(). The directory signature verifies for capgo.app and fails for another authority.
  • OAuth metadata loader tested for the capgo.app issuer and rejects any other issuer
  • After deploy: run the isitagentready scan for capgo.app

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

View guided diff Turn on auto-fix

…very

Add agent discovery surfaces on capgo.app:

- /auth.md: how agents get credentials (OAuth 2.1 for the hosted MCP
  server, API keys, CLI login) and how to use them
- /.well-known/http-message-signatures-directory: Ed25519 JWKS, signed
  when WEB_BOT_AUTH_PRIVATE_JWK is set; worker outbound fetches to GitHub
  and status.capgo.app are signed with Web Bot Auth
- /.well-known/agent-card.json (+ legacy agent.json): A2A Agent Card for
  the hosted MCP server, declared as a custom MCP Streamable HTTP binding
- /.well-known/oauth-protected-resource: RFC 9728 metadata for capgo.app
  pointing at the api.capgo.app authorization server
- /.well-known/oauth-authorization-server: cached mirror of the
  api.capgo.app RFC 8414 metadata, plus an empty /.well-known/jwks.json
  since access tokens are opaque API keys

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 25 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: bd085b36-f4ef-4e57-8d0e-886be1bdbcd6
📥 Commits

Reviewing files that changed from the base of the PR and between a3ab5ce and 75f4f4c.

⛔ Files ignored due to path filters: 1
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing: 11
  • apps/shared/agentDiscovery.ts
  • apps/web/package.json
  • apps/web/src/pages/auth.md.ts
  • apps/web/src/worker/index.ts
  • apps/web/src/worker/mcp.ts
  • apps/web/src/worker/oauth-discovery.ts
  • apps/web/src/worker/web-bot-auth.ts
  • apps/web/test/agent-discovery.test.js
  • apps/web/test/mcp-server.test.js
  • apps/web/test/oauth-discovery.test.js
  • apps/web/test/web-bot-auth.test.js
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-21T11:38:29.927395Z 75f4f4c New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@socket-security

socket-security Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedhttp-message-sig@​0.3.0100100998780
Addedweb-bot-auth@​0.2.010010010088100

View full report

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b79ac6a527

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/web/src/worker/oauth-discovery.ts Outdated
Comment on lines +25 to +26
if (metadata.issuer !== CAPGO_API_ORIGIN) throw new Error(`Unexpected issuer ${String(metadata.issuer)}`)
return { ...metadata, jwks_uri: metadata.jwks_uri ?? `${CAPGO_ORIGIN}${OAUTH_JWKS_PATH}` }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid publishing authorization metadata for a different issuer

When a client performs OAuth discovery for https://capgo.app, this endpoint returns metadata whose issuer is https://api.capgo.app. RFC 8414 §3.3 requires the returned issuer to match the issuer used to construct the discovery URL, so conforming clients must reject this response even when the upstream fetch succeeds. Checking the upstream issuer does not make the mirrored document valid at the website origin. Keep discovery pointed at the canonical API-origin endpoint rather than exposing this mirror as an authorization-server discovery endpoint.

Useful? React with 👍 / 👎.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 12 files

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread apps/shared/agentDiscovery.ts
Comment thread apps/web/src/worker/web-bot-auth.ts
Comment thread apps/web/src/worker/index.ts
Comment thread apps/web/test/web-bot-auth.test.js
Comment thread apps/web/src/worker/oauth-discovery.ts
capgo.app becomes the RFC 8414 issuer of the hosted MCP authorization
server (endpoints stay on api.capgo.app). The worker serves the metadata
the API generates and only when it names https://capgo.app as issuer.
Protected resource metadata, the A2A card and auth.md point at the
capgo.app issuer. Remove the placeholder /.well-known/jwks.json: access
tokens are opaque API keys, so there are no signing keys to publish.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@riderx
riderx merged commit aad41ea into main Oct 21, 2026
13 checks passed
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.

1 participant