HAProxy
TCP and HTTP load balancer. GPL-2.0-or-later. linux/amd64.
Pin this image next to hardened Argo CD.
published Latest tag 3.3.16-alpine-tpio.1. Usage with Argo CD is on the Argo CD page.
Pin by digest
oci.thepeoples.io/hardened/haproxy@sha256:ba110856a084d7a5b9d61325ef6a24928371b3a9b22a37270a53929c5a7c1e7ePull:
podman pull oci.thepeoples.io/hardened/haproxy@sha256:ba110856a084d7a5b9d61325ef6a24928371b3a9b22a37270a53929c5a7c1e7eVerify:
cosign verify --key https://thepeoples.io/keys/oci.thepeoples.io.pub --insecure-ignore-tlog oci.thepeoples.io/hardened/haproxy@sha256:ba110856a084d7a5b9d61325ef6a24928371b3a9b22a37270a53929c5a7c1e7ePublished 2026-10-09T16:13:59Z21.8 MiB compressed
Usage
These image overrides were exercised as part of the full argo/argo-cd 10.10.1 Helm HA install; see the Validated section. The redis_exporter sidecar is not hardened. The example pins the upstream image by digest and labels it in the values file. A proposal to add it to the hardened allowlist is recorded with the catalog change. Use the complete HA values for the full tested configuration.
global: {image: {repository: oci.thepeoples.io/hardened/argocd, tag: "v3.5.4-tpio.2@sha256:0f0d36559c94d41c544d65c6ead8bd2aa7f29a9d04d9721af9dd29c2558bc2d8"}}
dex: {image: {repository: oci.thepeoples.io/hardened/dex, tag: "v2.46.0-tpio.2@sha256:29991671646ac11153ba0225fc26b20b237ad432be56cbcaccb7b1e9635f4ba3"}}
redis: {image: {repository: oci.thepeoples.io/hardened/redis, tag: "8.6.4-alpine-tpio.1@sha256:83b6e02798f8896d6eddd4f6c977a821ac4fe8a12d0bd886e1db9cb775114145"}}
redis-ha:
image: {repository: oci.thepeoples.io/hardened/redis, tag: "8.6.4-alpine-tpio.1@sha256:83b6e02798f8896d6eddd4f6c977a821ac4fe8a12d0bd886e1db9cb775114145"}
haproxy: {image: {repository: oci.thepeoples.io/hardened/haproxy, tag: "3.3.16-alpine-tpio.1@sha256:ba110856a084d7a5b9d61325ef6a24928371b3a9b22a37270a53929c5a7c1e7e"}}
---
# Production-oriented Helm values exercised by validate/run.sh together with
# validate/values/ha.yaml and the generated image pins. CI-only overlays live
# in test-env.yaml / test-env-ha.yaml and are not part of the public example.
# Secrets stay placeholders. Turn a metrics block off by setting enabled: false.
# NetworkPolicy objects for every component (chart default is already true).
# https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#network-policy
# https://kubernetes.io/docs/concepts/services-networking/network-policies/
global:
networkPolicy:
create: true
defaultDenyIngress: false
# Soft anti-affinity spreads replicas when the cluster has enough nodes.
# https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/
affinity:
podAntiAffinity: soft
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
# https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
logging:
format: json
level: info
# HA shape from the upstream chart README (without autoscaling).
# https://github.com/argoproj/argo-helm/tree/main/charts/argo-cd#ha-mode-without-autoscaling
# https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/
controller:
replicas: 1 # only one replica unless sharding is enabled
# configs.params.controller.sharding.enabled / .replicas to shard clusters
metrics:
enabled: true # set false to skip the metrics Service
pdb:
enabled: true
minAvailable: 1
resources:
requests: {cpu: 250m, memory: 256Mi}
limits: {cpu: 1, memory: 1Gi}
containerSecurityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
seccompProfile: {type: RuntimeDefault}
server:
replicas: 2
metrics:
enabled: true # set false to skip the metrics Service
pdb:
enabled: true
minAvailable: 1
resources:
requests: {cpu: 100m, memory: 128Mi}
limits: {cpu: 500m, memory: 256Mi}
containerSecurityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
seccompProfile: {type: RuntimeDefault}
repoServer:
replicas: 2
# Parallelism is per-pod; scale replicas before raising the limit.
# https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/#repo-server
metrics:
enabled: true # set false to skip the metrics Service
pdb:
enabled: true
minAvailable: 1
resources:
requests: {cpu: 100m, memory: 128Mi}
limits: {cpu: 1, memory: 1Gi}
containerSecurityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
seccompProfile: {type: RuntimeDefault}
applicationSet:
replicas: 2
metrics:
enabled: true # set false to skip the metrics Service
pdb:
enabled: true
minAvailable: 1
resources:
requests: {cpu: 50m, memory: 64Mi}
limits: {cpu: 250m, memory: 256Mi}
containerSecurityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
seccompProfile: {type: RuntimeDefault}
# Dex telemetry is the metrics listener on container port 5558.
# https://dexidp.io/docs/getting-started/
# https://argo-cd.readthedocs.io/en/stable/operator-manual/metrics/
dex:
metrics:
enabled: true # set false to skip the Dex metrics Service
pdb:
enabled: true
minAvailable: 1
resources:
requests: {cpu: 10m, memory: 32Mi}
limits: {cpu: 100m, memory: 128Mi}
containerSecurityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
seccompProfile: {type: RuntimeDefault}
configs:
params:
# 0 = unlimited per repo-server pod. Prefer more replicas over a huge limit.
# https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/#repo-server
reposerver.parallelism.limit: "0"
controller.status.processors: "20"
controller.operation.processors: "10"
# redis-ha AUTH is on by default; replace the generated secret in production.
# https://github.com/DandyDeveloper/charts/tree/master/charts/redis-ha
# https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/
# https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/
redis-ha:
auth: true
existingSecret: argocd-redis # placeholder; chart job fills this unless you bring your own
persistentVolume:
enabled: true
storageClass: "" # cluster default StorageClass
size: 8Gi
exporter:
enabled: true # set false to skip the redis_exporter sidecar
# NOT HARDENED: redis_exporter is not on the hardened allowlist yet.
# Upstream image pinned by digest from oliver006/redis_exporter v1.93.0
# (multi-arch index; linux/amd64 manifest sha256:eb2b1e93b654fc21bf508e45ec3d17ca55d22db66c6b826750cecc92c0c21e42).
image: ghcr.io/oliver006/redis_exporter
tag: "v1.93.0@sha256:6ca518a72f30f7f576ef92963de1b91d3c3f5fd3aeac949f878bfda183587820"
haproxy:
metrics:
enabled: true # set false to skip HAProxy Prometheus metrics
containerSecurityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
seccompProfile: {type: RuntimeDefault}
# https://www.haproxy.org/download/3.3/doc/management.txt
resources:
requests: {cpu: 50m, memory: 64Mi}
limits: {cpu: 250m, memory: 128Mi}Standalone example, not validated
The command also works with podman in place of docker.
HAProxy requires your own haproxy.cfg; this image supplies no default proxy configuration. The port mapping must match a bind :8080 listener in that file. Backends, checks and TLS files belong in your mounted configuration; no environment variable configures them automatically.
docker run --rm -p 127.0.0.1:8080:8080 \
-v "$PWD/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro" \
oci.thepeoples.io/hardened/haproxy@sha256:ba110856a084d7a5b9d61325ef6a24928371b3a9b22a37270a53929c5a7c1e7eVerify the latest published digest
cosign verify --key https://thepeoples.io/keys/oci.thepeoples.io.pub --insecure-ignore-tlog oci.thepeoples.io/hardened/haproxy@sha256:ba110856a084d7a5b9d61325ef6a24928371b3a9b22a37270a53929c5a7c1e7e
cosign verify-attestation --key https://thepeoples.io/keys/oci.thepeoples.io.pub --insecure-ignore-tlog --type https://thepeoples.io/attestations/hardened-gate/v1 oci.thepeoples.io/hardened/haproxy@sha256:ba110856a084d7a5b9d61325ef6a24928371b3a9b22a37270a53929c5a7c1e7eThe report views show the predicate types and commands for SPDX, scanner and optional OpenVEX attestations. Inspect the verified predicates as well as the signature. Publish and rescan reports for each tag. Gate is 0 CRITICAL / 0 HIGH from Trivy and Grype. MEDIUM/LOW are listed; they do not block publish. Remaining-CVE tables live here. 21.8 MiB · Publication scan reports: Trivy · Grype · gate · OpenVEX · Scan index Corresponding source for MEDIUM/LOW are best-effort and non-blocking. Remaining counts: Fixed-version availability does not guarantee a compatible fix. Counts retain scanner gate semantics; the list deduplicates identical package/version records. Different scanner IDs can describe the same advisory.Evidence
3.3.16-alpine-tpio.1 · worst-of Trivy and Grype at publish.3.3.16-alpine-tpio.1 is at /oci/hardened/haproxy/3.3.16-alpine-tpio.1/source/.Scanner CVE / ID Package Installed Severity Fixed version available grype CVE-2025-60876 busybox 1.37.0-r31 MEDIUM No fixed version available grype CVE-2025-60876 busybox-binsh 1.37.0-r31 MEDIUM No fixed version available grype CVE-2025-60876 ssl_client 1.37.0-r31 MEDIUM No fixed version available
This image is here as the HA cache load balancer. Used by Argo CD (HA cache load balancer). Arrow styles
Status: published. Platform: linux/amd64.
Available tags and scan history
3.3.16-alpine-tpio.1
Digest:
oci.thepeoples.io/hardened/haproxy@sha256:ba110856a084d7a5b9d61325ef6a24928371b3a9b22a37270a53929c5a7c1e7ePublished 2026-10-09T16:13:59Z UTC.
This tag used the first-publish cooldown break-glass (first publish; 24h new-upstream cooldown waived).
Publication scan reports: Trivy / Grype / gate / OpenVEX
SPDX SBOM · OpenVEX: attached
Corresponding source available at /oci/hardened/haproxy/3.3.16-alpine-tpio.1/source/, including exact upstream archives, SHA-256 sums, packaging, rebuild recipe and recorded changes.
| Scanned (UTC) | Kind / gate | Trivy | Grype | Scanner DB versions/dates |
|---|---|---|---|---|
| 2026-10-09T16:31:35Z (summary only; full historical report not retained) | rescan / pass | CRITICAL 0HIGH 0MEDIUM 0LOW 0 | CRITICAL 0HIGH 0MEDIUM 3LOW 0 | Trivy 0.75.0 / DB {} / 2026-10-09T01:16:59.530806077Z; Grype 0.120.1 / schema v6.1.10 / 2026-10-09T06:32:32Z |
Show 1 older scans
| Scanned (UTC) | Kind / gate | Trivy | Grype | Scanner DB versions/dates |
|---|---|---|---|---|
| 2026-10-09T13:15:51Z | publish / pass | CRITICAL 0HIGH 0MEDIUM 0LOW 0 | CRITICAL 0HIGH 0MEDIUM 3LOW 0 | Trivy 0.75.0 / DB {} / 2026-10-09T01:16:59.530806077Z; Grype 0.120.1 / schema v6.1.10 / 2026-10-09T06:32:32Z |
MEDIUM/LOW are best-effort and non-blocking. Remaining counts:
MEDIUM 3LOW 0Fixed-version availability does not guarantee a compatible fix.Remaining MEDIUM/LOW findings (3 distinct scanner/package/version records; 0 with fixed versions available)
Scanner CVE / ID Package Installed Severity Fixed version available grype CVE-2025-60876 busybox 1.37.0-r31 MEDIUM No fixed version available grype CVE-2025-60876 busybox-binsh 1.37.0-r31 MEDIUM No fixed version available grype CVE-2025-60876 ssl_client 1.37.0-r31 MEDIUM No fixed version available
Counts retain scanner gate semantics; the list deduplicates identical package/version records. Different scanner IDs can describe the same advisory.
Rebuild and licence
Newest patch on the chart's minor, 3.3.16 (ladder a), plus an apk upgrade layer (ladder c). Two Grype matches (CVE-2026-55203, CVE-2026-55204) are fixed upstream in 3.3.11 per the HAProxy changelog and carried as an attached OpenVEX statement.
Licence: GPL-2.0-or-later.
HAProxy is GPL-2.0-or-later (headers LGPL-2.1). The HAProxy source is unmodified. Obtain corresponding source from the source link for each tag: download the source archive, exact packaging and our rebuild recipe, then verify SHA256SUMS. Alpine package sources are available at https://gitlab.alpinelinux.org/alpine/aports.