OpenBao Secrets Management:

OpenBao: complete gids voor secrets management op Kubernetes

OpenBao is een open-source secrets management platform β€” een community-driven fork van HashiCorp Vault, beheerd door de Linux Foundation. Waar Vault in 2023 overstapte naar een commerciΓ«le licentie (BSL), bleef OpenBao volledig open-source onder de Mozilla Public License 2.0. Voor organisaties die secrets centraal willen beheren in Kubernetes en OpenShift-omgevingen, is OpenBao een krachtig alternatief dat actief wordt doorontwikkeld.

Wat is secrets management en waarom heb je het nodig?

In moderne cloud-native omgevingen heb je overal geheimen nodig: database-wachtwoorden, API-sleutels, TLS-certificaten, SSH-sleutels. De verkeerde aanpak is deze secrets hardcoded in configuratiebestanden of environment variables op te slaan β€” zeker niet in Git.

OpenBao lost dit op door een centrale, beveiligde opslag te bieden met:

  • Versleutelde opslag β€” secrets worden versleuteld opgeslagen, nooit als plain tekst
  • Dynamische secrets β€” tijdelijke, automatisch roterende credentials (bijv. database-wachtwoorden die na 1 uur verlopen)
  • Fine-grained access control β€” elke applicatie krijgt alleen de secrets waar het recht op heeft
  • Audit logging β€” volledig overzicht van wie welk secret heeft opgevraagd
  • Lease management β€” secrets verlopen automatisch, geen lang-levende credentials

Architectuur en kernconcepten

De vier stappen van OpenBao

  1. Authenticatie β€” wie ben je? (Kubernetes ServiceAccount, LDAP, OIDC, AppRole)
  2. Validatie β€” wat mag je? (policies bepalen toegang tot paths)
  3. Autorisatie β€” toegang verlenen via een token met gekoppelde policies
  4. Secret ophalen β€” de applicatie leest het secret via de API

Secrets engines

  • KV (Key-Value) β€” eenvoudige statische secrets opslag, versie 1 (geen history) of versie 2 (met history)
  • PKI β€” dynamische TLS-certificaten genereren, fungeert als Certificate Authority
  • Database β€” dynamische database-credentials genereren voor PostgreSQL, MySQL, MongoDB etc.
  • SSH β€” tijdelijke SSH-sleutels of OTP’s genereren
  • Transit β€” versleuteling als dienst (encrypt/decrypt zonder het secret zelf op te slaan)
  • TOTP β€” time-based one-time passwords genereren

Auth methoden

  • Kubernetes β€” ServiceAccount tokens, ideaal voor Kubernetes/OpenShift deployments
  • AppRole β€” machine-to-machine authenticatie voor CI/CD pipelines
  • OIDC β€” gebruikersauthenticatie via Keycloak, Azure AD, Okta
  • LDAP β€” Active Directory of OpenLDAP integratie
  • Token β€” directe token-authenticatie (voor beheer)

OpenBao installeren op Kubernetes met Helm

# Voeg de OpenBao Helm repository toe
helm repo add openbao https://openbao.github.io/openbao-helm
helm repo update

# Namespace aanmaken
kubectl create namespace openbao

# Installeren in dev-modus (niet voor productie)
helm install openbao openbao/openbao \
  --namespace openbao \
  --set "server.dev.enabled=true" \
  --set "server.dev.devRootToken=root"

# Status controleren
kubectl get pods -n openbao

# Port-forward voor lokale toegang
kubectl port-forward svc/openbao 8200:8200 -n openbao

Productie-installatie met Raft storage (HA)

# values.yaml voor productie
server:
  ha:
    enabled: true
    replicas: 3
    raft:
      enabled: true
      setNodeId: true

  affinity: |
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchLabels:
              app.kubernetes.io/name: openbao
          topologyKey: kubernetes.io/hostname

  resources:
    requests:
      memory: 256Mi
      cpu: 250m
    limits:
      memory: 512Mi
      cpu: 500m

  ingress:
    enabled: true
    hosts:
      - host: openbao.voorbeeld.nl
        paths: ["/"]
    tls:
      - secretName: openbao-tls
        hosts: ["openbao.voorbeeld.nl"]

ui:
  enabled: true

injector:
  enabled: true  # Sidecar injector voor automatische secret-injectie

Initialiseren en unsealen

# OpenBao initialiseren (eenmalig)
kubectl exec -n openbao openbao-0 -- bao operator init \
  -key-shares=5 \
  -key-threshold=3

# Dit geeft 5 unseal keys en 1 root token
# Bewaar deze VEILIG en VERSPREID (bijv. in aparte kluis per beheerder)
# Unseal key 1: abc123...
# Unseal key 2: def456...
# Root token: hvs.xyz789...

