Repository navigation
v2.7.1
theauth-go v2.7.1
Docs: https://docs.theauth.dev/go . Full list: CHANGELOG.md.
This is a security fix. If you use the authorization server with private_key_jwt client authentication or trusted JWT issuers, upgrade.
go get github.com/glincker/theauth-go/v2@v2.7.1Upgrade notes
- JWKS URLs must use
https. Plainhttpis refused unlessJWTBearerConfig.AllowPrivateJWKSNetworksis set. - JWKS hosts that resolve to loopback, private, link-local, CGNAT or cloud metadata addresses are refused. Local development and tests that serve a JWKS from
localhostneedAllowPrivateJWKSNetworks: true, or an injectedJWKSHTTPClient. - Redirects are not followed. A JWKS URL must serve the document directly.
- Rotated keys are picked up after the cache TTL (
JWKSCacheTTL, default 5 minutes). - CIMD fetch errors now start with
safehttp:instead ofcimd:.errors.Isstill works.
What was wrong
The server fetched a client's jwks_uri or a trusted issuer's JWKSURL with a plain HTTP GET: no address check, no timeout, redirects followed, and a cache that never expired. A client that registered a jwks_uri pointing at an internal address could make the server connect there.
What changed
JWKS fetching now uses a guarded client (shared with CIMD in internal/safehttp). The address check runs at dial time, so DNS rebinding does not get around it. No proxy is used, requests time out after 5 seconds by default, the response must be status 200 and at most 512 KiB, and the cache expires entries after a TTL, holds at most 256 URLs by default, and never stores failed fetches. See PR #213.
New options on JWTBearerConfig
| Option | Default | Purpose |
|---|---|---|
AllowPrivateJWKSNetworks |
false |
Local development only. Permits private addresses and plain http. |
JWKSCacheTTL |
5 minutes | How long a fetched JWKS is reused. |
JWKSCacheMaxEntries |
256 | Maximum number of cached JWKS URLs. |
JWKSFetchTimeout |
5 seconds | Total time allowed for one fetch. |
JWKSHTTPClient |
guarded client | Replaces the default client. It is used as is, so it must give equivalent protection. |
Verify this release
The tarball and the SBOM carry a SLSA build provenance attestation from the release workflow:
gh release download v2.7.1 -R glincker/theauth-go -p 'theauth-go-v2.7.1.tar.gz*'
gh attestation verify theauth-go-v2.7.1.tar.gz --repo glincker/theauth-goEach asset also has a cosign signature (.sig). The signing certificates were not attached to this release, so verify with the attestation above. This is tracked in a fix to the release config.
Install: go get github.com/glincker/theauth-go/v2@v2.7.1
Changelog
Bug fixes
- : fix: guard JWKS fetches against SSRF and expire the JWKS cache (@thegdsks)
- : fix: pin benchstat for Go 1.25, resolve bench base on dispatch and cron; chore: cut 2.7.0 changelog section (@thegdsks)
- : fix: satisfy staticcheck in the JWKS fetcher and its test (@thegdsks)
Other changes
- : Merge origin/main into chore/bench-workflow-and-changelog (@thegdsks)