feat(secrets): ClusterSecretStore + declarative audit — SOPS migration phase 2 #170

Merged
k.renner merged 1 commits from openbao-phase2 into master 2026-07-13 17:00:03 +00:00
5 changed files with 59 additions and 10 deletions
+8 -2
View File
@@ -41,7 +41,10 @@ Post-merge, one-time init (single admin → 1 share / threshold 1):
```sh
kubectl -n openbao exec -it openbao-0 -- bao operator init \
-key-shares=1 -key-threshold=1
# Store BOTH outputs in the existing GPG pass store, nowhere else:
# Store BOTH outputs in the GPG pass store, nowhere else:
# (bootstrapped 2026-07-13: key 6B8FED8020C1478F892EA83816866E146A8252A4,
# no passphrase yet — set one via `gpg --edit-key ... passwd`, and BACK THE
# KEY UP off-machine: without it, pass and thus unseal key are gone.)
pass insert homelab/openbao/unseal-key
pass insert homelab/openbao/root-token
kubectl -n openbao exec -it openbao-0 -- bao operator unseal # paste key
@@ -61,7 +64,10 @@ Manual, with the root token (then stop using the root token day-to-day):
export BAO_ADDR=https://openbao.k.renner.uno
bao login # root token, from pass
bao secrets enable -path=homelab -version=2 kv
bao audit enable file file_path=stdout # audit into pod logs → Loki
# NOTE: `bao audit enable` is disabled in OpenBao 2.5 — audit devices are
# declarative-only, configured in the server HCL (see the audit stanza in
# infrastructure/openbao/helmrelease.yaml; keep log_raw OFF or plaintext
# secrets land in Loki).
bao auth enable kubernetes
bao write auth/kubernetes/config \
kubernetes_host=https://kubernetes.default.svc.cluster.local:443
+2 -4
View File
@@ -25,10 +25,8 @@ resources:
- spegel/
- openbao/
- external-secrets/
# ClusterSecretStore for OpenBao intentionally NOT committed yet: it can only
# turn Ready after `bao operator init` + auth setup (manual, see
# kubernetes/MIGRATION-sops-openbao.md phase 2) — committing it earlier would
# block the wait/health gate of the infrastructure-crds Kustomization.
# The OpenBao ClusterSecretStore lives in post-crds/ (needs ESO's CRDs and
# an initialized OpenBao; see kubernetes/MIGRATION-sops-openbao.md).
# cnpg-barman-plugin/ lives in its own Flux Kustomization
# (`infrastructure-cnpg-barman`) so it can dependsOn infrastructure-crds
# where the cert-manager Certificates create the TLS Secrets its
@@ -43,16 +43,40 @@ spec:
enabled: false
server:
# Single-node raft (not standalone/file) so we get `bao operator raft
# snapshot` as a consistent backup primitive. The chart's default raft
# config already matches (ui on, tls_disable listener on 8200, raft
# storage at /openbao/data, kubernetes service_registration). TLS
# terminates at the Traefik ingress; in-cluster traffic is plain HTTP.
# snapshot` as a consistent backup primitive. TLS terminates at the
# Traefik ingress; in-cluster traffic is plain HTTP.
ha:
enabled: true
replicas: 1
raft:
enabled: true
setNodeId: true
# Chart default config (ui, tls_disable listener, raft storage,
# kubernetes service_registration) + the audit device: OpenBao 2.5
# only supports declarative audit config, `bao audit enable` via
# API is disabled. NO log_raw — raw mode would ship plaintext
# secret values via stdout into Loki; default HMAC redaction stays.
config: |
ui = true
listener "tcp" {
tls_disable = 1
address = "[::]:8200"
cluster_address = "[::]:8201"
}
storage "raft" {
path = "/openbao/data"
}
service_registration "kubernetes" {}
audit "file" "stdout" {
description = "audit trail to pod stdout -> Loki"
options {
file_path = "/dev/stdout"
}
}
dataStorage:
enabled: true
size: 5Gi
@@ -6,4 +6,8 @@ resources:
- cilium-bgp.yaml
- cnpg-barman-certs.yaml
- velero-schedules.yaml
# Only safe here because OpenBao is already initialized + k8s-auth is
# configured (2026-07-13): a store that can't turn Ready would block this
# KS's wait gate and freeze the dependsOn chain.
- openbao-clustersecretstore.yaml
- ../network-policies/
@@ -0,0 +1,17 @@
apiVersion: external-secrets.io/v1
kind: ClusterSecretStore
metadata:
name: openbao
spec:
provider:
vault: # ESO's provider name; speaks OpenBao fine
server: http://openbao.openbao.svc.cluster.local:8200
path: homelab
version: v2
auth:
kubernetes:
mountPath: kubernetes
role: eso
serviceAccountRef:
name: external-secrets
namespace: external-secrets