What Is the External Secrets Operator?

advanced|configmaps secretsdevopssreplatform engineerCKA
TL;DR

The External Secrets Operator (ESO) synchronizes secrets from external providers (AWS Secrets Manager, HashiCorp Vault, Azure Key Vault, Google Secret Manager) into Kubernetes Secrets. It keeps Kubernetes Secrets in sync with the source of truth and supports automatic rotation.

Detailed Answer

The External Secrets Operator (ESO) is a Kubernetes operator that reads secrets from external APIs and injects them as Kubernetes Secrets. It eliminates the need to manually create and update Secrets, providing a bridge between enterprise secret management systems and Kubernetes.

Why External Secrets

Storing secrets directly in Kubernetes has limitations:

  • No centralized management across clusters
  • No audit trail for secret access
  • No automatic rotation
  • Secrets must be created before deployments
  • Risk of secrets in Git repositories

ESO solves these by keeping an external provider as the source of truth.

Architecture

External Provider               Kubernetes Cluster
┌──────────────────┐           ┌─────────────────────────────┐
│ AWS Secrets Mgr  │◄──poll───│  External Secrets Operator   │
│ HashiCorp Vault  │           │         │                    │
│ Azure Key Vault  │           │         ▼                    │
│ GCP Secret Mgr   │           │  ┌─────────────┐            │
└──────────────────┘           │  │  K8s Secret  │◄─ Pods     │
                               │  └─────────────┘            │
                               └─────────────────────────────┘

Setup

1. Install the Operator

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

2. Create a SecretStore

A SecretStore defines the connection to an external provider:

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: aws-secrets
  namespace: production
spec:
  provider:
    aws:
      service: SecretsManager
      region: us-east-1
      auth:
        secretRef:
          accessKeyIDSecretRef:
            name: aws-credentials
            key: access-key-id
          secretAccessKeySecretRef:
            name: aws-credentials
            key: secret-access-key

For cluster-wide access, use ClusterSecretStore:

apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
  name: vault-store
spec:
  provider:
    vault:
      server: "https://vault.internal:8200"
      path: "secret"
      version: "v2"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "external-secrets"

3. Create an ExternalSecret

An ExternalSecret defines which secrets to sync:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: app-credentials
  namespace: production
spec:
  refreshInterval: 1h                  # How often to check for changes
  secretStoreRef:
    name: aws-secrets
    kind: SecretStore
  target:
    name: app-credentials              # Name of the K8s Secret to create
    creationPolicy: Owner              # ESO manages the Secret lifecycle
  data:
    - secretKey: DATABASE_PASSWORD     # Key in the K8s Secret
      remoteRef:
        key: prod/database             # Path in AWS Secrets Manager
        property: password             # Specific field in the JSON secret
    - secretKey: API_KEY
      remoteRef:
        key: prod/api-keys
        property: primary-key

Syncing Entire Secrets

Instead of mapping individual fields, sync all properties:

spec:
  dataFrom:
    - extract:
        key: prod/database    # All JSON fields become K8s Secret keys

If the AWS secret prod/database contains:

{"host": "db.example.com", "password": "secret123", "port": "5432"}

The Kubernetes Secret gets keys: host, password, port.

Templating

ESO supports templating for the target Secret:

spec:
  target:
    name: db-connection-string
    template:
      type: Opaque
      data:
        CONNECTION_STRING: "postgresql://{{ .user }}:{{ .password }}@{{ .host }}:5432/mydb"
  data:
    - secretKey: user
      remoteRef:
        key: prod/database
        property: username
    - secretKey: password
      remoteRef:
        key: prod/database
        property: password
    - secretKey: host
      remoteRef:
        key: prod/database
        property: host

Monitoring Sync Status

# Check ExternalSecret status
kubectl get externalsecrets -n production
# NAME              STORE         REFRESH INTERVAL   STATUS
# app-credentials   aws-secrets   1h                 SecretSynced

# Describe for details
kubectl describe externalsecret app-credentials -n production

Supported Providers

| Provider | Backend | |---|---| | AWS | Secrets Manager, Parameter Store | | Azure | Key Vault | | GCP | Secret Manager | | HashiCorp | Vault | | IBM | Secrets Manager | | Oracle | Vault | | 1Password | Connect | | Kubernetes | Another cluster's Secrets |

Best Practices

  1. Use ClusterSecretStore for shared providers to avoid duplicating configuration per namespace
  2. Set appropriate refreshInterval — shorter intervals mean faster rotation but more API calls
  3. Use IRSA/Workload Identity instead of static credentials for authenticating to cloud providers
  4. Monitor sync failures — a stale Secret can cause application outages
  5. Use creationPolicy: Owner so ESO manages the Secret lifecycle and cleans up on deletion

Why Interviewers Ask This

Interviewers ask this to assess whether you understand enterprise-grade secret management and can integrate Kubernetes with external security infrastructure.

Common Follow-Up Questions

How does ESO differ from directly using a CSI secrets driver?
ESO creates real Kubernetes Secret objects that can be referenced by any workload. CSI drivers mount secrets directly as volumes without creating Secret objects, but require workload-level configuration.
How does ESO handle secret rotation?
ESO polls the external provider at a configurable interval (refreshInterval). When the external secret changes, ESO updates the Kubernetes Secret, and volume-mounted Secrets propagate the change to Pods.
What is a SecretStore vs a ClusterSecretStore?
SecretStore is namespace-scoped — only ExternalSecrets in the same namespace can use it. ClusterSecretStore is cluster-wide and can be referenced from any namespace.

Key Takeaways

  • ESO bridges external secret managers and Kubernetes, keeping secrets synchronized.
  • It supports all major cloud providers plus HashiCorp Vault and other backends.
  • SecretStore and ExternalSecret CRDs define where and what secrets to sync.

Related Questions

You Might Also Like