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 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.

HashiCorp VaultKubernetesExternal Secrets OperatorDevSecOpsSecret ManagementInfrastructure as CodeCloud NativeDevOpsLinuxServer

Managing secrets in Kubernetes is a constant pain point. If you’re manually creating Kubernetes Secrets or—heaven forbid—committing base64-encoded strings to Git, you’re doing it wrong. I’ve spent years cleaning up these messes. The industry standard isn't just "encrypting at rest"; it's about centralizing your secrets in a dedicated vault and syncing them into your clusters on demand.

In this post, we’re going to set up HashiCorp Vault as our source of truth and use the External Secrets Operator (ESO) to inject those secrets directly into Kubernetes.

Why External Secrets Operator?

Kubernetes native secrets are just base64-encoded strings stored in etcd. They aren't truly secure. By using HashiCorp Vault, you get audit logs, rotation policies, and fine-grained access control. ESO acts as the bridge; it polls Vault and creates native Kubernetes Secret objects, meaning your applications don't need to change their code to talk to Vault.

Prerequisites

  • A running Kubernetes cluster (v1.24+)
  • A HashiCorp Vault instance (v1.12+)
  • Helm installed

Step 1: Installing the External Secrets Operator

We’ll install ESO using Helm. It’s the most straightforward path.

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

Once installed, verify the pods are running with kubectl get pods -n external-secrets. You should see the controller and the webhook pods up and ready.

Step 2: Configure Vault Authentication

ESO needs a way to talk to Vault. The cleanest way is using Kubernetes ServiceAccount tokens.

First, enable the Kubernetes auth method in Vault:

Bash
vault auth enable kubernetes

Configure the auth path to point to your Kubernetes cluster:

Bash
vault write auth/kubernetes/config \
    kubernetes_host="https://<YOUR_K8S_API_URL>"

Now, create a role in Vault that maps a Kubernetes ServiceAccount to a Vault policy.

Step 3: Create the SecretStore

The SecretStore is a namespaced resource that tells ESO how to connect to Vault.

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: "eso-role"

Apply this with kubectl apply -f secretstore.yaml. Ensure the status is Ready by running kubectl get secretstore.

Step 4: Syncing Secrets with ExternalSecret

Now for the magic. We define an ExternalSecret resource that tells ESO which keys to fetch from Vault and how to map them to a local Kubernetes Secret.

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

ESO will now reach out to Vault, pull the value for password from the secret/data/myapp/db path, and create a Kubernetes Secret named db-credentials.

Hard-Won Lessons from Production

I’ve seen teams get this wrong, so keep these three things in mind:

  1. Refresh Intervals: Don't set refreshInterval too low (e.g., every 10 seconds). You’ll hammer your Vault instance unnecessarily. 1h or 5m is usually plenty.
  2. RBAC is Key: Ensure the ServiceAccount ESO uses has the absolute minimum permissions in Vault. Use the principle of least privilege.
  3. Monitoring: Monitor the ESO controller logs. If it fails to sync, it will tell you exactly why (usually a permission issue or a missing secret path).

Final Thoughts

Integrating HashiCorp Vault with External Secrets Operator transforms your secret management from a manual, error-prone task into a robust, automated DevSecOps pipeline. Your developers get the native Kubernetes Secret experience they expect, while your security team gets the centralized control they demand.

It’s a win-win. Stop hardcoding your credentials and start automating today.

Back to Blog

Similar Posts

Software EngineeringJune 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.

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 Disaster Recovery: Velero and Restic Implementation Guide

Master Kubernetes disaster recovery by using Velero and Restic. Learn how to back up persistent volumes and perform cross-cluster restoration like a pro.

Read more