External Secrets Operator: From Git-Tracked Secrets to Cloud-Native Secret Management

The Evolution of Kubernetes Secret Management

For years, the conventional wisdom was simple: never store secrets in etcd. This led to elaborate workarounds—encrypted secrets in Git repositories, Vault clusters requiring dedicated teams, or custom sidecars that injected secrets from cloud providers. While security teams slept better, developers wrestled with complex workflows just to get a database password into their pods.

The landscape has fundamentally changed. Modern Kubernetes secret management has matured from "avoid etcd at all costs" to "sync from authoritative external stores with encryption-at-rest." This shift was enabled by three key developments:

  1. Kubernetes encryption-at-rest became standard (KMS integration on EKS, GKE, AKS)
  2. Workload identity patterns (IRSA, Workload Identity, Managed Identity) eliminated the need for static credentials
  3. Operator-based sync patterns emerged that treat external secret stores as the source of truth

External Secrets Operator (ESO) sits at the convergence of these trends: a lightweight controller that continuously syncs secrets from cloud providers into Kubernetes Secret objects, using cloud-native identity, with minimal operational overhead. It's neither a heavyweight secret vault requiring specialized teams, nor a static encryption scheme requiring manual rotations. It's secret synchronization done right for cloud-native infrastructure.

The Maturity Spectrum: Kubernetes Secret Management Approaches

Let's examine how teams manage secrets in Kubernetes, from anti-patterns to production-ready solutions.

Level 0: The Anti-Pattern

Base64-Encoded Secrets in Git — Some teams still commit Kubernetes Secret manifests directly to Git, relying on base64 encoding as "security." This is fundamentally broken: base64 is encoding, not encryption. Anyone with repository access has plaintext secrets.

Verdict: Never do this. Base64 provides zero security and creates a nightmare of secret sprawl, rotation, and audit trails.

Level 1: Encrypted Secrets in Git

Sealed Secrets (Bitnami) and similar tools encrypt secrets using a cluster-specific key, allowing you to safely store encrypted Secret manifests in Git. Developers commit sealed secrets, and a controller decrypts them at runtime.

Strengths:

  • Pure GitOps workflow: all secrets are code-reviewed and versioned
  • No external runtime dependencies
  • Simple mental model

Limitations:

  • Secret rotation requires re-encrypting and committing new sealed secrets
  • No dynamic secret generation (database credentials with short TTLs)
  • Secrets are effectively static configuration, not runtime data
  • Disaster recovery requires backing up cluster private keys

When to use: Small teams with configuration-type secrets that rarely change, strong GitOps culture, and no compliance requirements around dynamic rotation.

Level 2: Sidecar Injection from Cloud Providers

Cloud-Specific CSI Drivers (AWS Secrets Store CSI, GCP Secret Manager CSI, Azure Key Vault CSI) mount secrets as volumes directly into pods using native cloud identity.

Strengths:

  • Secrets never touch etcd—mounted as ephemeral volumes
  • Cloud-native: maintained by providers, tight IAM integration
  • Automatic updates when volume remounts

Limitations:

  • Secrets aren't Kubernetes Secret objects—incompatible with Helm charts expecting existingSecret references
  • Application code must read from file paths, not environment variables (without additional configuration)
  • Single-cloud focus: multi-cloud setups require multiple CSI drivers
  • Volume mounts don't work well for init containers or job-style workloads

When to use: Strict compliance requirements prohibiting secrets in etcd, applications designed for file-based secret injection, single-cloud environments.

HashiCorp Vault with Vault Agent Injector or CSI driver provides enterprise-grade secret management: dynamic secrets, detailed audit logs, advanced policies, and automatic rotation.

Strengths:

  • Dynamic secret generation (database credentials rotated every few hours)
  • Fine-grained access policies and comprehensive audit trails
  • Secrets-as-a-service for the entire organization
  • Short-lived credentials reduce exposure window

