feat(oauth): enforce HTTPS-or-loopback redirect URIs via STRICT_REDIRECT_URIS#192
Merged
Conversation
…ECT_URIS - Add opt-in STRICT_REDIRECT_URIS flag, default false, that rejects plain-http redirect URIs to non-loopback hosts per OAuth 2.1 and the MCP authorization spec - Reject http schemes at client create and update unless the host is loopback, leaving https and pre-existing clients untouched - Add an IsLoopbackHost helper recognizing localhost, 127.0.0.0/8, and ::1 - Wire the flag into ClientService through a WithStrictRedirectURIs functional option so existing constructor call sites stay unchanged - Document the flag in the configuration reference and MCP deployment checklist Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds an opt-in STRICT_REDIRECT_URIS flag to enforce OAuth 2.1 / MCP redirect-URI constraints (HTTPS-only except loopback over HTTP) during OAuth client create/update flows.
Changes:
- Introduces loopback-host detection (
IsLoopbackHost) and strict redirect URI validation invalidateRedirectURIs. - Plumbs
STRICT_REDIRECT_URISfrom config intoClientServicevia a new constructor option. - Adds unit/integration tests and documents the new configuration behavior.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| internal/util/url.go | Adds IsLoopbackHost helper used by strict redirect validation. |
| internal/util/url_test.go | Adds unit tests for loopback host detection. |
| internal/services/client.go | Extends redirect validation with strict-mode enforcement; adds service option wiring. |
| internal/services/client_user.go | Updates user client update path to pass strict-mode flag into validation. |
| internal/services/client_test.go | Expands redirect URI validation tests; adds strict-mode create-client integration test. |
| internal/config/config.go | Adds StrictRedirectURIs config value from STRICT_REDIRECT_URIS env var. |
| internal/bootstrap/services.go | Wires cfg.StrictRedirectURIs into ClientService construction. |
| docs/MCP.md | Documents recommended MCP deployment setting for STRICT_REDIRECT_URIS. |
| docs/CONFIGURATION.md | Documents the new STRICT_REDIRECT_URIS configuration key. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
- Render the loopback host table subtest names with %q so the empty-host case no longer produces a blank name Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in
STRICT_REDIRECT_URISflag (defaultfalse) that enforces the OAuth 2.1 §1.5 / MCP authorization-spec requirement that every redirect URI be either loopback or HTTPS. When enabled, AuthGate rejects a redirect URI that uses plainhttp://to a non-loopback host at client create/update time. Closes MCP gap #2 (redirect URIs were previously accepted over plain HTTP to any host).AI Authorship
Change classification
validateRedirectURIsis the single choke point for all OAuth client registration paths (admin, user self-service, and Dynamic Client Registration). A bug here weakens an auth-boundary security control, so it warrants close review.Plan reference
Goal: operators deploying AuthGate as an MCP authorization server can set
STRICT_REDIRECT_URIS=trueto reject plain-http redirect URIs to non-loopback hosts, at client create/update. With the flag off (default), behavior is unchanged — non-breaking for existing deployments.Two design decisions, both deliberately chosen for backward compatibility:
Verification
TestIsLoopbackHost(loopback detection: localhost, 127.0.0.0/8, ::1, negatives)TestCreateClient_StrictRedirectURIsexercises the flag throughClientService.CreateClienthttps://app.example.com/cb→ acceptedhttp://app.example.com/cb→ErrInvalidRedirectURIhttp://127.0.0.1.../localhost→ accepted; strict off +http://app.example.com/cb→ still acceptedmake generate,go build ./...,make fmt,make lint(0 issues), and the services/util/bootstrap/handlers test packages all pass.Verifiability check
ErrInvalidRedirectURI→ HTTP 400 at the handlerSecurity check
Risk & rollback
STRICT_REDIRECT_URIS=false.Reviewer guide
internal/services/client.go— the new strict guard invalidateRedirectURIsand theWithStrictRedirectURIsoption /NewClientServiceopts wiringinternal/util/url.go—IsLoopbackHost(correctness of loopback detection is the security crux)internal/config/config.go,internal/bootstrap/services.go— straightforward flag plumbing*_test.go,docs/*— tests and documentation