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]>
107 lines
4.1 KiB
Markdown
107 lines
4.1 KiB
Markdown
# openbao-gitops
|
|
|
|
Deploys [OpenBao](https://openbao.org/) (standalone mode, file storage backend)
|
|
as the cluster's central secret management backend, and wires up the
|
|
[External Secrets Operator](https://external-secrets.io/) (ESO) to read from it
|
|
via Vault's Kubernetes auth method.
|
|
|
|
This chart wraps the official [`openbao-helm`](https://github.com/openbao/openbao-helm)
|
|
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 one-time bootstrap `Job` (disabled by default) that enables the
|
|
Kubernetes auth method, a read-only policy, and a role bound to ESO's
|
|
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
|
|
|
|
- ESO must already be installed in the cluster (deployed separately via the
|
|
`apps-in-apps` repo) with a ServiceAccount named `eso.serviceAccountName`
|
|
(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
|
|
|
|
OpenBao (like Vault) cannot be auto-initialized/unsealed when using file
|
|
storage without a KMS auto-unseal mechanism, so this part is a manual,
|
|
one-time step per environment:
|
|
|
|
1. Deploy this chart (via ArgoCD, see `apps-in-apps`) - or locally:
|
|
|
|
```sh
|
|
helm dependency update .
|
|
helm upgrade --install openbao . -n openbao --create-namespace
|
|
```
|
|
|
|
2. Initialize OpenBao (**save the unseal keys and root token securely**,
|
|
e.g. in a password manager - they are NOT stored anywhere in git):
|
|
|
|
```sh
|
|
kubectl exec -n openbao -it openbao-0 -- bao operator init
|
|
```
|
|
|
|
3. Unseal (repeat with 3 of the 5 unseal keys from step 2):
|
|
|
|
```sh
|
|
kubectl exec -n openbao -it openbao-0 -- bao operator unseal
|
|
```
|
|
|
|
4. Store the root token as a Secret so the bootstrap Job can use it:
|
|
|
|
```sh
|
|
kubectl create secret generic openbao-root-token \
|
|
-n openbao --from-literal=token=<root-token-from-step-2>
|
|
```
|
|
|
|
5. Enable the bootstrap Job and re-sync (e.g. `--set bootstrap.enabled=true`
|
|
via the ArgoCD Application's Helm parameters, or in `values.yaml`). It
|
|
enables the KV v2 engine, the Kubernetes auth method, the `eso-read`
|
|
policy and the `eso-role` role bound to the ESO ServiceAccount.
|
|
|
|
6. Confirm the `ClusterSecretStore/openbao` becomes `Valid`:
|
|
|
|
```sh
|
|
kubectl get clustersecretstore openbao -o wide
|
|
```
|
|
|
|
After this, any namespace can create an `ExternalSecret` referencing the
|
|
`openbao` `ClusterSecretStore` to pull secrets from OpenBao's `secret/` KV
|
|
mount.
|
|
|
|
> Note: after a pod restart (upgrade, node reschedule, etc.) OpenBao comes
|
|
> back up **sealed** and must be unsealed again with the keys from step 2
|
|
> unless you later configure an auto-unseal mechanism (e.g. Transit, cloud
|
|
> KMS) - out of scope for this initial setup.
|
|
|
|
## Configuration
|
|
|
|
See [`values.yaml`](values.yaml). Key settings:
|
|
|
|
| Key | Description | Default |
|
|
|---|---|---|
|
|
| `openbao.server.dataStorage.size` | PVC size for OpenBao's data | `10Gi` |
|
|
| `openbao.server.dataStorage.storageClass` | StorageClass, empty = cluster default | `""` |
|
|
| `eso.namespace` / `eso.serviceAccountName` | Where ESO runs and which ServiceAccount to bind | `external-secrets` |
|
|
| `eso.kvMountPath` | KV v2 mount path used by the ClusterSecretStore | `secret` |
|
|
| `bootstrap.enabled` | Toggle the one-time auth/policy bootstrap Job | `false` |
|