• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pomerium / pomerium / 24161261011
52%

Build:
DEFAULT BRANCH: main
Ran 08 Apr 2026 10:32PM UTC
Jobs 1
Files 691
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

08 Apr 2026 10:08PM UTC coverage: 45.448% (+0.02%) from 45.432%
24161261011

push

github

web-flow
fix: allow loopback redirect URIs with any port per OAuth 2.1 (#6251)

## Summary

MCP OAuth authorization rejects clients that use loopback redirect URIs
with dynamic ephemeral ports (e.g. Claude Code), returning
`invalid_grant` because redirect URI validation requires an exact string
match including the port.

[OAuth 2.1
§2.3.1](https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-13.html#section-2.3.1)
requires an exception for loopback redirects:

> Authorization servers MUST require clients to register their complete
redirect URI (including the path component). Authorization servers MUST
reject authorization requests that specify a redirect URI that doesn't
exactly match one that was registered, **with an exception for loopback
redirects, where an exact match is required except for the port URI
component.**

[OAuth 2.1 §8.4.2 "Loopback Interface
Redirection"](https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-13.html#section-8.4.2)
further specifies that native apps use loopback redirects with ephemeral
ports, and the authorization server must not require clients to
pre-register a specific port.

The [MCP Authorization spec
(2025-11-25)](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization)
defers to OAuth 2.1 for redirect URI validation rules and explicitly
permits `localhost` redirect URIs.

## Related issues

- [ENG-3857](https://linear.app/pomerium/issue/ENG-3857)

## User Explanation

MCP clients using loopback redirect URIs (e.g.
`http://localhost:<port>/callback`) can now authenticate successfully
regardless of which ephemeral port they bind to.

## Checklist

- [x] reference any related issues
- [x] updated unit tests
- [x] add appropriate label (`enhancement`, `bug`, `breaking`,
`dependencies`, `ci`)
- [ ] ready for review

23 of 26 new or added lines in 1 file covered. (88.46%)

6 existing lines in 3 files now uncovered.

35090 of 77209 relevant lines covered (45.45%)

114.19 hits per line

Uncovered Changes

Lines Coverage ∆ File
3
91.94
-2.8% internal/oauth21/validate_client.go

Coverage Regressions

Lines Coverage ∆ File
3
87.75
-1.47% config/config_source.go
2
79.16
-0.53% pkg/storage/postgres/backend.go
1
82.24
-0.2% pkg/envoy/resource_monitor_linux.go
Jobs
ID Job ID Ran Files Coverage
1 24161261011.1 08 Apr 2026 10:32PM UTC 691
45.45
GitHub Action Run
Source Files on build 24161261011
  • Tree
  • List 691
  • Changed 7
  • Source Changed 1
  • Coverage Changed 7
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #24161261011
  • 44a41ccf on github
  • Prev Build on main (#24160000169)
  • Next Build on main (#24201497741)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc