No description
  • Go 91.1%
  • Go Template 5.2%
  • Nix 2.7%
  • Makefile 1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
sa-renovate 800aa49278
All checks were successful
ci-general / code (pull_request) Successful in 1m29s
ci-general / code (push) Successful in 1m22s
chore(deps): pin dependencies
2026-08-17 09:07:09 +00:00
.forgejo/workflows chore(deps): pin dependencies 2026-08-17 09:07:09 +00:00
cmd/oidc-discovery-proxy feat: reload serving TLS certificates 2026-07-20 17:34:35 +02:00
deploy/charts/oidc-discovery-proxy feat: reload serving TLS certificates 2026-07-20 17:34:35 +02:00
proxy feat: reload serving TLS certificates 2026-07-20 17:34:35 +02:00
.envrc init 2026-07-16 18:14:12 +02:00
.gitignore init 2026-07-16 18:14:12 +02:00
.goreleaser.yaml init 2026-07-16 18:14:12 +02:00
Dockerfile.goreleaser init 2026-07-16 18:14:12 +02:00
flake.lock init 2026-07-16 18:14:12 +02:00
flake.nix init 2026-07-16 18:14:12 +02:00
go.mod Update go.mod 2026-08-17 09:04:54 +00:00
Makefile feat: Added helm chart 2026-07-17 14:41:22 +02:00
README.md feat: reload serving TLS certificates 2026-07-20 17:34:35 +02:00
renovate.json Update renovate.json 2026-07-31 16:58:08 +00:00

OIDC discovery proxy

This service adapts authenticated Kubernetes ServiceAccount issuer discovery for anonymous OIDC consumers such as KCP. It periodically reads a projected ServiceAccount token, fetches and validates upstream discovery and JWKS, rewrites only jwks_uri, then atomically publishes both documents.

Endpoints

  • GET/HEAD /.well-known/openid-configuration
  • GET/HEAD /openid/v1/jwks
  • GET/HEAD /healthz: live whenever the HTTP process is running
  • GET/HEAD /readyz: 503 before the first successful full refresh; remains ready with the last-known-good snapshot during later failures

Other methods return 405; other paths return 404. All responses use application/json.

Flags

Flag Default Purpose
-listen-address :8443 Serving address
-upstream-discovery-url Kubernetes in-cluster issuer discovery URL Authenticated discovery source
-upstream-jwks-url unset Optional trusted authenticated JWKS URL override
-expected-issuer https://kubernetes.default.svc.cluster.local Exact required discovery issuer
-public-base-url in-cluster proxy HTTPS URL Base used for rewritten jwks_uri
-token-file default projected SA token Bearer token, reread every refresh
-upstream-ca-file system roots Optional additional PEM CA certificates
-allow-insecure-upstream-http false Permit token-bearing HTTP upstream requests for local tests only
-refresh-interval 5m Refresh period
-request-timeout 10s Per-upstream-request timeout; a full refresh has twice this total budget
-tls-cert-file, -tls-key-file unset Serving TLS pair; both are required together
-tls-reload-interval 1m Polling period for serving certificate rotation

Local development

nix run nixpkgs#go -- test ./...
nix run nixpkgs#go -- run ./cmd/oidc-discovery-proxy \
  -listen-address=:8080 \
  -upstream-discovery-url=http://127.0.0.1:9000/.well-known/openid-configuration \
  -allow-insecure-upstream-http \
  -expected-issuer=https://kubernetes.default.svc.cluster.local \
  -public-base-url=http://127.0.0.1:8080 \
  -token-file=/tmp/token

Inside a Go-enabled development shell, make check verifies module tidiness, formats, vets, race-tests, and builds the service. On a Nix host without Go installed globally, run individual commands as nix run nixpkgs#go -- <command>.

Release

Forgejo Actions validate every branch and pull request with Go tests, GoReleaser snapshot builds, and Trivy scans of both supported container architectures. Tags matching v* create Forgejo releases and publish linux/amd64 and linux/arm64 images to the Forgejo package registry through GoReleaser. Dockerfile.goreleaser is the sole supported image build path.

Security

The proxy exposes only validated public OIDC metadata. Upstream requests always carry the token, redirects are rejected, responses are size-limited, and logs contain neither token nor response body. By default, a discovered jwks_uri must have the exact same origin (scheme, hostname, and effective port) as the configured discovery URL, preventing bearer-token forwarding to another host. JWKS keys must be objects with a non-empty kty.

Some Kubernetes API servers advertise a jwks_uri on a different API origin, such as a host IP and dynamic port. In that case, explicitly set -upstream-jwks-url to the operator-trusted authenticated endpoint, typically https://kubernetes.default.svc/openid/v1/jwks, while retaining -expected-issuer=https://kubernetes.default.svc.cluster.local. The advertised URI must remain syntactically valid, but the proxy fetches only the configured override. An override is an explicit trust boundary and therefore need not share the discovery origin.

Token-bearing upstream traffic requires HTTPS by default. TLS verification cannot be disabled; -upstream-ca-file extends system roots. The explicit -allow-insecure-upstream-http escape hatch is only for local tests. Production serving should supply a certificate/key and restrict the ServiceAccount to discovery access. Each request has -request-timeout; the complete discovery-plus-JWKS refresh is also canceled after twice that duration and on process shutdown.

Kubernetes Secret projection updates are eventually propagated to the mount. The TLS reload interval is therefore a polling interval and practical lower bound, not a strict upper bound on when a new certificate becomes visible.