Skip to content

Secret Management

Design Principle

ALL secrets are centrally managed via OpenBao. OpenBao is the single source of truth for all credentials in CobaltCore — bootstrap passwords, service credentials, database credentials, Ceph keys, kubeconfigs, TLS certificates, and messaging credentials.

Integration is done via the External Secrets Operator (ESO), which runs in each cluster and reads secrets from OpenBao. Existing operators continue to read Kubernetes Secrets — no code changes to operators needed. PushSecret CRDs write operator-generated secrets (Ceph Keys, Application Credentials) back to OpenBao.

OpenBao Architecture

OpenBao runs as an HA cluster in the Management Cluster (namespace openbao-system):

text
┌─────────────────────────────────────────────────────────────────────────────┐
│                    MANAGEMENT CLUSTER — openbao-system                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐           │
│  │  OpenBao Node 0  │  │  OpenBao Node 1  │  │  OpenBao Node 2  │           │
│  │  (Leader/Standby)│  │  (Standby)       │  │  (Standby)       │           │
│  ├──────────────────┤  ├──────────────────┤  ├──────────────────┤           │
│  │ Raft Storage     │◀─┼──────────────────┼──▶│ Raft Storage    │           │
│  │ Seal: Transit/   │  │ Raft Storage     │  │ Seal: Transit/   │           │
│  │       Auto-Unseal│  │ Seal: Transit/   │  │       Auto-Unseal│           │
│  └──────────────────┘  │       Auto-Unseal│  └──────────────────┘           │
│                        └──────────────────┘                                 │
│                                                                             │
│  Raft Consensus: 3 Replicas, integrated storage                             │
│  Listener: HTTPS (TLS) on Port 8200                                         │
│  Service: openbao.openbao-system.svc.cluster.local                          │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Secret Engines

EngineMount PathPurposeExample Paths
KV v2kv-v2/bootstrap/Bootstrap credentialskv-v2/bootstrap/keystone-admin, kv-v2/bootstrap/service-passwords
KV v2kv-v2/openstack/OpenStack service secretskv-v2/openstack/nova/db, kv-v2/openstack/neutron/config
KV v2kv-v2/infrastructure/Infrastructure credentialskv-v2/infrastructure/mariadb, kv-v2/infrastructure/rabbitmq, kv-v2/infrastructure/valkey
KV v2kv-v2/ceph/Ceph auth keyskv-v2/ceph/client-nova, kv-v2/ceph/client-cinder, kv-v2/ceph/client-glance
PKIpki/TLS certificatespki/issue/openstack-internal, pki/issue/api-external
Databasedatabase/mariadb/Dynamic DB credentials (optional)database/mariadb/creds/nova-rw, database/mariadb/creds/neutron-rw

Auth Methods

Auth MethodMount PathUsageCluster
Kuberneteskubernetes/managementESO, FluxCD in Management ClusterManagement
Kuberneteskubernetes/control-planeESO in Control Plane ClusterControl Plane
Kuberneteskubernetes/hypervisorESO in Hypervisor ClusterHypervisor
Kuberneteskubernetes/storageESO in Storage ClusterStorage
AppRoleapprole/ci-cdCI/CD pipelines for secret provisioningExternal

Policies (Least Privilege)