Limitations:

  • Significant operational overhead: running Vault clusters (HA setup, backups, upgrades)
  • Requires dedicated expertise: Vault administrators become a specialization
  • Complexity can slow down development velocity
  • Many teams only need 20% of Vault's features but pay 100% of the operational cost

When to use: Large enterprises already invested in Vault infrastructure, compliance requirements mandating detailed audit trails, need for dynamic secret generation across the organization.

Level 4: The Modern Pragmatic Solution

External Secrets Operator (ESO) bridges the gap between simplicity and production readiness. It treats cloud provider secret stores as the source of truth, continuously syncing them into Kubernetes Secret objects.

How it works:

  1. Secrets live in AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, or 20+ other providers
  2. ESO runs as a lightweight controller (50m CPU, 100Mi memory)
  3. Developers define ExternalSecret custom resources that reference external secrets
  4. ESO pulls secrets using cloud-native identity (IRSA, Workload Identity, Managed Identity)
  5. Kubernetes Secret objects are created/updated automatically at configurable intervals

Strengths:

  • Cloud-native identity: No static credentials—uses IRSA (EKS), Workload Identity (GKE), Managed Identity (AKS)
  • Multi-cloud by design: Single controller handles AWS + GCP + Azure + Vault simultaneously
  • Kubernetes-native UX: Secrets end up as standard Secret objects—compatible with all Helm charts and applications
  • Minimal overhead: One lightweight operator per cluster, no specialized infrastructure
  • Operational maturity: Apache 2.0 licensed, CNCF sandbox project, production-proven at scale
  • Rotation-friendly: Update secret in cloud provider → ESO syncs automatically within configured interval

Trade-offs:

  • Secrets are stored in etcd (mitigated by Kubernetes encryption-at-rest with KMS)
  • Polling-based updates (configurable intervals from minutes to hours)
  • Not designed for extremely short-lived secrets (minute-scale TTLs—use Vault for that)

When to use: Cloud-native teams using AWS/GCP/Azure, need for simple secret sync without heavyweight infrastructure, multi-cloud environments, teams wanting standard Kubernetes Secret objects rather than sidecar injection.

Comparison: ESO vs. Alternatives

ApproachSecrets in etcd?Dynamic Secrets?Multi-Cloud?Operational OverheadGitOps-Friendly?
Sealed SecretsYes (encrypted)NoYesVery LowExcellent
CSI DriversNo (volume mount)NoSingle-cloud per driverLowGood
VaultDepends on modeYesYesHighFair
ESOYes (encrypted at rest)No*ExcellentLowExcellent

*ESO can sync dynamically-generated Vault secrets, but doesn't generate them itself.

Licensing & Maturity:

  • ESO: Apache 2.0, CNCF Sandbox, 6K+ GitHub stars, v1.0+ Helm chart
  • Sealed Secrets: Apache 2.0, stable, widely deployed
  • Vault: MPL 2.0 (Enterprise features require commercial license)
  • CSI Drivers: Provider-specific (typically Apache/MIT)

The Project Planton Choice: External Secrets Operator

Project Planton defaults to External Secrets Operator for Kubernetes secret management. This decision is grounded in three principles:

1. Cloud-Native by Default

Modern cloud platforms provide excellent secret stores (AWS Secrets Manager, GCP Secret Manager, Azure Key Vault) with built-in encryption, audit trails, and IAM integration. ESO leverages these native capabilities rather than reinventing secret storage.

2. Open-Source and Production-Proven

ESO is Apache 2.0 licensed with no proprietary tiers. It's mature enough for production (v1.0+ chart, CNCF sandbox) yet lightweight enough to run in every cluster without specialized teams.

3. Developer Experience Matters

Developers get standard Kubernetes Secret objects that work with any Helm chart or application. No file-path injection, no custom sidecars, no reading from specialized volume mounts. Just secretKeyRef in pod specs—the Kubernetes-native pattern everyone already knows.

