feat(secrets): ClusterSecretStore + declarative audit — SOPS migration phase 2 #170
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user