diff --git a/kubernetes/MIGRATION-sops-openbao.md b/kubernetes/MIGRATION-sops-openbao.md index 40452e8c..c56de574 100644 --- a/kubernetes/MIGRATION-sops-openbao.md +++ b/kubernetes/MIGRATION-sops-openbao.md @@ -30,7 +30,7 @@ must exist before phase 3 begins, not after. ## Phase 1 — deploy (this PR) Adds `kubernetes/infrastructure/openbao/` (single-node raft, 5Gi ceph-block, -UI at `openbao.k.renner.uno`, internal-only) and +UI at `openbao.renner.uno`, not publicly routed) and `kubernetes/infrastructure/external-secrets/` (ESO, CRDs via CreateReplace). No ClusterSecretStore yet (constraint 1). Merging is safe: nothing consumes either component; the OpenBao pod sits 0/1 Ready (sealed) by design @@ -61,7 +61,7 @@ Secrets keep their last value (they are real k8s Secrets — pods keep running). Manual, with the root token (then stop using the root token day-to-day): ```sh -export BAO_ADDR=https://openbao.k.renner.uno +export BAO_ADDR=https://openbao.renner.uno bao login # root token, from pass bao secrets enable -path=homelab -version=2 kv # NOTE: `bao audit enable` is disabled in OpenBao 2.5 — audit devices are diff --git a/kubernetes/infrastructure/network-policies/kustomization.yaml b/kubernetes/infrastructure/network-policies/kustomization.yaml index 1c68bb12..3664c064 100644 --- a/kubernetes/infrastructure/network-policies/kustomization.yaml +++ b/kubernetes/infrastructure/network-policies/kustomization.yaml @@ -18,4 +18,5 @@ resources: - rook-ceph-ns.yaml - velero-ns.yaml - evcc-ns.yaml + - openbao-ns.yaml - allow-cilium-health.yaml diff --git a/kubernetes/infrastructure/network-policies/openbao-ns.yaml b/kubernetes/infrastructure/network-policies/openbao-ns.yaml new file mode 100644 index 00000000..6be5d826 --- /dev/null +++ b/kubernetes/infrastructure/network-policies/openbao-ns.yaml @@ -0,0 +1,33 @@ +apiVersion: cilium.io/v2 +kind: CiliumNetworkPolicy +metadata: + name: default-deny-ingress + namespace: openbao +spec: + endpointSelector: {} + ingress: + # Intra-namespace — the raft-snapshot CronJob talks to the openbao + # Service on :8200. + - fromEndpoints: + - matchLabels: + "k8s:io.kubernetes.pod.namespace": openbao + # UI/API via Traefik. Public non-reachability is enforced at the edge + # (proxy.renner.uno serves only explicitly configured SNI — openbao is + # not among them), NOT by hostname choice; this rule additionally pins + # cluster-side access to the ingress path. + - fromEndpoints: + - matchLabels: + "k8s:io.kubernetes.pod.namespace": ingress + app.kubernetes.io/name: traefik + toPorts: + - ports: + - port: "8200" + protocol: TCP + # External Secrets Operator syncs ExternalSecrets from the KV API. + - fromEndpoints: + - matchLabels: + "k8s:io.kubernetes.pod.namespace": external-secrets + toPorts: + - ports: + - port: "8200" + protocol: TCP diff --git a/kubernetes/infrastructure/openbao/ingress.yaml b/kubernetes/infrastructure/openbao/ingress.yaml index a3cd3196..51bfd236 100644 --- a/kubernetes/infrastructure/openbao/ingress.yaml +++ b/kubernetes/infrastructure/openbao/ingress.yaml @@ -8,10 +8,12 @@ metadata: spec: ingressClassName: traefik rules: - # Deliberately internal-only (no openbao.renner.uno second host): the - # secrets-manager UI/API has no business being reachable from the - # public edge. Add the external host only with a conscious decision. - - host: openbao.k.renner.uno + # Internal-only despite the production domain: external-dns publishes the + # internal LB IP for this name, and the public edge (proxy.renner.uno) + # refuses SNI it isn't configured for — the secrets-manager UI/API is not + # reachable from the internet. NOTE: *.k.renner.uno is banned (migration- + # era artifact, owner directive 2026-07-14) — never add a k. host here. + - host: openbao.renner.uno http: paths: - path: / @@ -24,4 +26,4 @@ spec: tls: - secretName: openbao-tls hosts: - - openbao.k.renner.uno + - openbao.renner.uno