Project Planton Abstractions:

The ExternalSecrets API focuses on the essential 20%:

message ExternalSecretsSpec {
  // Target cluster (any K8s cluster—EKS, GKE, AKS, or on-prem)
  KubernetesAddonTargetCluster target_cluster = 1;
  
  // Poll interval (balance freshness vs. cloud API costs)
  uint32 poll_interval_seconds = 2;  // default: 10 seconds
  
  // Resource tuning (CPU/memory for controller)
  ExternalSecretsSpecContainer container = 3;
  
  // Provider-specific configuration (exactly one)
  oneof provider_config {
    ExternalSecretsGkeConfig gke = 100;    // GCP + Workload Identity
    ExternalSecretsEksConfig eks = 101;    // AWS + IRSA
    ExternalSecretsAksConfig aks = 102;    // Azure + Managed Identity
  }
}

What we handle for you:

  • Installing ESO Helm chart with production defaults (HA mode, leader election)
  • Configuring cloud provider authentication (IRSA role creation for EKS, Workload Identity binding for GKE, etc.)
  • Setting up ClusterSecretStore resources for the configured provider
  • Resource tuning and namespace isolation

What you control:

  • Which secrets to sync (via ExternalSecret custom resources in your namespaces)
  • Poll intervals (balance secret freshness vs. cloud API costs)
  • Provider-specific IAM policies (which secrets ESO can access)

Multi-Provider Support

One ESO instance can sync secrets from multiple providers simultaneously. A single cluster might pull:

  • Database credentials from AWS Secrets Manager
  • API keys from GCP Secret Manager
  • TLS certificates from Azure Key Vault
  • Internal credentials from HashiCorp Vault

Define multiple SecretStore resources (one per provider) and ExternalSecret resources reference the appropriate store. ESO handles the rest.

Production Considerations

Security Best Practices

