Skip to content

docs(auth): record the OAuth auto-approve trust model + J1 residual#119

Merged
vinsonconsulting merged 1 commit into
mainfrom
docs/j1-auto-approve-trust-model
Jun 29, 2026
Merged

docs(auth): record the OAuth auto-approve trust model + J1 residual#119
vinsonconsulting merged 1 commit into
mainfrom
docs/j1-auto-approve-trust-model

Conversation

@vinsonconsulting

Copy link
Copy Markdown
Owner

Final review item — J1 (documentation only). No behavior, schema, or test change.

Release-review J1 flagged that auto-approve fires on a trusted redirect_uri alone (no client_id requirement), and open RFC 7591 registration lets any client self-register the allowlisted callback to skip consent. The adversarial-verify pass confirmed this is NOT exploitable: matchesAllowlist is exact-match and the code is 302'd only to the allowlisted URI (the real first party), the code is bound to the initiating client at /oauth/token, and the grant carries the single-tenant limner-dogfood identity with the pinned ['mcp'] scope.

The "obvious fix" — also requiring a trusted client_id — is intentionally not applied: the live agent's client_id rotates, so an AND with isTrustedClient would break agent auto-approve (violating the "live agent untouched" guardrail). This PR documents the deliberate trust decision, the non-exploitable residual, and the condition under which to revisit it (a real per-user identity replacing limner-dogfood) — at the auto-approve site (consent.ts) so a future reader doesn't "harden" it into an agent-breaking change.

Typecheck + lint clean; 244 mcp tests unchanged.

🤖 Generated with Claude Code

Release-review J1 flagged that auto-approve fires on a trusted redirect_uri
alone (no client_id requirement), and open RFC 7591 registration lets any client
self-register the allowlisted callback to skip consent. The adversarial-verify
pass confirmed this is NOT exploitable: matchesAllowlist is exact-match and the
code is 302'd only to the allowlisted URI (the real first party), the code is
bound to the initiating client at /oauth/token, and the grant carries the
single-tenant 'limner-dogfood' identity with the pinned ['mcp'] scope.

The "obvious fix" — also requiring a trusted client_id — is intentionally NOT
applied: the live agent's client_id ROTATES, so an AND with isTrustedClient
would break agent auto-approve. Documented the deliberate trust decision, the
non-exploitable residual, and the condition under which to revisit it (a real
per-user identity replacing 'limner-dogfood'), at the auto-approve site so a
future reader doesn't "harden" it into an agent-breaking change.

Documentation only — no behavior, schema, or test change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Jim Vinson <jim@vinson.org>
@vinsonconsulting vinsonconsulting merged commit 365644d into main Jun 29, 2026
2 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