RoleAllowed PathsCapabilities
eso-control-planekv-v2/data/bootstrap/*, kv-v2/data/openstack/*, kv-v2/data/infrastructure/*, kv-v2/data/ceph/*read
eso-hypervisorkv-v2/data/ceph/client-nova, kv-v2/data/openstack/nova/compute-*read
eso-storagekv-v2/data/ceph/*read, create, update
eso-managementkv-v2/data/bootstrap/*, kv-v2/data/infrastructure/*read
push-ceph-keyskv-v2/data/ceph/*create, update
push-app-credentialskv-v2/data/openstack/*/app-credentialcreate, update
ci-cd-provisionerkv-v2/data/*create, update, read
pki-issuerpki/issue/*create, update

ESO Integration

The External Secrets Operator (ESO) runs in each cluster and synchronizes secrets from OpenBao. ESO uses ClusterSecretStore resources (cluster-wide scope, as opposed to namespace-scoped SecretStore) to define the connection to OpenBao:

text
┌─────────────────────────────────────────────────────────────────────────────┐
│                       ESO INTEGRATION PATTERN                               │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  Per Cluster:                                                               │
│                                                                             │
│  ┌────────────────────────┐     ┌────────────────────────┐                  │
│  │   ClusterSecretStore   │     │    ExternalSecret      │                  │
│  │   ───────────────────  │     │    ──────────────      │                  │
│  │   provider: vault      │     │    secretStoreRef:     │                  │
│  │   server: https://     │◀────│      clusterStore      │                  │
│  │     openbao.mgmt:8200  │     │    target:             │                  │
│  │   auth:                │     │      name: <k8s-sec>   │                  │
│  │     kubernetes:        │     │    data:               │                  │
│  │       mountPath: ...   │     │      - remoteRef:      │                  │
│  │       role: eso-<cls>  │     │          key: <path>   │                  │
│  └────────────────────────┘     └────────────────────────┘                  │
│                                                                             │
│  ┌────────────────────────┐                                                 │
│  │     PushSecret         │     (Return channel: K8s Secret → OpenBao)      │
│  │     ──────────         │                                                 │
│  │     selector:          │                                                 │
│  │       name: <k8s-sec>  │                                                 │
│  │     data:              │                                                 │
│  │       - match:         │                                                 │
│  │          remoteRef:    │                                                 │
│  │            remoteKey:  │                                                 │
│  │              <vaultpath>                                                 │
│  └────────────────────────┘                                                 │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Complete Secret Inventory

Secret TypeOpenBao PathEngineConsumer(s)Cluster
Keystone Admin Passwordkv-v2/bootstrap/keystone-adminKV v2Keystone Bootstrap JobControl Plane
Service User Passwordskv-v2/bootstrap/service-passwordsKV v2c5c3-operatorControl Plane
K-ORC Service User Passwordkv-v2/openstack/k-orc/credentialsKV v2c5c3-operator (creates Keystone User)Control Plane
MariaDB Root Credentialskv-v2/infrastructure/mariadbKV v2MariaDB OperatorControl Plane
RabbitMQ Credentialskv-v2/infrastructure/rabbitmqKV v2RabbitMQ OperatorControl Plane
Valkey Authkv-v2/infrastructure/valkeyKV v2Valkey OperatorControl Plane
Nova DB Credentialskv-v2/openstack/nova/dbKV v2Nova APIControl Plane
Neutron DB Credentialskv-v2/openstack/neutron/dbKV v2Neutron APIControl Plane
Glance DB Credentialskv-v2/openstack/glance/dbKV v2Glance APIControl Plane
Cinder DB Credentialskv-v2/openstack/cinder/dbKV v2Cinder APIControl Plane
Nova Application Credentialkv-v2/openstack/nova/app-credentialKV v2nova-operator (via c5c3-operator)Control Plane
Neutron Application Credentialkv-v2/openstack/neutron/app-credentialKV v2neutron-operator (via c5c3-operator)Control Plane
Glance Application Credentialkv-v2/openstack/glance/app-credentialKV v2glance-operator (via c5c3-operator)Control Plane
Cinder Application Credentialkv-v2/openstack/cinder/app-credentialKV v2cinder-operator (via c5c3-operator)Control Plane
Placement Application Credentialkv-v2/openstack/placement/app-credentialKV v2placement-operator (via c5c3-operator)Control Plane
K-ORC Application Credentialkv-v2/openstack/k-orc/app-credentialKV v2K-ORC ControllerControl Plane
Cortex Application Credentialkv-v2/openstack/cortex/app-credentialKV v2CortexControl Plane
Ceph Client Key (Nova)kv-v2/ceph/client-novaKV v2Nova Compute, Hypervisor Node AgentHypervisor
Ceph Client Key (Cinder)kv-v2/ceph/client-cinderKV v2Cinder VolumeControl Plane
Ceph Client Key (Glance)kv-v2/ceph/client-glanceKV v2Glance APIControl Plane
Nova Compute Credentialskv-v2/openstack/nova/compute-configKV v2Nova Compute AgentHypervisor
OVN Configkv-v2/openstack/ovn/configKV v2ovn-controllerHypervisor
Kubeconfig Control Planekv-v2/infrastructure/kubeconfig-cpKV v2FluxCDManagement
Kubeconfig Hypervisorkv-v2/infrastructure/kubeconfig-hvKV v2FluxCDManagement
Kubeconfig Storagekv-v2/infrastructure/kubeconfig-stKV v2FluxCDManagement
TLS Certificatespki/issue/openstack-internalPKIOpenStack APIsControl Plane

Multi-Cluster Secret Distribution

text
┌─────────────────────────────────────────────────────────────────────────────┐
│                  MULTI-CLUSTER SECRET DISTRIBUTION                          │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│                    ┌─────────────────────────┐                              │
│                    │      OpenBao            │                              │
│                    │  (Management Cluster)   │                              │
│                    │                         │                              │
│                    │  kv-v2/bootstrap/*      │                              │
│                    │  kv-v2/openstack/*      │                              │
│                    │  kv-v2/infrastructure/* │                              │
│                    │  kv-v2/ceph/*           │                              │
│                    │  pki/*                  │                              │
│                    └───┬─────┬─────┬─────────┘                              │
│                        │     │     │                                        │
│               ┌────────┘     │     └────────┐                               │
│               │              │              │                               │
│               ▼              ▼              ▼                               │
│  ┌────────────────┐ ┌────────────────┐ ┌────────────────┐                   │
│  │ ESO            │ │ ESO            │ │ ESO            │                   │
│  │ Control Plane  │ │ Hypervisor     │ │ Storage        │                   │
│  ├────────────────┤ ├────────────────┤ ├────────────────┤                   │
│  │ ExternalSecret │ │ ExternalSecret │ │ PushSecret     │                   │
│  │ → K8s Secrets: │ │ → K8s Secrets: │ │ (Ceph Keys →  │                    │
│  │  - DB Creds    │ │  - Ceph Keys   │ │  OpenBao)      │                   │
│  │  - SvcPasswords│ │  - Nova Config │ │                │                   │
│  │  - AppCreds    │ │  - OVN Config  │ │ ExternalSecret │                   │
│  │  - Ceph Keys   │ │                │ │ → K8s Secrets: │                   │
│  └────────────────┘ └────────────────┘ │  - Ceph Config │                   │
│                                        └────────────────┘                   │
│                                                                             │
│  ESO in Management Cluster itself:                                          │
│  ExternalSecret → K8s Secrets: Kubeconfigs, FluxCD Secrets                  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Ceph Key Flow

The flow for Ceph credentials from Rook Operator via OpenBao to the Libvirt daemon:

text
┌─────────────────────────────────────────────────────────────────────────────┐
│                    CEPH KEY FLOW (via OpenBao)                              │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  STORAGE CLUSTER                                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │ 1. Rook Operator creates CephClient + K8s Secret                    │    │
│  │    Secret: rook-ceph-client-openstack-nova (key: AQBxxxx==)         │    │
│  │                                                                     │    │
│  │ 2. PushSecret writes key to OpenBao                                 │    │
│  │    PushSecret → kv-v2/ceph/client-nova                              │    │
│  └───────────────────────────────┬─────────────────────────────────────┘    │
│                                  │                                          │
│                                  ▼                                          │
│  MANAGEMENT CLUSTER                                                         │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │ 3. OpenBao stores Ceph key                                          │    │
│  │    Path: kv-v2/data/ceph/client-nova                                │    │
│  └───────────────────────────────┬─────────────────────────────────────┘    │
│                                  │                                          │
│                                  ▼                                          │
│  HYPERVISOR CLUSTER                                                         │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │ 4. ESO ExternalSecret reads from OpenBao                            │    │
│  │    → Creates K8s Secret: ceph-client-nova (namespace: openstack)    │    │
│  │                                                                     │    │
│  │ 5. Nova Compute DaemonSet mounts secret                             │    │
│  │    → /etc/ceph/ceph.client.nova.keyring                             │    │
│  │                                                                     │    │
│  │ 6. Hypervisor Node Agent creates Libvirt Secret on each node        │    │
│  │    → virsh secret-define + virsh secret-set-value                   │    │
│  │                                                                     │    │
│  │ 7. Libvirt uses secret for RBD access                               │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Bootstrap Sequence

The bootstrap sequence with OpenBao as central secret store:

PhaseDescriptionSecret Source
Phase 0Initialize OpenBao, Unseal, configure Secret Engines + Auth MethodsManual / CI-CD
Phase 1Write bootstrap secrets to OpenBao (Admin PW, Service Passwords)CI-CD → OpenBao
Phase 2Deploy ESO in all clusters, configure ClusterSecretStoresFluxCD
Phase 3ESO creates K8s Secrets from OpenBao in all clustersESO → OpenBao
Phase 4Infrastructure Operators start (MariaDB, RabbitMQ, Valkey)K8s Secrets
Phase 5Keystone Bootstrap with Admin credentials from OpenBaoK8s Secrets
Phase 6c5c3-operator creates Keystone Services, Endpoints, Service Users, Application Credentials (via K-ORC)Keystone API
Phase 7PushSecrets write generated credentials back to OpenBaoPushSecret → OpenBao
Phase 8ESO distributes all secrets to target clusters, services startESO → K8s Secrets

Credential Rotation

OpenBao KV v2 supports versioned secrets. In combination with the CredentialRotation CRD of the c5c3-operator:

  • Versioned Secrets: OpenBao KV v2 stores all secret versions with metadata
  • ESO Refresh: ExternalSecrets have a configurable refreshInterval (default: 1h)
  • Rotation Flow: Write new secret to OpenBao → ESO updates K8s Secret → Pods receive new secret via Secret watch or rolling update
  • CredentialRotation CRD: The c5c3-operator automatically rotates Application Credentials based on schedule and grace period

For the CRD definitions of SecretAggregate and CredentialRotation, see CRDs.

Further Reading