# Unsealen (3 van de 5 keys nodig)
kubectl exec -n openbao openbao-0 -- bao operator unseal abc123...
kubectl exec -n openbao openbao-0 -- bao operator unseal def456...
kubectl exec -n openbao openbao-0 -- bao operator unseal ghi789...

# Status controleren
kubectl exec -n openbao openbao-0 -- bao status

Auto-unseal met een externe KMS (aanbevolen voor productie)

# values.yaml fragment voor auto-unseal met AWS KMS
server:
  extraEnvironmentVars:
    VAULT_SEAL_TYPE: awskms
    AWS_REGION: eu-west-1
    VAULT_AWSKMS_SEAL_KEY_ID: arn:aws:kms:eu-west-1:123456789:key/abc-def

# Of met Azure Key Vault
server:
  extraEnvironmentVars:
    VAULT_SEAL_TYPE: azurekeyvault
    AZURE_TENANT_ID: tenant-id
    AZURE_CLIENT_ID: client-id
    AZURE_CLIENT_SECRET: client-secret
    VAULT_AZUREKEYVAULT_VAULT_NAME: mijn-keyvault
    VAULT_AZUREKEYVAULT_KEY_NAME: openbao-unseal-key

CLI-basiscommando’s

# Omgevingsvariabelen instellen
export BAO_ADDR=https://openbao.voorbeeld.nl
export BAO_TOKEN=hvs.roottoken123

# Inloggen
bao login hvs.roottoken123

# Status bekijken
bao status

# Secrets engine inschakelen
bao secrets enable -path=geheimen kv-v2

# Secret opslaan
bao kv put geheimen/database \
  gebruikersnaam=admin \
  wachtwoord=GeheimWachtwoord123

# Secret opvragen
bao kv get geheimen/database

# Specifiek veld opvragen
bao kv get -field=wachtwoord geheimen/database

# Versiegeschiedenis bekijken (KV v2)
bao kv metadata get geheimen/database

# Specifieke versie opvragen
bao kv get -version=2 geheimen/database

# Secret verwijderen (soft delete)
bao kv delete geheimen/database

# Secret permanent verwijderen
bao kv destroy -versions=1,2 geheimen/database

Kubernetes integratie β€” de juiste manier

Kubernetes auth methode configureren

# Kubernetes auth inschakelen
bao auth enable kubernetes

# Configureren (vanuit binnen het cluster)
bao write auth/kubernetes/config \
  kubernetes_host="https://kubernetes.default.svc:443" \
  kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
  token_reviewer_jwt=@/var/run/secrets/kubernetes.io/serviceaccount/token

# Policy aanmaken
bao policy write mijn-app-policy - <

Secrets via de sidecar injector (aanbevolen)

# Deployment met automatische secret-injectie
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mijn-app
  namespace: productie
spec:
  template:
    metadata:
      annotations:
        # Injectie inschakelen
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/role: "mijn-app"

        # Secret injecteren als bestand
        vault.hashicorp.com/agent-inject-secret-database: "geheimen/data/mijn-app/database"

        # Template voor de injectie (optioneel, voor specifiek formaat)
        vault.hashicorp.com/agent-inject-template-database: |
          {{- with secret "geheimen/data/mijn-app/database" -}}
          export DB_USER="{{ .Data.data.gebruikersnaam }}"
          export DB_PASS="{{ .Data.data.wachtwoord }}"
          {{- end -}}
    spec:
      serviceAccountName: mijn-app-sa
      containers:
      - name: mijn-app
        image: mijn-app:1.0.0
        # Secret beschikbaar als /vault/secrets/database

Secrets via de Vault Secrets Operator (moderne aanpak)

# VaultStaticSecret resource
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
  name: database-secret
  namespace: productie
spec:
  type: kv-v2
  mount: geheimen
  path: mijn-app/database
  destination:
    name: database-secret  # Wordt een gewoon Kubernetes Secret
    create: true
  refreshAfter: 30s
  vaultAuthRef: openbao-auth

PKI secrets engine β€” dynamische TLS-certificaten

# PKI engine inschakelen
bao secrets enable pki

# Maximum TTL instellen
bao secrets tune -max-lease-ttl=8760h pki

# Root CA genereren
bao write pki/root/generate/internal \
  common_name="Voorbeeld Root CA" \
  ttl=8760h

# Intermediate CA aanmaken
bao secrets enable -path=pki_int pki
bao secrets tune -max-lease-ttl=4380h pki_int

# CSR genereren voor intermediate
bao write pki_int/intermediate/generate/internal \
  common_name="Voorbeeld Intermediate CA" \
  | jq -r '.data.csr' > intermediate.csr

