* update to release version v7.15.1
* doc: release notes for v7.15.1
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* Propagate errors during route building
This fixes cases such as invalid paths being silently discarded after
creation by throwing a visible error in such cases.
Due to the way gorilla/mux's fluent API is designed, it is necessary to
manually call `.GetError()` to check for errors while building routes.
Signed-off-by: Simon Engmann <simon.engmann@sovity.de>
* Add test for route building error propagation
Signed-off-by: Simon Engmann <simon.engmann@sovity.de>
* Add route building error propagation to changelog
Signed-off-by: Simon Engmann <simon.engmann@sovity.de>
---------
Signed-off-by: Simon Engmann <simon.engmann@sovity.de>
Co-authored-by: Simon Engmann <simon.engmann@sovity.de>
* Improve logging for session refresh token status
Signed-off-by: Yosri Barhoumi <med.yosri.brh@gmail.com>
* doc: add changelog entry for #3327
Signed-off-by: Jan Larwig <jan@larwig.com>
* test: fix existing test cases for new behaviour
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Yosri Barhoumi <med.yosri.brh@gmail.com>
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* fix: handle Unix socket RemoteAddr in IP resolution
When oauth2-proxy listens on a Unix socket, Go sets RemoteAddr to "@"
instead of the usual "host:port" format. This caused net.SplitHostPort
to fail on every request, flooding logs with errors:
Error obtaining real IP for trusted IP list: unable to get ip and
port from http.RemoteAddr (@)
Fix by handling the "@" RemoteAddr at the source in getRemoteIP,
returning nil without error since Unix sockets have no meaningful
client IP. Also simplify the isTrustedIP guard and add a nil check
in GetClientString to prevent calling String() on nil net.IP.
Fixes#3373
Signed-off-by: h1net <ben@freshdevs.com>
* docs: add changelog entry and Unix socket trusted IPs documentation
Add changelog entry for #3374. Document that trusted IPs cannot match
against RemoteAddr for Unix socket listeners since Go sets it to "@",
and that IP-based trust still works via X-Forwarded-For with reverse-proxy.
Signed-off-by: Ben Newbery <ben.newbery@gmail.com>
Signed-off-by: h1net <ben@freshdevs.com>
* doc: fix changelog entry for #3374
Signed-off-by: Jan Larwig <jan@larwig.com>
* doc: add trusted ip a section to versioned docs as well
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: h1net <ben@freshdevs.com>
Signed-off-by: Ben Newbery <ben.newbery@gmail.com>
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* add new docs version 7.15.x
* update to release version v7.15.0
* doc: changelog for v7.15.0 and extended docs for additional claims
* ci: fix trivy failure for release PR
---------
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
fix: linter issues and set default unix socket permissions to 0660
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Tristan <tristan@mangadex.org>
* the attribute version is obsolete, it will be ignored, please remove it to avoid potential confusion
Signed-off-by: Joost <439100+jvnoije@users.noreply.github.com>
* Add cookie-csrf-samesite option
Most of the code is copied form pull request #1947
Signed-off-by: Joost <439100+jvnoije@users.noreply.github.com>
* Update CHANGELOG.md
Signed-off-by: Joost <439100+jvnoije@users.noreply.github.com>
* Removed release information (review comment)
Signed-off-by: Joost <439100+jvnoije@users.noreply.github.com>
* All cookie variables in a struct
Signed-off-by: Joost <439100+jvnoije@users.noreply.github.com>
* doc: add changelog entry for #3347
Signed-off-by: Jan Larwig <jan@larwig.com>
* revert: unnecessary removal of docker compose version
Signed-off-by: Jan Larwig <jan@larwig.com>
* doc: sort csrf flags
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Joost <439100+jvnoije@users.noreply.github.com>
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* feat: add --config-test flag for validating configuration without starting the proxy
Signed-off-by: MayorFaj <mayorfaj@gmail.com>
* doc: fix alpha config and add changelog entry for #3338
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: MayorFaj <mayorfaj@gmail.com>
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* fix: filter empty strings from allowed groups
When parsing allowed groups from configuration (e.g., via environment
variable OAUTH2_PROXY_ALLOWED_GROUPS), viper may include empty
strings in the parsed slice when trailing commas are present
(e.g., "group2," becomes ["group2", ""]).
The setAllowedGroups function now filters out empty strings before
adding them to the AllowedGroups map, ensuring that only valid group
names are checked during authorization.
Fixes#3123
Signed-off-by: Br1an67 <932039080@qq.com>
* refactor: minor change
Signed-off-by: Jan Larwig <jan@larwig.com>
* doc: add changelog entry for 3365
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Br1an67 <932039080@qq.com>
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* feat: add support for specifying allowed OIDC JWT signing algorithms (#2753)
TODO:
- [X] update docs
- [X] add support in yaml (modern) config
- [X] add more test(s)?
Add (legacy for now) configuration flag "oidc-enabled-signing-alg" (cfg:
oidc_enabled_signing_algs) that allows setting what signing algorithms
are specified by provider in JWT header ("alg" header claim).
In particular useful when skip_oidc_discovery = true, as verifier
defaults to only accept "RS256" in alg field in such circumstances.
Signed-off-by: Jan Larwig <jan@larwig.com>
* doc: update changelog and alpha config
Signed-off-by: Jan Larwig <jan@larwig.com>
* feat: add signing algorithm intersection handling with oidc discovery and additional tests
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* feat: possibility to inject id_token in redirect url during sign out
Signed-off-by: Alban Fonrouge <alban.fonrouge@visma.com>
* doc: changelog for #3278
Signed-off-by: Jan Larwig <jan@larwig.com>
* test: fix assertion for TestIdTokenPlaceholderInSignOut
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Alban Fonrouge <alban.fonrouge@visma.com>
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* feat: support additional claims
Signed-off-by: afsu <suaf2020@163.com>
Signed-off-by: af su <saf@zjuici.com>
* docs: clarify that AdditionalClaims may come from id_token or userinfo endpoint
Signed-off-by: afsu <suaf2020@163.com>
Signed-off-by: af su <saf@zjuici.com>
* feat: include AdditionalClaims in /oauth2/userinfo response (#834)
Signed-off-by: afsu <suaf2020@163.com>
Signed-off-by: af su <saf@zjuici.com>
* refactor: extract coerceClaim logic into util
Signed-off-by: afsu <suaf2020@163.com>
Signed-off-by: af su <saf@zjuici.com>
* doc: add changelog entry for #2685
Signed-off-by: Jan Larwig <jan@larwig.com>
* refactor: added more verbose comments to some struct fields and minor code cleanup
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: afsu <suaf2020@163.com>
Signed-off-by: af su <saf@zjuici.com>
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: af su <saf@zjuici.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* Ensure Windows binary has .exe extension
Signed-off-by: Jan Larwig <jan@larwig.com>
* doc: add changelog for #3332
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* update to release version v7.14.2
* doc: changelog entry for v7.14.2
Signed-off-by: Jan Larwig <jan@larwig.com>
* doc: fix nginx example docker-compose
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* docs(nginx): Clarify auth_request redirect pattern with named location
Update the nginx integration documentation to recommend using a named location
(@oauth2_signin) for the error_page directive instead of the previous
'error_page 401 =403' approach.
The named location pattern ensures the browser receives a proper 302 redirect,
which is required for --skip-provider-button=true to work correctly.
The previous pattern (error_page 401 =403 /oauth2/sign_in) returned a 403
status with a Location header. Browsers do not auto-follow redirects on 403
responses, causing users to see a 'Found.' link instead of being automatically
redirected to the IdP.
Changes:
- Updated main nginx example to use @oauth2_signin named location
- Added 'Understanding the error_page redirect pattern' section
- Added warning about the limitations of 'error_page 401 =403'
- Updated local test environment (contrib/local-environment/nginx.conf)
Refs: #334
Signed-off-by: Stefan Markmann <stefan@markmann.net>
* docs: clarify browser vs API routes for nginx auth_request redirects
Add new "Browser vs API Routes" section explaining:
- Use 302 redirect to /oauth2/sign_in only for browser-facing routes
- Use 401/403 without redirect for API/machine clients
This ensures:
- Browsers get a redirect and smooth login flow
- API clients fail fast with appropriate HTTP status codes
- /oauth2/auth remains a pure boolean oracle (2xx/401)
Signed-off-by: Stefan Markmann <stefan@markmann.net>
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Stefan Markmann <stefan@markmann.net>
Signed-off-by: Jan Larwig <jan@larwig.com>
This reverts commit 9c61c49ec2.
The original fix broke nginx deployments using `auth_request`. When `/oauth2/auth` returns 302,
nginx's `auth_request` module treats this as an internal error:
[error] auth request unexpected status: 302 while sending to client
nginx then returns **500 Internal Server Error** to the browser.
> If the subrequest returns a 2xx response code, the access is allowed. If it returns 401 or 403,
> the access is denied with the corresponding error code. Any other response code returned by the
> subrequest is considered an error.
https://nginx.org/en/docs/http/ngx_http_auth_request_module.html
The nginx `auth_request` module has strict semantics (non-negotiable):
| Subrequest status | nginx behavior |
|---|---|
| 2xx | Allow request |
| 401 / 403 | Deny → trigger `error_page` |
| **Any other status** | **Internal error → 500** |
The `/oauth2/auth` endpoint is used as a **policy oracle** (yes/no decision),
not as a browser-facing endpoint. It cannot return redirects.
Any nginx deployment with:
- `skip-provider-button=true`
- Using `auth_request` directive
Will receive 500 errors instead of the expected authentication flow.
The correct fix for #334 is a **documentation update**, not a code change:
```nginx
error_page 401 = @oauth2_signin;
location @oauth2_signin {
return 302 /oauth2/sign_in?rd=$scheme://$host$request_uri;
}
```
This keeps `/oauth2/auth` as a pure 401/2xx oracle and lets nginx perform the proper 302 redirect to the browser.
- Original Issue: #334
- Regression introduced in PR: #3309
Signed-off-by: Stefan Markmann <stefan@markmann.net>
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* fix: Return 302 redirect from AuthOnly when skip-provider-button is true
When SkipProviderButton is enabled and a user needs to login, the AuthOnly
endpoint now returns a 302 redirect directly to the OAuth provider instead
of returning 401.
This fixes an issue with nginx auth_request architecture where 401 triggers
error_page handling, which can break redirect flows because nginx overrides
the status code (e.g., to 403), and browsers don't follow Location headers
for non-3xx responses.
Fixes: #334
Signed-off-by: Stefan Markmann <stefan@markmann.net>
* update docs and changelog
Signed-off-by: Stefan Markmann <stefan@markmann.net>
* test: Add specific OAuth redirect assertions per code review feedback
Improve TestAuthOnlyEndpointRedirectWithSkipProviderButton to verify
that the Location header actually redirects to the OAuth provider's
authorize endpoint with required parameters (client_id, redirect_uri,
state), not just that a Location header exists.
Signed-off-by: Stefan Markmann <stefan@markmann.net>
* refactor: Flatten AuthOnly error handling structure
Move the SkipProviderButton check outside of the nested err != nil block
using an if-else structure. This makes the special case more visible and
reduces nesting depth without changing behavior.
Signed-off-by: Stefan Markmann <stefan@markmann.net>
* doc: backport to v7.14.x
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Stefan Markmann <stefan@markmann.net>
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* Fix WebSocket proxy to respect PassHostHeader setting
When PassHostHeader is set to false, the regular HTTP proxy correctly
sets the Host header to the upstream backend URL. However, the WebSocket
proxy was not respecting this setting, causing WebSocket connections to
fail when backend services validate the Host header.
This commit:
- Adds passHostHeader parameter to newWebSocketReverseProxy()
- Applies setProxyUpstreamHostHeader() when PassHostHeader=false
- Ensures consistent behavior between HTTP and WebSocket proxies
Fixes#3288
Signed-off-by: Pascal Schmiel <pascal.schmiel@gmail.com>
* chore(): add tests, update changelog
Signed-off-by: Pascal Schmiel <pascal.schmiel@gmail.com>
---------
Signed-off-by: Pascal Schmiel <pascal.schmiel@gmail.com>
* Fix session refresh handling in OIDC provider
- `s.Refreshed` was always `false` as the session object was not updated
- `ValidateURL` is, by default, not configured for OIDC providers. Access token validation now only happens when a validation endpoint is available.
Signed-off-by: Michael Gysel <michael.gysel@unblu.com>
* Update changelog
Signed-off-by: Michael Gysel <michael.gysel@unblu.com>
---------
Signed-off-by: Michael Gysel <michael.gysel@unblu.com>
* partly address #2120 and more aggressively truncate access_token
- leaking half of the access token to the logs seems problematic from
a security point of view
- also noisier than necessary logging
- fixed by truncating to at most first 5 chars (e.g. `ya29.`)
Signed-off-by: Martin Nowak <code@dawg.eu>
* feat: more aggressively truncate logged access_token; add unit test and changelog
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Martin Nowak <code@dawg.eu>
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* fix: NewRemoteKeySet is not using DefaultHTTPClient
Signed-off-by: Jan Larwig <jan@larwig.com>
* doc: add changelog entry
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* add new docs version 7.13.x
* update to release version v7.13.0
* doc: add release notes v7.13.0
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* Add check for constraints to the proxy endpoint
* Add tests for allowed_groups query string
* Add this feature to the changelog
* Apply suggestions from code review
Co-authored-by: Jan Larwig <jan@larwig.com>
* Use explicit key names in TestProxyAllowedGroups
* Document the query parameters on proxy endpoint
* Comment was copied from the AuthOnly handler but on closer inspection is not relevant here
replacing comment with one more relevant
---------
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
The package under pkg/clock is github.com/benbjohnson/clock, which is
archived. It's also way more complex than is what is actually needed
here, so we can entirely remove the dependency and remove the helper
package.
Fixes#2840.
Signed-off-by: David Symonds <dsymonds@gmail.com>
* fix: use GetSecret() in ticket.go makeCookie
The makeCookie method in ticket.go was using t.options.Secret directly, which
meant cookie-secret-file was not being respected. Updated to use GetSecret()
which handles both cookie-secret and cookie-secret-file properly.
Also added test coverage for cookie-secret-file functionality.
Fixes#3224
Signed-off-by: stagswtf <142280349+stagswtf@users.noreply.github.com>
* docs: update CHANGELOG.md for cookie-secret-file fix
Signed-off-by: stagswtf <142280349+stagswtf@users.noreply.github.com>
* correct PR link and undo file formatting
Signed-off-by: stagswtf <142280349+stagswtf@users.noreply.github.com>
* fix: error wrapping
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: stagswtf <142280349+stagswtf@users.noreply.github.com>
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>
* bugfix: Gitaa team membership
Gitea doesn't properly fill in all the fields like GitHub,
so implement a series of fallbacks.
Signed-off-by: magic_rb <magic_rb@redalder.org>
* add changelog, documentation and fix groups list
Signed-off-by: Jan Larwig <jan@larwig.com>
---------
Signed-off-by: magic_rb <magic_rb@redalder.org>
Signed-off-by: Jan Larwig <jan@larwig.com>
Co-authored-by: Jan Larwig <jan@larwig.com>