CloudOps Logo
Securing EKS with HashiCorp Vault

Securing EKS with HashiCorp Vault

Por Ruben Quispe Cárdenas3 min de lectura
kubernetesvaultawssecurity

title: "Securing EKS with HashiCorp Vault" date: "2026-03-20" excerpt: "A step-by-step guide to integrating HashiCorp Vault with Amazon EKS for secrets management in production Kubernetes clusters." coverImage: "/images/posts/securing-eks-vault.png" tags: ["kubernetes", "vault", "aws", "security"] language: "en"

Why Vault for Kubernetes Secrets?

Kubernetes Secrets are base64-encoded — not encrypted. Anyone with RBAC access to the namespace can decode them. HashiCorp Vault solves this with:

  • Dynamic secrets with automatic rotation
  • Fine-grained access policies
  • Full audit logging of every secret access
  • Encryption as a service

Never store production secrets as plain Kubernetes Secrets. Use an external secrets manager like Vault, AWS Secrets Manager, or Azure Key Vault.

Architecture Overview

The integration uses the Vault Agent Injector pattern:

  1. Vault runs as an external service (or in-cluster via Helm)
  2. The Vault Agent Injector mutating webhook intercepts pod creation
  3. Secrets are injected as files in a shared volume
  4. Applications read secrets from the filesystem — no SDK needed

Installing Vault via Helm

# vault-values.yaml
server:
  ha:
    enabled: true
    replicas: 3
    raft:
      enabled: true
  dataStorage:
    enabled: true
    size: 10Gi
    storageClass: gp3
  ingress:
    enabled: true
    hosts:
      - host: vault.internal.example.com
injector:
  enabled: true
  replicas: 2
helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
helm install vault hashicorp/vault \
  --namespace vault \
  --create-namespace \
  -f vault-values.yaml

Configuring Kubernetes Auth

resource "vault_auth_backend" "kubernetes" {
  type = "kubernetes"
}
 
resource "vault_kubernetes_auth_backend_config" "eks" {
  backend            = vault_auth_backend.kubernetes.path
  kubernetes_host    = data.aws_eks_cluster.main.endpoint
  kubernetes_ca_cert = base64decode(data.aws_eks_cluster.main.certificate_authority[0].data)
}
 
resource "vault_kubernetes_auth_backend_role" "app" {
  backend                          = vault_auth_backend.kubernetes.path
  role_name                        = "app-role"
  bound_service_account_names      = ["app-sa"]
  bound_service_account_namespaces = ["production"]
  token_ttl                        = 3600
  token_policies                   = ["app-secrets"]
}

The Kubernetes auth method lets pods authenticate to Vault using their service account token — no hardcoded credentials needed.

Injecting Secrets into Pods

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    metadata:
      annotations:
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/role: "app-role"
        vault.hashicorp.com/agent-inject-secret-db-creds: "secret/data/production/db"
        vault.hashicorp.com/agent-inject-template-db-creds: |
          {{- with secret "secret/data/production/db" -}}
          export DB_HOST="{{ .Data.data.host }}"
          export DB_USER="{{ .Data.data.username }}"
          export DB_PASS="{{ .Data.data.password }}"
          {{- end -}}
    spec:
      serviceAccountName: app-sa
      containers:
        - name: app
          image: my-app:latest
          command: ["/bin/sh", "-c", "source /vault/secrets/db-creds && ./start.sh"]

Key Takeaways

  • Vault Agent Injector is the cleanest integration pattern — no application changes needed
  • Kubernetes auth eliminates credential bootstrapping problems
  • Dynamic secrets with TTLs are far more secure than long-lived static credentials
  • Always enable audit logging in Vault for compliance
  • Use Terraform to manage Vault configuration as code

Start with the Agent Injector pattern. It works with any language or framework since secrets are just files on disk.

"Security is not a feature — it's the foundation. Build it in from day one, or pay the price later."