MHRubel
HomeAboutProjectsSkillsExperienceBlogContact
MHRubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Software EngineeringTechnologyJune 18, 20263 min read

Automating Kubernetes Secrets: Using HashiCorp Vault and ESO

Learn how to automate Kubernetes secrets using HashiCorp Vault and the External Secrets Operator. Secure your infrastructure with this DevSecOps best practice.

KubernetesHashiCorp VaultExternal Secrets OperatorDevSecOpsAutomationSecurityDevOpsLinuxServer

Managing secrets in Kubernetes is a headache. If you’re still manually creating Secret objects or base64-encoding YAML files in your Git repositories, you’re doing it wrong. It’s a security risk, it’s unscalable, and frankly, it’s a manual process that doesn't belong in a modern CI/CD pipeline.

I’ve spent the last few years refining our DevSecOps posture, and the gold standard remains the same: use a dedicated secret manager like HashiCorp Vault and bridge it to Kubernetes using the External Secrets Operator (ESO).

Why bother with External Secrets Operator?

Kubernetes Secrets are just base64-encoded strings stored in etcd. Anyone with cluster-admin access—or even a compromised pod with the right RBAC—can read your production database credentials.

HashiCorp Vault provides encryption-at-rest, audit logging, and dynamic secret generation. But Vault doesn't natively speak "Kubernetes Secret." That’s where the External Secrets Operator (ESO) comes in. It acts as the glue, watching for custom resources in your cluster and pulling the latest values from Vault to inject them as native Kubernetes secrets.

The Setup

We’ll assume you have a running Kubernetes cluster (v1.27+) and a functional HashiCorp Vault instance (v1.14+).

1. Install ESO

I recommend using Helm for this. It’s the standard, it’s reliable, and it’s easy to version-control.

Bash
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets \
   external-secrets/external-secrets \
    -n external-secrets \
    --create-namespace

2. Configure the SecretStore

The SecretStore is a namespaced resource that tells ESO how to talk to Vault. We need to authenticate using a Kubernetes ServiceAccount.

YAML
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
spec:
  provider:
    vault:
      server: "https://vault.example.com:8200"
      path: "secret"
      version: "v2"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "my-app-role"

3. Defining the ExternalSecret

This is where the magic happens. You define an ExternalSecret object that maps a key in Vault to a specific key in a Kubernetes Secret.

YAML
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
spec:
  refreshInterval: "1h"
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: app-db-secret # The resulting K8s secret
  data:
  - secretKey: username
    remoteRef:
      key: secret/data/myapp/db
      property: username
  - secretKey: password
    remoteRef:
      key: secret/data/myapp/db
      property: password

Pro-Tips from the Trenches

When you’re implementing this, keep these three lessons in mind:

1. Use Namespace Scoping Don't use a ClusterSecretStore unless you absolutely have to. By sticking to namespaced SecretStore objects, you enforce the principle of least privilege. If one namespace is compromised, the attacker can't necessarily pull secrets from the entire Vault instance.

2. Watch the Refresh Interval ESO defaults to a refresh interval of 1 hour. In a high-security environment, you might be tempted to set this to 30 seconds. Don't. You’ll hammer your Vault API unnecessarily. If you need secrets to rotate instantly, look into the Vault Agent Injector instead, though it’s a different architecture.

3. RBAC is your best friend The ServiceAccount used by ESO needs specific permissions in Vault. Ensure you’ve mapped your Kubernetes ServiceAccount to a Vault policy that only grants read access to the specific paths the application needs. Never give the operator "root" access to your secret engines.

Why this is the Future

By automating Kubernetes secrets, we remove the human element. No more copy-pasting API keys into Slack or pasting them into YAML files. Everything is defined as code. If we need to rotate the database password, we update it in Vault, and within an hour, the cluster updates itself.

This is what DevSecOps is really about: building systems that are secure by default, not by manual checklist.

Back to Blog

Similar Posts

Software EngineeringJune 19, 20263 min read

HashiCorp Vault and External Secrets Operator: Secure Kubernetes Secrets

Master HashiCorp Vault and External Secrets Operator to automate your Kubernetes secrets management. Learn how to sync sensitive data securely in your cluster.

Read more
Software EngineeringJune 19, 20263 min read

Kubernetes Secret Management: Using External Secrets and HashiCorp Vault

Master Kubernetes Secret Management by syncing HashiCorp Vault with External Secrets Operator. Learn how to automate secure, GitOps-friendly secret injection.

Read more
TechnologyJune 19, 20263 min read

Kubernetes Security Auditing: Automating Trivy with Admission Controllers

Master Kubernetes security auditing by automating Trivy scans with admission controllers. Prevent vulnerable container images from deploying to your cluster.

Read more