Changelog
Unreleased
Section titled “Unreleased”[1.9.0] - 2026-10-21
Section titled “[1.9.0] - 2026-10-21”-
Enable the metrics listener and dedicated Service automatically when the Helm ServiceMonitor switch is enabled, with setup guidance and unchanged opt-out defaults.
-
Bump golang.org/x/net from 0.58.0 to 0.60.0 to fix 5 govulncheck findings in the HTTP/2 code that the proxy calls. Also bump golang.org/x/crypto to 0.57.0, x/mod to 0.41.0, x/sync to 0.23.0, x/sys to 0.48.0, x/term to 0.46.0 and x/text to 0.42.0.
-
A documentation website with a product landing page, the guides and references from docs/ and a version banner, published to GitHub Pages from a gated workflow.
-
The Helm chart renders the
helm testconnection hook image fromtest.image.repositoryandtest.image.tag(defaultdocker.io/library/busybox:1.37.0) instead of a barebusyboxliteral, so image mirrors can redirect it. -
Enrol in the OpenSSF Best Practices Badge, with proposed answers in
.bestpractices.json, the badge in the README, explicit bug and vulnerability reporting links, and a release-notes rule that security fixes name their advisory. -
Bump google.golang.org/grpc from 1.83.1 to 1.83.2 (the gRPC server now rejects requests missing both
:authorityandHostheaders), go.opentelemetry.io/otel, otel/sdk, otel/exporters/otlp/otlptrace and otlptracegrpc from 1.44.0 to 1.45.0, and golang.org/x/crypto from 0.55.0 to 0.56.0 to remediate GO-2026-6354 and GO-2026-6355. -
Build against Go 1.26.10, which fixes a crypto/x509 certificate verification vulnerability (CVE-2026-111943, golang/go#82345). The proxy uses crypto/x509 to verify client TLS certificates and the TLS certificates of OIDC issuers.
-
Document that an issuer entry in
--authentication-configmay list severalaudienceswithaudienceMatchPolicy: MatchAny, and cover it in the unit and end-to-end suites: a token carrying any listed audience is accepted, one carrying none is rejected, and an audience listed for one issuer does not admit tokens from another.
[1.8.1] - 2026-09-13
Section titled “[1.8.1] - 2026-09-13”- Load the Helm chart’s structured OIDC authentication configuration from an existing Secret with a configurable key.
- Configure single-issuer OIDC in the Helm chart through environment variables sourced from an existing Secret, with configurable keys for required and optional settings.
[1.8.0] - 2026-09-08
Section titled “[1.8.0] - 2026-09-08”- The Helm chart can enable the metrics endpoint (
metrics.enabled), rendering the flag, a named container port and a dedicated ClusterIP Service<release>-metricsthat is never part of the main Service, plus an optional Prometheus Operator ServiceMonitor or PodMonitor, an empty PrometheusRule and a NetworkPolicy that admits only the listed peers to the metrics port while keeping the proxy and readiness ports open. - Bump github.com/prometheus/client_golang from 1.24.0 (indirect) to a direct dependency at 1.24.1, which fixes a promhttp panic on requests carrying a nil URL, ahead of the proxy exposing a Prometheus metrics endpoint.
- Three Grafana dashboards (overview, security and identity, capacity and dependencies) shipped by the chart as a sidecar-loaded ConfigMap when
metrics.dashboards.enabledis set, a data-flow diagram of where the metrics attach in docs/metrics.md, and a reproducible kind demo (make metrics_demo_up) that installs the chart with Prometheus and Grafana, generates every kind of traffic, verifies every panel has data and captures the documented screenshots. - The proxy now refuses to start when two configured issuers share a host (for example
https://idp.example.com/realms/aandhttps://idp.example.com/realms/b). Issuers are identified by host in every log record and metric series, so such a configuration could not be reported unambiguously. Give each issuer its own host. - A 1xx informational response forwarded from the API server (for example 103 Early Hints) is no longer recorded as the request’s final http_status in the request.response.completed record; only the final status is.
- Metrics for authentication attempts, access decisions by reason, TokenReview and SubjectAccessReview API calls and latency, review cache hits and misses, per-issuer initialization, readiness and observable audit backend failures, documented in docs/metrics.md as a versioned contract generated from the code and verified in CI.
- An opt-in Prometheus metrics endpoint.
--metrics-bind-address=host:portservesGET /metricsover plain HTTP on a dedicated listener with request counters, a latency histogram that excludes long-running requests, in-flight and open-stream gauges and build information. Off by default; every label value comes from a closed set, so no identity, path or client-chosen value ever becomes a series.
[1.7.1] - 2026-09-05
Section titled “[1.7.1] - 2026-09-05”- The Helm chart’s ClusterRole now lets the proxy’s ServiceAccount create
SubjectAccessReviews. The proxy authorizes every inboundImpersonate-*header value with one before forwarding, so on a chart install everykubectl --asrequest failed with HTTP 500 andreason=internal_error(authz.sar.failedcarriedcannot create resource "subjectaccessreviews"). The end-to-end suite grants this in its own fixture, which is why it never surfaced there. Plain token requests were unaffected. - The Helm chart’s ClusterRole now grants
impersonateonuserextras/<key>for everyclaimMappings.extra[].keydeclared inauthenticationConfig.content, plus any keys listed in the newrbac.userExtrasvalue. Previously an issuer that mapped extra claims had every request rejected with 403, because the API server authorizes eachImpersonate-Extra-<key>header separately and the chart only granted a fixed set of keys. The chart’s development baselineappVersionis 1.7.0. - Every namespaced object the Helm chart renders now carries
metadata.namespaceset to the release namespace.helm installwas unaffected, buthelm template ... | kubectl apply -fplaced the Deployment, Service, ServiceAccount, Secrets and Ingress in the caller’s current namespace while the ClusterRoleBinding still named the rendered one, so a proxy applied that way ran without its RBAC grants. Manifests rendered for GitOps now land in the namespace they were rendered for.
[1.7.0] - 2026-09-05
Section titled “[1.7.0] - 2026-09-05”- Security denials now appear at the default verbosity as
AuFailrecords with areason; the readiness transition is INFO; “issuers pending” is logged on change only; Kubernetes library output is JSON undercomponent=k8s. - Operational log messages changed value. The access record’s
msgwasproxied requestorrejected requestand is nowaccess decisionfor both, with the outcome in the frozeneventfield (AuSuccess/AuFail); other records carry newmsgtext as well. Queries and alerts must key onevent_type(andeventfor the access record), not onmsg, which is descriptive and not part of the contract. - The access log no longer emits the original user’s full extra-claims map under
outbound_extra, and configured impersonation header values are no longer logged at any verbosity. - One JSON log stream with a per-request
request_id(also sent upstream asAudit-ID), a closedevent_typeregistry documented in docs/logging.md, and--logging-format.
[1.6.1] - 2026-09-04
Section titled “[1.6.1] - 2026-09-04”- Helm chart now deploys the image matching its appVersion by default. Charts 1.2.0 through 1.6.0 shipped with a hardcoded
image.tagof 1.1.0, so installs without an explicitimage.tagoverride ran the 1.1.0 binary; the release pipeline now refuses to publish a chart whose default image tag differs from the release version.
[1.6.0] - 2026-09-01
Section titled “[1.6.0] - 2026-09-01”- Bump github.com/google/cel-go to v0.30.0 and go.etcd.io/etcd/{api,client/pkg,client}/v3 to v3.7.1 to remediate GO-2026-6094 and GO-2026-6107.
- Impersonation requests are now capped at a configurable number of Impersonate-* header values (—max-impersonation-header-values, default 64). Requests exceeding the cap are rejected with HTTP 431 before any SubjectAccessReview is sent, bounding the per-request authorization load a client can generate.
- Impersonation SubjectAccessReview decisions are now served from a bounded in-memory cache with separately configurable TTLs (—subject-access-review-cache-allow-ttl and —subject-access-review-cache-deny-ttl, default 10s, 0 disables). Revoking or granting an RBAC impersonation permission can take up to the corresponding TTL to be enforced through the proxy.
- Token passthrough now caches TokenReview results in a bounded in-memory cache with separately configurable TTLs (—token-passthrough-cache-success-ttl and —token-passthrough-cache-failure-ttl, default 10s, 0 disables). A revoked token can continue to pass for up to the success TTL and a newly valid token can be rejected for up to the failure TTL.
[1.5.0] - 2026-08-28
Section titled “[1.5.0] - 2026-08-28”- Audit event sourceIPs now follow the trusted-proxy contract — forwarded headers from untrusted peers are stripped before auditing and before the request is forwarded upstream, so clients can no longer spoof the audit trail via X-Forwarded-For. Operators with a load balancer in front of the proxy must set —trusted-proxies to resolve the real client IP.
- Unauthenticated (401) requests now produce audit events — the unauthorized audit chain initialises the audit context, so failed authentication attempts are recorded with a ResponseStarted event instead of leaving no trace in the audit log.
- Update k8s.io modules to v0.37.0, sigs.k8s.io/kind to v0.33.0, and test dependencies; refresh the distroless base image digest and move test tool images to alpine 3.24; bump all pinned GitHub Actions to current releases.
- Pull request e2e runs now exercise the full supported Kubernetes window (currently 1.37.0, 1.36.4, 1.35.8) instead of only the newest minor; the release path stays newest-only since the same code already passed the full window on its pull request.
- Test and CI tooling now targets Kubernetes 1.37 — the e2e suite boots kindest/node v1.37.0 by default, the kind CLI in the e2e workflows moves to v0.33.0 (kubeadm v1beta4 support, required since 1.37 dropped v1beta3), and the Makefile kubectl download fallback moves to v1.37.0.
- UID impersonation works end to end — an authorized Impersonate-Uid header is forwarded to the API server, the impersonation check reviews uids in the authentication.k8s.io group, and the chart grants the proxy impersonate on uids and on the originaluser.jetstack.io-uid extra. Deployments that map a uid claim now emit Impersonate-Uid and need the new RBAC.
- New —token-passthrough-request-timeout flag bounds each TokenReview call the proxy makes when validating a passthrough token (default 10s, previously hardcoded).
[1.4.0] - 2026-08-20
Section titled “[1.4.0] - 2026-08-20”- Replace —allow-reserved-identity-claims with —allow-reserved-groups, which permits named system:-prefixed groups instead of disabling the reserved-identity guard wholesale. Reserved usernames can no longer be permitted at all. The flag it replaces was added after v1.2.0 and has not appeared in a release.
[1.3.0] - 2026-08-19
Section titled “[1.3.0] - 2026-08-19”- Update go.opentelemetry.io/otel to v1.44.0 and golang.org/x/mod to v0.40.0, clearing three advisories reported against the dependency tree.
- Harden CI — scope the Prepare Release and GitHub Actions OIDC e2e workflow tokens to the jobs that need them, and stop the e2e fake API server from logging request header values or echoing a caller-controlled body as sniffable content.
- Build against Go 1.26.6, which resolves six reachable Go standard library advisories in crypto/tls, net/http, net/url, html/template, and encoding/asn1.
- Log OIDC token validation failures at
-v=2with the resolved remote address, instead of-v=5. An error from the bearer-token authenticator always means a token was present and failed validation, so it was previously invisible at any verbosity operators run. Request routing is unchanged. - The readiness endpoint now reports not-ready until the proxy is actually serving, instead of reporting ready as soon as an OIDC issuer initialized. Previously the readiness server started before the proxy’s handler chain did, so a pod could join its Service while requests to the proxy port could only queue.
- Audit streaming requests as long-running — exec, attach, portforward, log and proxy are now recorded when the response starts instead of only when the stream ends, so a long session is no longer missing from the audit log while it runs, or entirely if the proxy dies first. These requests now emit a ResponseStarted event as well as ResponseComplete, so audit volume for exec, attach and portforward increases.
- Refuse authenticated identities carrying the Kubernetes-reserved
system:prefix from token claims, so an OIDC issuer can no longer mintsystem:mastersor a service-account username through the proxy’s blanket impersonation rights. The check runs before the SubjectAccessReview that authorizes inbound impersonation, and the 403 is audited against the identity that was presented.system:authenticatedremains permitted as a group because the proxy adds it to every request itself. Name specific reserved groups in--allow-reserved-groupsif a directory legitimately holds one. - Audit requests to the core API group (/api/…) are now classified correctly. The audit server config named no legacy API prefix, so every core group request — which is where pods and services live, and with them exec, attach, portforward, log and proxy — was recorded as a non-resource request, with the lowercased HTTP method as its verb and no objectRef, and neither the long-running check nor a watch could ever be recognised. Audit events for these requests now carry the Kubernetes verb (list, create, watch and so on) and an objectRef naming the resource, namespace, name and subresource. If you parse audit logs or write audit policy rules matching on verb or resource, expect the corrected values.
enhancements:
- Multi-issuer OIDC authentication via —authentication-config (AuthenticationConfiguration v1/v1beta1), based on #85 with strict versioned config loading, whole-document validation, a shared CEL compiler and configurable readiness (—readiness-require-all-issuers)
1.0.12
Section titled “1.0.12”tasks:
- 1.0.12 build #83
1.0.11
Section titled “1.0.11”bugs:
- Critical Vulnerability CVE-2025-68121 #78
1.0.10
Section titled “1.0.10”tasks:
- 1.0.10 build #74
tasks:
- 1.0.9 #64
enhancements:
- Add flags to be able to configure kubernetes client throttling #65
tasks:
- 1.0.8 #61
enhancements:
- change oidc config to line up with new kube authenticator #55
tasks:
- 1.0.7 Release #54
bugs:
tasks:
- 1.0.6 build #41
tasks:
- 1.0.5 build #34
tasks:
- 1.0.4 build #29
enhancements:
- 1.0.3 release #26
bugs:
- CVE-2022-1996 #20
enhancements:
- 1.0.1 #14
bugs:
enhancements:
- 1.0.0 Release #10
- Access logging to standard out #2
- create github action to automate builds #8
- Switch from alpine —> ubuntu 20.04 #9
- Support
kubectl --as#3 - Upgrade KinD #1
bugs:
- update dependencies #5