Least-Privilege IAM:

  • EKS: Create IRSA roles limited to specific secret paths (prod/analytics/*)
  • GKE: Grant GCP Service Accounts only Secret Manager Secret Accessor on needed secrets
  • AKS: Use Managed Identities with Key Vault access policies scoped to specific keys

RBAC on ExternalSecret CRDs: Treat ExternalSecret and SecretStore custom resources as sensitive. Only allow developers to create ExternalSecrets in their own namespaces, referencing pre-configured ClusterSecretStores. Restrict ClusterSecretStore creation to cluster admins.

Network Policies: Limit ESO pod egress to cloud provider API endpoints and Kubernetes API. No unrestricted internet access.

Pod Security: ESO adheres to Kubernetes restricted Pod Security Standard by default (non-root, read-only filesystem, dropped capabilities).

High Availability

Production deployments run ESO with:

  • Multiple replicas (2-3) with leader election (only one actively syncs, others standby)
  • Pod anti-affinity to spread replicas across nodes
  • Resource limits to prevent memory leaks from affecting cluster

Project Planton configures this automatically.

Monitoring & Operational Health

Key Metrics (Prometheus):

  • externalsecret_sync_calls_total — total syncs
  • externalsecret_sync_calls_error — failed syncs (alert on this)
  • externalsecret_status_condition — per-secret health gauge

Alerts to Configure:

  • Any ExternalSecret in error state for >10 minutes
  • Sync error rate spike (could indicate IAM issues or provider outage)
  • No successful syncs for a canary ExternalSecret (ESO health check)

Troubleshooting Common Issues:

  • Error: AccessDenied → Check IAM policy on cloud provider
  • Error: Secret not found → Verify remoteRef.key matches secret name in provider
  • ExternalSecret stuck in "Pending" → Check ESO controller logs for authentication errors
  • Secret not updating after external change → Verify poll interval hasn't elapsed; consider shorter interval or manual trigger

Cost Optimization

Poll Interval Tuning:

  • Longer intervals (1-4 hours) for rarely-changed secrets (TLS certificates, API keys)
  • Shorter intervals (15-30 minutes) for frequently-rotated credentials
  • Very short intervals (<5 minutes) only for critical secrets—beware cloud API costs

Example Cost Math:

  • 100 secrets polled every hour = 2,400 API calls/day = ~72,000/month
  • AWS Secrets Manager: $0.05 per 10,000 API calls → ~$0.36/month
  • Scale this by your secret count and poll frequency

Most teams find polling costs negligible, but avoid "poll everything every minute" anti-patterns.

Secret Rotation

ESO's polling model handles rotation elegantly:

  1. Rotate secret in cloud provider (AWS, GCP, Azure)
  2. ESO fetches new value at next poll interval
  3. Kubernetes Secret object updates automatically
  4. Pods using Secret via environment variables require restart (standard K8s behavior)
  5. Pods mounting Secret as volume get updated content (kubelet sync delay applies)

For zero-downtime rotations: Stage new credentials, update ExternalSecret to create a new Secret, update deployment to reference new Secret, cut over, delete old Secret.

Migration Path: From Static Secrets to ESO

Existing clusters with static Kubernetes Secrets can migrate incrementally:

  1. Install ESO (via Project Planton or directly)
  2. Populate external store with current secret values
  3. Create ExternalSecret resources with creationPolicy: Merge (doesn't overwrite existing secrets)
  4. Validate sync — ensure ESO-synced values match existing secrets
  5. Switch to Owner mode — change creationPolicy: Owner so ESO fully manages the Secret
  6. Remove static definitions from Git/Helm/Terraform

One secret at a time, one namespace at a time. No big-bang migration required.

Common Anti-Patterns to Avoid

❌ Overly Frequent Polling

Setting poll intervals to seconds wastes cloud API calls and increases costs. Most secrets change infrequently—hourly polling is usually sufficient.

❌ Shared ClusterSecretStore Without RBAC Controls

One ClusterSecretStore with broad credentials accessible to all namespaces violates least-privilege. Use namespace-scoped SecretStores or add ClusterSecretStore conditions restricting namespace access.

❌ Hardcoding Cloud Credentials in Kubernetes

Storing AWS access keys or GCP service account JSON keys in Kubernetes Secrets defeats the purpose. Use IRSA, Workload Identity, or Managed Identity—never static credentials in production.

❌ Running Single Replica in Production

One ESO pod is a single point of failure. Run 2-3 replicas with leader election for high availability.

❌ No Monitoring on Sync Failures

Secrets are critical infrastructure. Always alert on ExternalSecret sync errors—a failed sync can lead to outages during rotations.

Conclusion: The Right Tool for Modern Cloud-Native Teams

External Secrets Operator represents a pragmatic middle ground in Kubernetes secret management. It's not as heavyweight as running Vault clusters, nor as limited as sealed secrets in Git. It leverages what cloud providers already do well (secret storage, encryption, audit) while giving you standard Kubernetes primitives (Secret objects) that work with existing tooling.

For teams running workloads on EKS, GKE, or AKS, ESO is the natural choice: cloud-native identity, minimal overhead, production-proven, and open-source. Project Planton's integration makes it even simpler—define your provider configuration, and we handle the installation, authentication setup, and best-practice defaults.

The result? Developers reference secrets naturally via secretKeyRef, operations teams manage them in cloud provider UIs (or Terraform), and security teams get audit trails and rotation without custom infrastructure. Secret management that just works.


Further Reading:

Next article

Ingress Nginx

NGINX Ingress Controller on Kubernetes: The Path to Production Introduction When Kubernetes first emerged, the conventional wisdom was simple: expose your services directly with LoadBalancer or NodePort, and call it a day. But as applications grew in complexity, teams faced a crucial question: How do we route HTTP traffic to dozens—or hundreds—of services without creating dozens of cloud load balancers? Enter the Ingress concept: a single entry point that routes traffic based on hostnames and...
Read next article