Introduction
Every application needs secrets: database passwords, API keys, TLS certificates, tokens. On Kubernetes the quickest path is to drop them into environment variables, a ConfigMap, or a Secret checked into Git. Each of those leaks credentials somewhere they shouldn’t be.
This tutorial explains the problem and the pattern that solves it: a dedicated secrets manager holding the real secrets, and an operator that syncs them into the Kubernetes Secrets your apps already know how to read.
Why Kubernetes Secrets alone fall short
A Kubernetes Secret is a useful primitive, with real limits:
- It is only base64-encoded. Secret values sit in etcd as base64, which anyone with cluster or etcd access can decode unless you separately enable encryption at rest.
- It lives in Git if you GitOps it. Committing a
Secretmanifest puts the credential in version history for anyone with repo access. - It does not rotate. A
Secretholds a static value. Rotating the underlying credential means editing and re-applying the manifest by hand. - There is no audit trail. Kubernetes does not record who read which secret value.
For a single throwaway app these are tolerable. Across a platform with many teams and real credentials, they become a liability.
A secrets manager plus a sync operator
The widely used answer pairs two open-source tools.
OpenBao is the secrets manager. A fork of HashiCorp Vault hosted by the Linux Foundation, it stores the real secrets in one encrypted, access-controlled, audited place, with a key/value store, dynamic secrets, fine-grained policies, and an audit log.
The External Secrets Operator (ESO) is the sync layer. It reads from a backend like OpenBao and creates ordinary Kubernetes Secret objects for your workloads. Your application keeps reading a normal Secret, and the operator keeps it in step with the source.
The flow looks like this:
OpenBao (source of truth) -> External Secrets Operator -> Kubernetes Secret -> your Pod
What you get
- Credentials stay out of Git and manifests. Your repo holds an
ExternalSecretthat references a path, never the secret value. - One audited, access-controlled source. Policies decide who and what can read each secret, and reads are logged.
- Rotation propagates. Update the value in OpenBao and ESO re-syncs the Kubernetes
Secreton its refresh interval. - Apps stay unchanged. Workloads consume a standard
Secret, so nothing in the application has to know about OpenBao.
What’s next
The rest of this series is hands-on. You will install OpenBao on a Kubernetes cluster, store and read secrets with it, and then wire up the External Secrets Operator to sync those secrets into your workloads.
Next in this series: Installing OpenBao on Kubernetes.
Summary
- A Kubernetes
Secretis base64-encoded, static, un-audited, and ends up in Git when you GitOps it. - A secrets manager (OpenBao) keeps the real secrets in one encrypted, policy-controlled, audited place.
- The External Secrets Operator syncs secrets from OpenBao into ordinary Kubernetes
Secretobjects. - Your manifests reference a path, your apps read a normal
Secret, and rotation flows through automatically.
