Terminate TLS on OpenBao with a cert-manager self-signed certificate
Adds a ClusterIssuer (selfSigned) + Certificate, mounts the resulting secret into the OpenBao pod, and switches the listener config from tls_disable=1 to a TLS-enabled listener. UI/API is now served over https://<node-ip>:30200 instead of plain HTTP. Also updates ClusterSecretStore/bootstrap Job to use https + trust the self-signed cert via caProvider/BAO_SKIP_VERIFY. Co-authored-by: Copilot <[email protected]>
This commit is contained in:
@@ -8,16 +8,37 @@ via Vault's Kubernetes auth method.
|
|||||||
This chart wraps the official [`openbao-helm`](https://github.com/openbao/openbao-helm)
|
This chart wraps the official [`openbao-helm`](https://github.com/openbao/openbao-helm)
|
||||||
chart as a dependency and adds:
|
chart as a dependency and adds:
|
||||||
|
|
||||||
|
- A self-signed TLS certificate (via cert-manager) that OpenBao terminates
|
||||||
|
itself, so both the UI and API are served over HTTPS
|
||||||
- A `ClusterSecretStore` (ESO CRD) pointing at the OpenBao service
|
- A `ClusterSecretStore` (ESO CRD) pointing at the OpenBao service
|
||||||
- A one-time bootstrap `Job` (disabled by default) that enables the
|
- A one-time bootstrap `Job` (disabled by default) that enables the
|
||||||
Kubernetes auth method, a read-only policy, and a role bound to ESO's
|
Kubernetes auth method, a read-only policy, and a role bound to ESO's
|
||||||
ServiceAccount
|
ServiceAccount
|
||||||
|
|
||||||
|
## TLS
|
||||||
|
|
||||||
|
OpenBao terminates HTTPS itself using a certificate issued by a dedicated
|
||||||
|
`ClusterIssuer/openbao-selfsigned` (cert-manager, `selfSigned` type - no
|
||||||
|
external CA involved). The UI/API is reachable at
|
||||||
|
`https://<node-ip>:30200` (NodePort, same pattern as ArgoCD).
|
||||||
|
|
||||||
|
Because the certificate is self-signed, browsers will show a trust warning
|
||||||
|
- this is expected. `ExternalSecret`/`ClusterSecretStore` traffic from ESO
|
||||||
|
trusts it automatically via `caProvider` (pointing at the same
|
||||||
|
`openbao-tls` Secret cert-manager creates), so no manual CA import is
|
||||||
|
needed for that path.
|
||||||
|
|
||||||
|
If you add/replace a node, or want a different reachable hostname, add it to
|
||||||
|
`tls.ipAddresses` / `tls.dnsNames` in `values.yaml` and cert-manager will
|
||||||
|
reissue the certificate automatically.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- ESO must already be installed in the cluster (deployed separately via the
|
- ESO must already be installed in the cluster (deployed separately via the
|
||||||
`apps-in-apps` repo) with a ServiceAccount named `eso.serviceAccountName`
|
`apps-in-apps` repo) with a ServiceAccount named `eso.serviceAccountName`
|
||||||
(default: `external-secrets`) in `eso.namespace` (default: `external-secrets`).
|
(default: `external-secrets`) in `eso.namespace` (default: `external-secrets`).
|
||||||
|
- cert-manager must already be installed (used for the self-signed TLS cert,
|
||||||
|
see below).
|
||||||
|
|
||||||
## Deployment & manual init/unseal
|
## Deployment & manual init/unseal
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,11 @@ spec:
|
|||||||
image: {{ .Values.bootstrap.image }}
|
image: {{ .Values.bootstrap.image }}
|
||||||
env:
|
env:
|
||||||
- name: BAO_ADDR
|
- name: BAO_ADDR
|
||||||
value: "http://{{ include "openbao-gitops.openbaoFullname" . }}:8200"
|
value: "{{ if .Values.tls.enabled }}https{{ else }}http{{ end }}://{{ include "openbao-gitops.openbaoFullname" . }}:8200"
|
||||||
|
{{- if .Values.tls.enabled }}
|
||||||
|
- name: BAO_SKIP_VERIFY
|
||||||
|
value: "true"
|
||||||
|
{{- end }}
|
||||||
- name: BAO_TOKEN
|
- name: BAO_TOKEN
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
|
|||||||
@@ -8,9 +8,16 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
provider:
|
provider:
|
||||||
vault:
|
vault:
|
||||||
server: "http://{{ include "openbao-gitops.openbaoFullname" . }}.{{ .Release.Namespace }}.svc:8200"
|
server: "{{ if .Values.tls.enabled }}https{{ else }}http{{ end }}://{{ include "openbao-gitops.openbaoFullname" . }}.{{ .Release.Namespace }}.svc:8200"
|
||||||
path: {{ .Values.eso.kvMountPath }}
|
path: {{ .Values.eso.kvMountPath }}
|
||||||
version: v2
|
version: v2
|
||||||
|
{{- if .Values.tls.enabled }}
|
||||||
|
caProvider:
|
||||||
|
type: Secret
|
||||||
|
name: {{ .Values.tls.secretName }}
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
key: tls.crt
|
||||||
|
{{- end }}
|
||||||
auth:
|
auth:
|
||||||
kubernetes:
|
kubernetes:
|
||||||
mountPath: kubernetes
|
mountPath: kubernetes
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
{{- if .Values.tls.enabled }}
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: ClusterIssuer
|
||||||
|
metadata:
|
||||||
|
name: openbao-selfsigned
|
||||||
|
spec:
|
||||||
|
selfSigned: {}
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: {{ .Values.tls.secretName }}
|
||||||
|
namespace: {{ .Release.Namespace }}
|
||||||
|
spec:
|
||||||
|
secretName: {{ .Values.tls.secretName }}
|
||||||
|
duration: {{ .Values.tls.duration }}
|
||||||
|
renewBefore: {{ .Values.tls.renewBefore }}
|
||||||
|
issuerRef:
|
||||||
|
name: openbao-selfsigned
|
||||||
|
kind: ClusterIssuer
|
||||||
|
dnsNames:
|
||||||
|
- {{ include "openbao-gitops.openbaoFullname" . }}
|
||||||
|
- {{ include "openbao-gitops.openbaoFullname" . }}.{{ .Release.Namespace }}
|
||||||
|
- {{ include "openbao-gitops.openbaoFullname" . }}.{{ .Release.Namespace }}.svc
|
||||||
|
- {{ include "openbao-gitops.openbaoFullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
|
||||||
|
- localhost
|
||||||
|
{{- range .Values.tls.dnsNames }}
|
||||||
|
- {{ . }}
|
||||||
|
{{- end }}
|
||||||
|
ipAddresses:
|
||||||
|
- "127.0.0.1"
|
||||||
|
{{- range .Values.tls.ipAddresses }}
|
||||||
|
- {{ . | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
+40
-1
@@ -10,6 +10,24 @@ openbao:
|
|||||||
# Standalone mode: single replica, file storage backend, PVC-backed.
|
# Standalone mode: single replica, file storage backend, PVC-backed.
|
||||||
standalone:
|
standalone:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
# TLS terminated directly by OpenBao itself, using the cert-manager
|
||||||
|
# issued self-signed certificate mounted below (see templates/tls.yaml
|
||||||
|
# and the `tls:` section further down). "-tls-skip-verify" is already
|
||||||
|
# baked into the chart's readiness/liveness probes, so this doesn't
|
||||||
|
# need any extra values there.
|
||||||
|
config: |
|
||||||
|
ui = true
|
||||||
|
|
||||||
|
listener "tcp" {
|
||||||
|
tls_disable = 0
|
||||||
|
address = "[::]:8200"
|
||||||
|
cluster_address = "[::]:8201"
|
||||||
|
tls_cert_file = "/openbao/userconfig/openbao-tls/tls.crt"
|
||||||
|
tls_key_file = "/openbao/userconfig/openbao-tls/tls.key"
|
||||||
|
}
|
||||||
|
storage "file" {
|
||||||
|
path = "/openbao/data"
|
||||||
|
}
|
||||||
|
|
||||||
dataStorage:
|
dataStorage:
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -24,6 +42,12 @@ openbao:
|
|||||||
authDelegator:
|
authDelegator:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
|
# Mounts the cert-manager issued TLS secret at
|
||||||
|
# /openbao/userconfig/openbao-tls/{tls.crt,tls.key,ca.crt}.
|
||||||
|
extraVolumes:
|
||||||
|
- type: secret
|
||||||
|
name: openbao-tls
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 250m
|
cpu: 250m
|
||||||
@@ -35,7 +59,7 @@ openbao:
|
|||||||
ui:
|
ui:
|
||||||
enabled: true
|
enabled: true
|
||||||
# NodePort, same pattern as ArgoCD (30080/30443) and Gitea (30300):
|
# NodePort, same pattern as ArgoCD (30080/30443) and Gitea (30300):
|
||||||
# reachable at http://<node-ip>:30200 without needing an Ingress.
|
# reachable at https://<node-ip>:30200 without needing an Ingress.
|
||||||
serviceType: NodePort
|
serviceType: NodePort
|
||||||
serviceNodePort: 30200
|
serviceNodePort: 30200
|
||||||
|
|
||||||
@@ -43,6 +67,21 @@ openbao:
|
|||||||
# Sidecar-injector webhook is not needed for ESO integration.
|
# Sidecar-injector webhook is not needed for ESO integration.
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
|
# --- TLS (self-signed via cert-manager) -------------------------------------
|
||||||
|
|
||||||
|
tls:
|
||||||
|
enabled: true
|
||||||
|
secretName: openbao-tls
|
||||||
|
# cert-manager Certificate validity/renewal.
|
||||||
|
duration: 2160h # 90d
|
||||||
|
renewBefore: 360h # 15d
|
||||||
|
# Extra SANs beyond the in-cluster service names (which are always
|
||||||
|
# included). Add your node IP(s)/hostname(s) here so browsers hitting the
|
||||||
|
# NodePort get a matching cert.
|
||||||
|
ipAddresses:
|
||||||
|
- 192.168.2.218
|
||||||
|
dnsNames: []
|
||||||
|
|
||||||
# --- ESO <-> OpenBao binding -------------------------------------------------
|
# --- ESO <-> OpenBao binding -------------------------------------------------
|
||||||
|
|
||||||
eso:
|
eso:
|
||||||
|
|||||||
Reference in New Issue
Block a user