Kubernetes Secrets Management with External Secrets Operator: Production Guide

External Secrets Operator for Kubernetes Secrets Management

External Secrets Operator Kubernetes integration solves one of the most persistent challenges in container orchestration: managing sensitive configuration data securely. Native Kubernetes Secrets are base64-encoded (not encrypted), stored in etcd, and difficult to rotate. External Secrets Operator (ESO) bridges Kubernetes with enterprise secret management platforms, automatically syncing secrets from AWS Secrets Manager, HashiCorp Vault, Azure Key Vault, and GCP Secret Manager into your clusters.

This guide covers installing and configuring ESO for production environments, including multi-cluster synchronization, automatic rotation, and disaster recovery patterns. Moreover, you will learn how to implement zero-trust secret access policies that satisfy SOC 2 and PCI-DSS compliance requirements.

Why Native Kubernetes Secrets Fall Short

Kubernetes Secrets have fundamental limitations that make them unsuitable for production secret management. They are only base64-encoded — anyone with RBAC access to read secrets can decode them trivially. Furthermore, secrets stored in etcd may not be encrypted at rest depending on your cluster configuration.

Secret rotation requires redeploying pods. There is no native audit trail for who accessed which secret and when. Additionally, sharing secrets across multiple clusters requires manual synchronization or custom tooling that often becomes a maintenance burden.

Kubernetes security and secrets management
External Secrets Operator architecture for secure secret synchronization

Installing External Secrets Operator

# Install ESO via Helm
helm repo add external-secrets https://charts.external-secrets.io
helm repo update

helm install external-secrets external-secrets/external-secrets \
  --namespace external-secrets \
  --create-namespace \
  --set installCRDs=true \
  --set webhook.port=9443 \
  --set certController.requeueInterval=5m

External Secrets Operator Kubernetes: AWS Provider Setup

# cluster-secret-store.yaml — Cluster-wide secret store
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
  name: aws-secrets-manager
spec:
  provider:
    aws:
      service: SecretsManager
      region: us-east-1
      auth:
        jwt:
          serviceAccountRef:
            name: external-secrets-sa
            namespace: external-secrets
---
# IRSA (IAM Role for Service Account) configuration
apiVersion: v1
kind: ServiceAccount
metadata:
  name: external-secrets-sa
  namespace: external-secrets
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/external-secrets-role
# IAM policy for the ESO role (Terraform)
resource "aws_iam_policy" "external_secrets" {
  name = "external-secrets-policy"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "secretsmanager:GetSecretValue",
          "secretsmanager:DescribeSecret",
          "secretsmanager:ListSecretVersionIds"
        ]
        Resource = "arn:aws:secretsmanager:us-east-1:123456789:secret:myapp/*"
      },
      {
        Effect = "Allow"
        Action = [
          "kms:Decrypt",
          "kms:DescribeKey"
        ]
        Resource = "arn:aws:kms:us-east-1:123456789:key/mrk-*"
      }
    ]
  })
}

Syncing Secrets from External Providers

Therefore, ExternalSecret resources define which secrets to sync and how to map them into Kubernetes Secrets. ESO watches these resources and automatically creates or updates the corresponding Kubernetes Secret whenever the source changes.

# external-secret.yaml — Sync database credentials
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
  namespace: production
spec:
  refreshInterval: 5m
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: db-credentials
    creationPolicy: Owner
    deletionPolicy: Retain
    template:
      type: Opaque
      data:
        DB_HOST: "{{ .host }}"
        DB_PORT: "{{ .port }}"
        DB_USERNAME: "{{ .username }}"
        DB_PASSWORD: "{{ .password }}"
        DB_CONNECTION_STRING: "postgresql://{{ .username }}:{{ .password }}@{{ .host }}:{{ .port }}/{{ .database }}"
  data:
    - secretKey: host
      remoteRef:
        key: myapp/production/database
        property: host
    - secretKey: port
      remoteRef:
        key: myapp/production/database
        property: port
    - secretKey: username
      remoteRef:
        key: myapp/production/database
        property: username
    - secretKey: password
      remoteRef:
        key: myapp/production/database
        property: password
    - secretKey: database
      remoteRef:
        key: myapp/production/database
        property: database
Cloud security and encryption
Automatic secret synchronization from cloud providers to Kubernetes

Automatic Secret Rotation

Consequently, ESO can trigger pod restarts when secrets are rotated in the source provider. Combined with AWS Secrets Manager’s automatic rotation for RDS credentials, this creates a fully automated rotation pipeline.

# Deployment with secret rotation awareness
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
  namespace: production
  annotations:
    reloader.stakater.com/auto: "true"
spec:
  template:
    spec:
      containers:
        - name: api
          image: myapp/api:latest
          envFrom:
            - secretRef:
                name: db-credentials
          volumeMounts:
            - name: tls-certs
              mountPath: /etc/tls
              readOnly: true
      volumes:
        - name: tls-certs
          secret:
            secretName: api-tls-cert

Multi-Cluster Secret Synchronization

Additionally, for organizations running multiple Kubernetes clusters, ESO enables consistent secret distribution from a single source of truth. Each cluster runs its own ESO instance pointing to the same secret store, ensuring all environments have synchronized credentials.

# ClusterExternalSecret — sync across all namespaces
apiVersion: external-secrets.io/v1beta1
kind: ClusterExternalSecret
metadata:
  name: shared-tls-certificates
spec:
  namespaceSelector:
    matchLabels:
      requires-tls: "true"
  externalSecretSpec:
    refreshInterval: 15m
    secretStoreRef:
      name: aws-secrets-manager
      kind: ClusterSecretStore
    target:
      name: shared-tls
      creationPolicy: Owner
    data:
      - secretKey: tls.crt
        remoteRef:
          key: shared/tls/wildcard-cert
          property: certificate
      - secretKey: tls.key
        remoteRef:
          key: shared/tls/wildcard-cert
          property: private_key

When NOT to Use External Secrets Operator

For simple applications with a handful of non-sensitive configuration values, ESO adds operational overhead that may not be justified. If your secrets rarely change and your cluster already encrypts etcd at rest, native Kubernetes Secrets with RBAC restrictions may suffice. As a result, evaluate the actual threat model before committing to ESO.

ESO introduces a dependency on external secret providers — if AWS Secrets Manager experiences an outage, new pods cannot start because they cannot fetch their secrets. Plan for this with appropriate caching and fallback strategies.

Security compliance and auditing
Balancing security requirements with operational complexity

Key Takeaways

External Secrets Operator Kubernetes integration transforms secret management from a manual, error-prone process into an automated, auditable pipeline. By syncing secrets from enterprise-grade providers, you get encryption at rest, access auditing, and automatic rotation without changing your application code. Furthermore, the ClusterExternalSecret pattern enables consistent secret distribution across multi-cluster environments.

Start with a single non-critical application to validate the ESO workflow before rolling it out organization-wide. For more information, see the External Secrets Operator documentation and AWS Secrets Manager best practices. Our guides on Kubernetes network policies and mTLS in Kubernetes complement this security-focused approach.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top