Repository navigation
v0.7.0
[0.7.0] - 2026-10-20
HAPTIC 0.7 hardens two trust boundaries: raw HAProxy configuration annotations,
which let an Ingress writer change the configuration for every host, need an
explicit opt-in, and every HTTP frontend replaces client-sent forwarded headers,
so clients can't forge their address. Chart upgrades roll the controller to the
new image before applying new templates.
Before upgrading: check your Ingresses for raw configuration annotations and
haproxy-ingress.github.io/forwardfor, and list any L7 proxies in front of
HAPTIC. Read the upgrade notes.
Added
watchedResources.<name>.namespacesrestricts watches and template lookups to listed namespaces;namespacesSettingidentifies the setting in rejection messages.- Metrics:
haptic_config_validated{status,reason}: each replica'sValidatedcondition, one series per state, so an alert can match a configuration stuck atUnknownorFalse.haptic_config_validation_total{result}:valid,invalid, andinconclusiveverdicts on theHAProxyTemplateConfig, the startup load gate included.haptic_validation_errors_totalcounts only HAProxy's verdicts on rendered configurations.
on_own_lines(render_glob "prefix-*")template function: renders the matching snippets so that each starts on a new line.
Changed
haptic_render_totalandhaptic_render_errors_totalexport everycache_stateat zero, andhaptic_config_rejected_totaleveryvalidator, soincrease()and theHAProxyControllerConfigRejectedalert see the first failure.- A change to a server's
maxconnis applied with HAProxy's runtime API instead of a reload. - The controller logs
Reload requiredat INFO with the pod and the reasons whenever it reloads a pod, instead of only at DEBUG.
Fixed
haptic preflightvalidates sidecar configurations even when a restrictive umask would prevent the container user from reading temporary files.- When an upgrade adds runtime operations, older agents still apply supported runtime changes without a reload.
- Frequent per-pod status writes no longer block publication of a changed
HAProxyCfgwith resource-version conflicts. - An unchanged successful render-gate verdict no longer rewrites
HAProxyCfgstatus on every render. - A change to the credentials Secret that leaves
dataplane_usernameanddataplane_passwordunchanged, such as every Helm upgrade, no longer restarts the controller iteration, which briefly doubled controller memory and could OOMKill large installs (#456). - A controller container restarted during its startup validation no longer fails every
validationTestwithno space left on device. Each test's scratch files are removed when it finishes, instead of when the whole suite does. - A controller could stop deploying, leaving HAProxy pods unready, when the render gate's verdict reached the deployment scheduler before the render it named. Each component now receives an event before any reaction to it.
- A configuration change on a large install no longer hands leadership to a replica with a cold render graph while the warm-up render is still running, which delayed deployments until the new leader rendered from scratch.
- Deployments no longer contend with leader Lease renewals or log spurious
Failed to update leaseerrors. - A new leader preserves the latest configuration validation verdict instead of reporting an older accepted configuration as valid over a newer rejected or unvalidated generation.
- Configuration changes fetch watched-resource schemas in parallel, and API discovery timeouts leave validation inconclusive and retry it instead of rejecting templates that use typed fields.
- Admission denials show the governance rule's message and the watched object; other render errors identify the watched object without exposing encoded cache keys.
- Startup-validation messages describe retrying NotReady pods and stalled rollouts instead of claiming the controller exits on rejection.
- A deployment cancelled because the HAProxy pod set changed no longer logs
context cancelederrors, emitsApplyFailedPod events, or counts inhaptic_deployment_errors_total(#430). - Expected events log at INFO instead of WARN: config publisher API calls cancelled by its own shutdown, the wait for the render gate's first verdict after a start or configuration change, and a leader drained during a configuration hand-over (#444, #445, #453).
Helm chart
Added
extraContext.forwardedHeaders.trustedProxies: the L7 load balancers whoseX-Forwarded-For,-Proto,-Host, and-Portheaders HAPTIC keeps.controller.rbac.releaseNamespaceSecretsOnlylimits Secret reads to the release namespace and rejects references elsewhere.- A watched resource that lists
namespacesis granted by a Role in each listed namespace instead of the ClusterRole. HAProxyControllerConfigNotValidatedalert (controller.monitoring.prometheusRule.defaultRules.configNotValidated): a replica hasn't validated its newestHAProxyTemplateConfigfor 10 minutes.
Changed
- The pre-upgrade hook rolls the controller Deployment to the new image before Helm applies new templates, so old replicas no longer reject a valid incoming configuration. See controller preparation for custom image tags and deployments without hooks.
- BREAKING: haproxy-ingress:
haproxy-ingress.github.io/forwardfor: addreplaces the client'sX-Forwarded-Forandupdateappends to it, as upstream does; HAPTIC had them the other way round. Check your Ingresses before upgrading. - An Ingress that sets
X-Forwarded-Forhandling through annotations from two families is rejected at admission, like other mixed-family features. - A
helm upgradethat changes only the chart version no longer changes theHAProxyTemplateConfig, so running controllers don't start a new iteration mid-rollout. The controller-managed HAProxy Service drops itshelm.sh/chart,app.kubernetes.io/version, andapp.kubernetes.io/managed-bylabels. - Controller pods no longer carry the
helm.sh/chartandapp.kubernetes.io/versionlabels; the Deployment keeps them. A chart upgrade then rolls the controllers once instead of twice; the upgrade to 0.7.0 itself still rolls them twice (#467).
Fixed
- Preflight compiles Varnish configurations with the deployed image when caching is enabled and a released fixture image when it is disabled.
- Custom TCP frontends that accept PROXY protocol pass validation when the built-in HTTP/HTTPS PROXY listeners are disabled.
haproxy.org/pod-maxconnandhaproxy-haptic.org/pod-maxconnsetmaxconnon each server line, so a change in the ready HAProxy pod count (for example during a rollout) updates it at runtime instead of reloading every HAProxy pod (#474).haproxy-haptic.org/forwardforandhaproxy-ingress.github.io/forwardfor:addandupdateno longer send the client address twice, andifmissingandignoreno longer append it to the client's header.- haproxytech:
haproxy.org/forwarded-for: "false"forwards the client'sX-Forwarded-Forunchanged; it was ignored. - A snippet at an extension point starts on its own line whether or not its template begins or ends with a newline. A
frontend-extra-*or other snippet without a leading newline could join the previous line and fail validation.
Security
- BREAKING: Raw HAProxy configuration annotations (
haproxy-haptic.org/config-*,haproxy-ingress.github.io/config-*,haproxy.org/backend-config-snippet, andnginx.ingress.kubernetes.io/configuration-snippet) are rejected unlesscontroller.config.templatingSettings.extraContext.ingressPermissions.allowRawHAProxyConfigistrue. Any Ingress writer in a watched namespace could otherwise change the configuration for every host or read HAProxy's TLS keys.waf.ingressPermissions.allowRawHAProxyConfigcan only narrow it. Check your Ingresses before upgrading. - WAF governance's
allowRawHAProxyConfig: falsealso rejects raw configuration annotations when thehapticAnnotationslibrary is disabled. - BREAKING: Every HTTP frontend replaces a client-sent
X-Forwarded-Forwith the client address, setsX-Forwarded-Prototohttpsorhttp, and drops a client-sentX-Forwarded-HostandX-Forwarded-Port, so clients can't forge their address or scheme (#406).X-Forwarded-Host,-Port, and-Protoset byfrontend-extra-*snippets are kept. Behind an L7 load balancer, list it intrustedProxies;trustedProxies: ["0.0.0.0/0", "::/0"]restores the oldX-Forwarded-Forhandling.