Secrets
Secrets engine with KV storage, an embedded web UI, and TLS listeners. MPL-2.0. linux/amd64.
Pin this image by digest.
published Latest tag v2.7.1-tpio.1. Pin by digest. Usage is on this page.
Pin by digest
oci.thepeoples.io/hardened/openbao@sha256:d7bc22f2f86c33ed96e29ba3d10975def3d492a83914caa00994e3e2b948d79aPull:
podman pull oci.thepeoples.io/hardened/openbao@sha256:d7bc22f2f86c33ed96e29ba3d10975def3d492a83914caa00994e3e2b948d79aVerify:
cosign verify --key https://thepeoples.io/keys/oci.thepeoples.io.pub --insecure-ignore-tlog oci.thepeoples.io/hardened/openbao@sha256:d7bc22f2f86c33ed96e29ba3d10975def3d492a83914caa00994e3e2b948d79aPublished 2026-10-22T15:24:09Z40.5 MiB compressed
Usage
Validated against this published digest: official-chart installation, exact runtime digest, nonroot UID 65532, health, initialization and unseal, KV write and read, persistent restart, Prometheus metrics and the embedded web UI. Functional evidence.
OpenBao and its embedded Ember UI are rebuilt from the pinned v2.7.1 source. The runtime is scratch under UID/GID 65532:65532. The official chart package is 0.30.4. Its container command is a shell entrypoint, which scratch cannot run, so Helm must use the post-renderer below. That renderer sets the container command to /usr/bin/bao server with the chart config file, clears args, and removes the shell preStop hook. Save it as openbao-chart-scratch.py and make it executable.
Create namespace openbao and Secret openbao-tls with tls.crt and tls.key covering the listener hostname before installation. Use your internal PKI or another trusted certificate. No default certificate is shipped, and a missing Secret prevents startup. Injector and CSI stay off. The service is ClusterIP with ingress disabled. Initialize and unseal after the first start, and store the unseal keys and root token outside the cluster and outside Git. Unauthenticated metrics stay off.
The StatefulSet requests a 10Gi ReadWriteOnce volume. Choose the StorageClass and capacity first. Storage must support fsGroup 65532 or already be writable by that UID/GID. Keep one replica for this filesystem layout and back up PebbleDB data before upgrades. server.updateStrategyType is RollingUpdate so helm --wait waits for the pod.
Save the following as values-hardened.yaml:
# Official OpenBao chart 0.30.4. Render a published v2.7.1-tpio.1@sha256:d7bc22f2f86c33ed96e29ba3d10975def3d492a83914caa00994e3e2b948d79a with
# scripts/render-openbao-config.py. Create Secret openbao-tls (tls.crt, tls.key)
# covering the listener hostname before installing. Helm requires
# --post-renderer scripts/openbao-chart-scratch.py because the chart command is
# /bin/sh plus docker-entrypoint.sh; scratch has no shell. Overlay official
# UID/GID 100 to 65532. Set server.updateStrategyType to RollingUpdate so
# Helm 3.19 --wait and kubectl rollout status wait for the pod (chart default
# OnDelete skips the ready check). Injector and CSI stay off. Skip chart test
# hooks.
fullnameOverride: openbao
injector: {enabled: false}
csi: {enabled: false}
server:
enabled: true
image:
registry: oci.thepeoples.io
repository: hardened/openbao
tag: "v2.7.1-tpio.1@sha256:d7bc22f2f86c33ed96e29ba3d10975def3d492a83914caa00994e3e2b948d79a"
pullPolicy: IfNotPresent
uid: 65532
gid: 65532
updateStrategyType: RollingUpdate
dataStorage:
enabled: true
size: 10Gi
accessMode: ReadWriteOnce
dev: {enabled: false}
standalone:
enabled: true
config: |
ui = true
listener "tcp" {
address = "[::]:8200"
cluster_address = "[::]:8201"
tls_cert_file = "/openbao/tls/tls.crt"
tls_key_file = "/openbao/tls/tls.key"
telemetry { unauthenticated_metrics_access = "false" }
}
storage "pebbledb" { path = "/openbao/data/pebbledb" }
telemetry {
prometheus_retention_time = "30s"
disable_hostname = true
}
ha: {enabled: false}
extraVolumes:
- name: tls
secret: {secretName: openbao-tls}
- name: tmp
emptyDir: {sizeLimit: 64Mi}
extraVolumeMounts:
- name: tls
mountPath: /openbao/tls
readOnly: true
- name: tmp
mountPath: /tmp
statefulSet:
securityContext:
pod:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
fsGroupChangePolicy: OnRootMismatch
seccompProfile: {type: RuntimeDefault}
container:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities: {drop: [ALL]}
readinessProbe:
enabled: true
path: /v1/sys/health?standbyok=true&sealedcode=200&uninitcode=200
port: 8200
livenessProbe: {enabled: false}
resources:
requests: {cpu: 100m, memory: 128Mi}
limits: {cpu: "2", memory: 1Gi}
ui:
enabled: true
serviceType: ClusterIP
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/os: linux#!/usr/bin/env python3
"""Rewrite official OpenBao chart pods so a scratch image can start."""
import sys
import yaml
COMMAND = ["/usr/bin/bao", "server", "-config=/openbao/config/extraconfig-from-values.hcl"]
def patch(doc):
if not isinstance(doc, dict) or doc.get("kind") != "StatefulSet":
return doc
spec = ((doc.get("spec") or {}).get("template") or {}).get("spec") or {}
for container in spec.get("containers") or []:
if container.get("name") != "openbao":
continue
container["command"] = list(COMMAND)
container["args"] = []
lifecycle = container.get("lifecycle") or {}
lifecycle.pop("preStop", None)
if lifecycle:
container["lifecycle"] = lifecycle
else:
container.pop("lifecycle", None)
return doc
def main():
docs = list(yaml.safe_load_all(sys.stdin.read() or ""))
yaml.dump_all((patch(doc) for doc in docs if doc is not None), sys.stdout,
default_flow_style=False, sort_keys=False, allow_unicode=True)
return 0
if __name__ == "__main__":
raise SystemExit(main())chmod +x openbao-chart-scratch.py
helm repo add openbao https://openbao.github.io/openbao-helm
helm pull openbao/openbao --version 0.30.4
echo 'f9d464f0288a96374fcddb33abb31bc3f134ccaa32da3e4cf272f143b34bb96b openbao-0.30.4.tgz' | sha256sum -c -
helm template openbao ./openbao-0.30.4.tgz --namespace openbao -f values-hardened.yaml --skip-tests --post-renderer ./openbao-chart-scratch.py
helm upgrade --install openbao ./openbao-0.30.4.tgz --namespace openbao -f values-hardened.yaml --post-renderer ./openbao-chart-scratch.py --wait --timeout 5mFor existing Kustomize manifests using the upstream image, pin this replacement:
images:
- name: quay.io/openbao/openbao
newName: oci.thepeoples.io/hardened/openbao
digest: sha256:d7bc22f2f86c33ed96e29ba3d10975def3d492a83914caa00994e3e2b948d79a # v2.7.1-tpio.1Verify the latest published digest
cosign verify --key https://thepeoples.io/keys/oci.thepeoples.io.pub --insecure-ignore-tlog oci.thepeoples.io/hardened/openbao@sha256:d7bc22f2f86c33ed96e29ba3d10975def3d492a83914caa00994e3e2b948d79a
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/openbao@sha256:d7bc22f2f86c33ed96e29ba3d10975def3d492a83914caa00994e3e2b948d79aThe 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. 40.5 MiB · Publication scan reports: Trivy · Grype · gate · 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
v2.7.1-tpio.1 · worst-of Trivy and Grype at publish.v2.7.1-tpio.1 is at /oci/hardened/openbao/v2.7.1-tpio.1/source/.Scanner CVE / ID Package Installed Severity Fixed version available
This image is here as the Secrets engine with embedded Ember UI.
Status: published. Platform: linux/amd64.
Available tags and scan history
v2.7.1-tpio.1
Digest:
oci.thepeoples.io/hardened/openbao@sha256:d7bc22f2f86c33ed96e29ba3d10975def3d492a83914caa00994e3e2b948d79aPublished 2026-10-22T15:24:09Z UTC.
This tag used the first-publish cooldown break-glass (first publish; PhreeStyle GO 2026-10-19 12:26 PM CT).
Publication scan reports: Trivy / Grype / gate / OpenVEX
SPDX SBOM · OpenVEX: not present
Corresponding source available at /oci/hardened/openbao/v2.7.1-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-22T15:17:19Z | publish / pass | CRITICAL 0HIGH 0MEDIUM 0LOW 0 | CRITICAL 0HIGH 0MEDIUM 0LOW 0 | Trivy 0.75.0 / DB {"DownloadedAt": "2026-10-22T15:15:23.711294079Z", "NextUpdate": "2026-10-23T13:15:26.425424534Z", "UpdatedAt": "2026-10-22T13:15:26.425424764Z", "Version": 2} / 2026-10-22T13:15:26.425424764Z; Grype 0.120.1 / schema v6.1.10 / 2026-10-22T06:29:52Z |
MEDIUM/LOW are best-effort and non-blocking. Remaining counts:
MEDIUM 0LOW 0Fixed-version availability does not guarantee a compatible fix.Remaining MEDIUM/LOW findings (0 distinct scanner/package/version records; 0 with fixed versions available)
Scanner CVE / ID Package Installed Severity 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
The recipe rebuilds OpenBao and the Ember UI from the pinned release tarball using Go 1.27.3 and Node 20.20.0. Compatible x/net updates use GO_BUMPS. Scratch runtime, UID/GID 65532, no shell or build tools. Publication requires fresh unsuppressed 0 CRITICAL / 0 HIGH scans, all nine official-chart functional checks and checksum-verified live source for the exact digest.
Licence: MPL-2.0.
OpenBao is MPL-2.0. Corresponding source is the official v2.7.1 release tarball plus this Containerfile, Ember UI rebuild, and recorded module changes.