OpenBao will have separate auth mount points – one per cluster.
kubectl -n openbao exec -it vmkube-1-openbao-0 -- env VAULT_TOKEN=<root-token> bao auth enable -path=vmkube-1 kubernetes
kubectl -n openbao exec -it vmkube-1-openbao-0 -- env VAULT_TOKEN=<root-token> bao auth enable -path=vmkube-2 kubernetesSince OpenBao is inside vmkube-1, it can use the in-cluster service account to talk to the Kubernetes API.
# Run this from a pod in vmkube-1 (or use a token with appropriate permissions)
kubectl -n openbao exec -it vmkube-1-openbao-0 -- \
sh -c "export VAULT_TOKEN=<root-token>; \
bao write auth/vmkube-1/config \
kubernetes_host='https://kubernetes.default.svc.cluster.local' \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
token_reviewer_jwt=\"\$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\""For the remote cluster, you need to provide OpenBao with credentials to call its Kubernetes API (to validate JWTs).
Service account is already created in vmkube-2 with permission to create tokenreviews.
Get a token for this service account, vmkube-2 api endpoint and ca cert:
kubectl config use-context admin@vmkube-2
export VMKUBE_2_OPENBAO_TOKEN=$(kubectl get secret openbao-auth-delegator-token -n external-secrets -o jsonpath='{.data.token}' | base64 -d)
export VMKUBE_2_API_ENDPOINT=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
kubectl config view --raw --minify -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 -d > vmkube-2-ca.crtThen configure the auth method in OpenBao:
kubectl config use-context admin@vmkube-1
kubectl cp vmkube-2-ca.crt openbao/vmkube-1-openbao-0:/tmp/vmkube-2-ca.crt
kubectl -n openbao exec -it vmkube-1-openbao-0 -- env VAULT_TOKEN=<root-token> bao write auth/vmkube-2/config \
kubernetes_host="$VMKUBE_2_API_ENDPOINT" \
kubernetes_ca_cert=@/tmp/vmkube-2-ca.crt \
token_reviewer_jwt="$VMKUBE_2_OPENBAO_TOKEN"First, create a policy that grants read access to your secrets (e.g., at path kv/data/*):
kubectl -n openbao exec -it vmkube-1-openbao-0 -- env VAULT_TOKEN=<root-token> bao policy write eso-reader - <<EOF
path "kv/data/*" {
capabilities = ["read"]
}
EOFThen create a role for each cluster that binds the service account external-secrets (the default service account used by ESO) to the policy.
For vmkube-1:
kubectl -n openbao exec -it vmkube-1-openbao-0 -- env VAULT_TOKEN=<root-token> bao write auth/vmkube-1/role/eso-role \
bound_service_account_names="vmkube-1-external-secrets" \
bound_service_account_namespaces="*" \
policies="eso-reader" \
ttl="1h"For vmkube-2:
kubectl -n openbao exec -it vmkube-1-openbao-0 -- env VAULT_TOKEN=<root-token> bao write auth/vmkube-2/role/eso-role \
bound_service_account_names="vmkube-2-external-secrets" \
bound_service_account_namespaces="*" \
policies="eso-reader" \
ttl="1h"kubectl -n openbao exec -it vmkube-1-openbao-0 -- env VAULT_TOKEN=<root-token> bao secrets enable -path=kv -version=2 kvNote: Be consistent with the version – external-secrets expects
v2by default. If you usev1, you must setversion: v1in the SecretStore.
Push a test secret to OpenBao:
kubectl -n openbao exec -it vmkube-1-openbao-0 -- env VAULT_TOKEN=<root-token> bao kv put kv/mysecret password=123kubectl apply -f - <<EOF
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: test
spec:
secretStoreRef:
name: openbao-store
kind: ClusterSecretStore
target:
name: test-secret
data:
- secretKey: password
remoteRef:
key: mysecret
property: password
EOFAfter applying the ExternalSecret, check that a Kubernetes secret test-secret is created.