# Ondertekenen met root CA
bao write pki/root/sign-intermediate \
  csr=@intermediate.csr \
  format=pem_bundle \
  ttl=4380h \
  | jq -r '.data.certificate' > intermediate.cert.pem

# Ondertekend certificaat importeren
bao write pki_int/intermediate/set-signed \
  certificate=@intermediate.cert.pem

# Rol aanmaken voor certificaatuitgifte
bao write pki_int/roles/server-cert \
  allowed_domains="voorbeeld.nl" \
  allow_subdomains=true \
  max_ttl=720h

# Certificaat uitschrijven
bao write pki_int/issue/server-cert \
  common_name="api.voorbeeld.nl" \
  ttl=720h

Database secrets engine β€” dynamische credentials

# Database engine inschakelen
bao secrets enable database

# PostgreSQL configureren
bao write database/config/mijn-db \
  plugin_name=postgresql-database-plugin \
  allowed_roles="app-rol" \
  connection_url="postgresql://{{username}}:{{password}}@postgres:5432/mijndb" \
  username="openbao-beheer" \
  password="BeheerWachtwoord"

# Rol aanmaken (dynamische gebruiker met TTL)
bao write database/roles/app-rol \
  db_name=mijn-db \
  creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT, INSERT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
  revocation_statements="DROP ROLE IF EXISTS \"{{name}}\";" \
  default_ttl=1h \
  max_ttl=24h

# Dynamische credentials opvragen
bao read database/creds/app-rol
# Output:
# Key      Value
# ---      -----
# username  v-root-app-rol-AbCdEf
# password  A1b2C3d4-tijdelijkeCredential

OpenBao op OpenShift deployen

# OpenShift vereist extra machtigingen voor de injector
oc create namespace openbao
oc adm policy add-scc-to-user anyuid -z openbao -n openbao
oc adm policy add-scc-to-user anyuid -z openbao-agent-injector -n openbao

# Helm installatie voor OpenShift
helm install openbao openbao/openbao \
  --namespace openbao \
  --set "global.openshift=true" \
  --set "server.route.enabled=true" \
  --set "server.route.host=openbao.apps.cluster.voorbeeld.nl"

# Route controleren
oc get route -n openbao

Audit logging instellen

# File audit log inschakelen
bao audit enable file file_path=/bao/logs/audit.log

# Syslog audit inschakelen
bao audit enable syslog tag="openbao" facility="AUTH"

# Audit logs bekijken (elk request en response wordt gelogd)
kubectl exec -n openbao openbao-0 -- cat /bao/logs/audit.log | jq '.'

OpenBao vs HashiCorp Vault

EigenschapOpenBaoHashiCorp Vault
LicentieMozilla Public License 2.0 (open-source)Business Source License (commercieel)
BeheerLinux Foundation communityHashiCorp / IBM
API-compatibiliteitVolledig compatibel met Vault APIβ€”
KostenGratisGratis tot bepaalde schaal, daarna Enterprise
Enterprise featuresWorden stapsgewijs open-source gemaaktAchter betaalmuur
Migratie van VaultDrop-in replacement, zelfde APIβ€”

Veelgestelde vragen

Is OpenBao een drop-in replacement voor Vault?

Ja β€” OpenBao gebruikt dezelfde API als HashiCorp Vault en is volledig achterwaarts compatibel. Bestaande Vault-clients, Terraform-providers en Kubernetes-integraties werken zonder aanpassingen op OpenBao. Alleen de CLI-commandonaam verschilt: vault is vervangen door bao.

Wat is het verschil tussen OpenBao en Kubernetes Secrets?

Kubernetes Secrets zijn base64-gecodeerde waarden opgeslagen in etcd β€” ze zijn standaard niet versleuteld en iedereen met cluster-admin rechten kan ze inzien. OpenBao versleutelt alles, biedt dynamische secrets, fine-grained toegangscontrole en audit logging. OpenBao vervangt Kubernetes Secrets niet volledig, maar is complementair: de meeste organisaties gebruiken OpenBao als de centrale bron en injecteren secrets dynamisch in Kubernetes workloads.

Hoe verhoudt OpenBao zich tot External Secrets Operator?

External Secrets Operator (ESO) is een Kubernetes-operator die secrets synchroniseert vanuit externe bronnen (AWS Secrets Manager, Azure Key Vault, Google Secret Manager) naar Kubernetes Secrets. OpenBao is zelf een secrets-store. ESO ondersteunt ook OpenBao/Vault als bron β€” je kunt beide combineren: OpenBao als centrale secrets-store, ESO om die secrets te synchroniseren naar Kubernetes Secrets.