Skip to content

Add OpenBao/ESO PoC for dynamic OpenStack credentials - #1

Open
mikejoh wants to merge 3 commits into
mainfrom
secret0-openbao-eso-poc
Open

Add OpenBao/ESO PoC for dynamic OpenStack credentials#1
mikejoh wants to merge 3 commits into
mainfrom
secret0-openbao-eso-poc

Conversation

@mikejoh

@mikejoh mikejoh commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • Replaces the tutorial's static clouds.yaml username/password with a dynamic broker chain: OpenBao's vault-plugin-secrets-openstack mints short-lived, project-scoped OpenStack Application Credentials from one narrowly-scoped root user (openbao/), instead of a per-cluster user account with a password that never expires.
  • External Secrets Operator (capo-poc/01-external-secret.yaml) pulls those credentials via a VaultDynamicSecret generator, authenticating to OpenBao with its own ServiceAccount token (OpenBao's kubernetes auth method) — no static token for that leg either — and reshapes them into a clouds.yaml Secret.
  • CAPO's OpenStackClusterIdentity (capo-poc/02-cluster-identity.yaml) consumes that Secret; a minimal, infra-only OpenStackCluster/Cluster (capo-poc/03-openstackcluster.yaml, no MachineDeployment/control plane on purpose) proves capo-controller can reconcile real Neutron resources with it.
  • README steps 19-23 + CLAUDE.md updated to document the new openbao/ and capo-poc/ directories and how to run this on top of steps 1-18.

Test plan

Verified end-to-end locally against a real DevStack (see README steps 19-22):

  • bao read openstack/creds/capo-poc-member mints a real Application Credential, confirmed via openstack application credential list
  • the minted credential actually authenticates (openstack network list succeeds using only the minted id/secret)
  • ExternalSecret syncs on first try (SecretSynced), no SecretStore needed
  • OpenStackCluster reaches READY: true, real network/subnet/router/security-group/floating-IP created in the capo-poc project
  • rotation: application_credential_id in the Secret changes every refreshInterval; old credentials disappear from Keystone once their lease expires (Vault-driven revoke)
  • not yet tested: full bootable workload cluster through this identity (needs an image-builder run); Vault-down failure mode

🤖 Generated with Claude Code

Bootstrap the workload cluster kube-proxy-free with a temporary Flannel
overlay, then have ArgoCD install Cilium (kubeProxyReplacement) and run
a one-shot Job that removes Flannel and re-IPs existing pods. Also
syncs k8s-devstack01.yaml to CAPI v1beta2 core kinds and bumps
Kubernetes/clusterctl versions and the HA topology in the README.

Assisted-by: Claude/claude-sonnet-5
…et0)

Replaces the tutorial's static clouds.yaml username/password with a
broker chain: OpenBao's vault-plugin-secrets-openstack mints short-lived,
project-scoped Application Credentials from one narrowly-scoped root
user, External Secrets Operator (authenticating to OpenBao via its own
ServiceAccount token, no static token either) reshapes them into a
clouds.yaml Secret, and CAPO's OpenStackClusterIdentity consumes it.
Verified end-to-end against a real DevStack: minted credentials
authenticate, rotate on refresh, and get revoked in Keystone on expiry;
a minimal OpenStackCluster reconciled real Neutron resources using only
the dynamic credential.

Assisted-by: Claude Code/Sonnet 5
Adds templates/cluster-chart: a Helm chart parameterizing everything the
capo-poc/ manifests hand-wrote (Vault roleset, VaultDynamicSecret,
ExternalSecret, OpenStackClusterIdentity, Cluster/OpenStackCluster) by
cluster name, plus argocd/apps/clusters-appset.yaml so a new cluster is
"add a clusters/<name>.yaml, commit" rather than a manual apply.

The Vault roleset is created by a chart-hooked Job (not a manifest, since
rolesets are a Vault API object) authenticating via a new, dedicated,
write-only OpenBao role (cluster-bootstrapper) — deliberately separate
from ESO's read-only role, which is now widened to a glob so it covers
every cluster without per-cluster edits.

Verified by instantiating a second, independent cluster (capo-poc-2)
through the chart: roleset auto-created, ExternalSecret synced, and a
real second Neutron network/router/security-group came up in DevStack.

Assisted-by: Claude Code/Sonnet 5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant