Sealed Secrets vs External Secrets Operator

Khimananda Oli 8 min read Database
Sealed Secrets vs External Secrets Operator

By Khimananda Oli | Last reviewed: August 2026

Choosing between Sealed Secrets vs External Secrets Operator defines how safely your team manages credentials in a GitOps workflow. While Sealed Secrets encrypts values for safe Git storage using an in-cluster controller, External Secrets Operator (ESO) synchronizes native secrets from external providers like AWS Secrets Manager or HashiCorp Vault directly into your cluster. Understanding this distinction prevents architectural debt that becomes painful during compliance audits or secret rotation events.

If you are building a new platform or refactoring legacy pipelines, understanding Kubernetes secrets management done right is essential before selecting a tool. Both solutions solve the "plaintext secret in Git" problem, but they diverge sharply on operational complexity, security boundaries, and auditability. In my experience helping teams across Nepal and globally achieve SOC 2 compliance, the wrong choice here often leads to manual rotation toil or failed audit evidence collection later.

Sealed Secrets FlowDeveloper CLIGit RepositorykubesealArgoCD / Flux SyncDeploys SealedSecret CRDSealed Secrets ControllerDecrypts → Creates K8s SecretExternal Secrets Operator FlowGit RepositoryAWS / Vault / GCPArgoCD / Flux SyncDeploys ExternalSecret CRDESO ControllerFetches → Creates K8s SecretAPI Call
Sealed Secrets vs External Secrets Operator architecture: encrypted Git artifacts versus runtime API synchronization from external providers.

How does Sealed Secrets work in a GitOps pipeline?

Sealed Secrets operates on a cryptographic asymmetry model designed specifically for GitOps. You encrypt secrets locally using the kubeseal CLI against the cluster's public certificate. The resulting SealedSecret manifest is safe to commit to Git because only the in-cluster controller possesses the private key needed to decrypt it. When ArgoCD or Flux applies this manifest, the controller unseals it and creates a standard Kubernetes Secret object that pods can mount.

Practical encryption workflow

The developer experience is straightforward but requires discipline. You must ensure the correct controller certificate is used, especially in multi-cluster setups where each cluster has its own key pair.

<!-- Encrypt a secret for the production cluster -->
kubeseal --controller-name=sealed-secrets-controller \
  --controller-namespace=kube-system \
  --cert=prod-cluster-cert.pem \
  --format=yaml < plain-secret.yaml > sealed-secret.yaml

<!-- Verify the sealed secret is valid before committing -->
kubeseal --validate < sealed-secret.yaml

A common mistake I see in teams adopting this for the first time is neglecting certificate rotation. The sealing key should be rotated periodically (e.g., every 30 days). Old keys remain valid for decryption by default, but new seals require the current cert. If you lose the private key stored in the cluster, all sealed secrets become permanently unrecoverable. This makes backing up the sealing key pair a critical disaster recovery task, distinct from etcd backups.

Limitations in dynamic environments

Sealed Secrets is static. Once sealed, the value is immutable unless you re-seal and re-commit. There is no native mechanism for automatic rotation or syncing with an external source of truth. For environments requiring frequent credential updates or short-lived tokens, this creates significant operational friction. Developers must manually trigger re-encryption pipelines, which defeats the purpose of automation in mature GitOps with ArgoCD workflows.

How does External Secrets Operator synchronize credentials?

External Secrets Operator (ESO) takes a fundamentally different approach: it treats Kubernetes as a consumer of secrets, not the primary store. ESO runs as a controller that watches ExternalSecret custom resources. When it detects one, it authenticates against a configured backend (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault, GCP Secret Manager, etc.), fetches the value, and creates/updates a native Kubernetes Secret. The secret definition lives in Git, but the actual sensitive value never touches your repository.

Configuring a basic ExternalSecret

ESO separates authentication configuration (SecretStore) from secret definitions (ExternalSecret). This separation enables platform teams to manage backend access centrally while application teams define their own secret mappings.

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: app-db-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: db-credentials
    creationPolicy: Owner
  data:
    - secretKey: username
      remoteRef:
        key: prod/app/db
        property: username
    - secretKey: password
      remoteRef:
        key: prod/app/db
        property: password

The refreshInterval parameter is crucial. It determines how often ESO polls the backend for changes. Setting this too low increases API costs and rate-limit risks; setting it too high delays propagation. For most applications, 1 hour is reasonable. For highly sensitive rotating credentials, 5–15 minutes may be necessary, provided your provider's API quotas support it.

Multi-cluster and multi-tenant patterns

ESO excels in complex topologies. A single ClusterSecretStore can serve dozens of clusters, with IAM roles or service accounts scoped per namespace. This aligns naturally with Kubernetes RBAC security models. Platform engineers configure the store once; developers reference it without needing cloud credentials. This reduces the blast radius of compromised credentials significantly compared to distributing sealing certificates across teams.

GitOps ControllerESO ControllerCloud ProviderKubernetes APIApply ExternalSecretFetch Secret ValueReturn JSON PayloadCreate/Update K8s SecretStatus Update (Synced)Poll Timer (1h)
ESO synchronization sequence: GitOps applies the CRD, ESO polls the provider on interval, and creates the native Kubernetes secret.

Which solution meets SOC 2 and ISO 27001 compliance requirements?

Compliance frameworks care about three things: least privilege, audit trails, and secret lifecycle management. Here, Sealed Secrets vs External Secrets Operator diverges significantly. Sealed Secrets provides encryption-at-rest in Git, which satisfies "no plaintext secrets" controls. However, it lacks centralized audit logging of secret access. You cannot easily prove to an auditor who accessed a secret or when it was last rotated without parsing Git history and correlating it with deployment logs.

ESO, when backed by AWS Secrets Manager or Vault, inherits the provider's audit capabilities. Every fetch operation generates a CloudTrail or Vault audit log entry. Rotation policies are enforced at the provider level, not dependent on developer discipline. For ISO 27001 or SOC 2 Type II audits, this automated evidence trail is invaluable. I have helped organizations migrate from Sealed Secrets to ESO specifically because auditors required proof of rotation enforcement that Git commits alone could not provide.

That said, Sealed Secrets can still be compliant if supplemented with additional controls: strict RBAC on the sealing key, automated re-sealing pipelines, and separate backup procedures for the private key. But the operational overhead to achieve equivalent assurance is higher. For teams in regulated industries or those pursuing certification, ESO's native integration with compliant backends usually justifies the added infrastructure dependency.

When should you choose Sealed Secrets over External Secrets Operator?

Despite ESO's advantages, Sealed Secrets remains the right choice for specific contexts. Its zero-dependency nature (beyond the controller itself) makes it ideal for edge clusters, air-gapped environments, or small teams without cloud provider secret management infrastructure. If your cluster runs in a Nepali data center with intermittent internet connectivity, relying on AWS Secrets Manager is a liability. Sealed Secrets works entirely offline after initial setup.

CriteriaSealed SecretsExternal Secrets Operator
Primary Use CaseSimple GitOps, air-gapped, edgeMulti-cloud, regulated, dynamic secrets
Secret StorageEncrypted in GitExternal provider (AWS/Vault/GCP)
Rotation SupportManual re-seal requiredAutomatic via refreshInterval
Audit TrailGit history onlyProvider-native logs (CloudTrail/Vault)
Multi-ClusterPer-cluster key managementCentralized SecretStore
Offline CapabilityFull (after init)None (requires API access)
ComplexityLowModerate (IAM, networking, CRDs)
Compliance FitBasic / SupplementalSOC 2 / ISO 27001 Native

Consider Sealed Secrets if your team is small (<10 engineers), your secrets change infrequently, and you lack existing cloud secret infrastructure. Consider ESO if you operate multiple clusters, require automated rotation, need audit-grade logging, or already use a cloud provider's secret manager extensively. Many mature organizations actually use both: ESO for production workloads with compliance requirements, and Sealed Secrets for development/staging clusters or bootstrap configurations where external dependencies are undesirable.

Decision Factors: Sealed Secrets vs External Secrets OperatorChoose Sealed Secrets• Air-gapped / Edge clusters• Small teams, low rotation needs• Zero external dependenciesChoose ESO• Multi-cluster / Multi-cloud• Automated rotation required• SOC 2 / ISO 27001 complianceHybrid Approach• Prod: ESO + Vault/AWS• Dev/Staging: Sealed Secrets• Bootstrap: Sealed SecretsKey Trade-offs SummarySecurity Model:Crypto-bound to cluster vs. IAM-bound to providerOperational Toil:Manual re-seal vs. API quota managementDisaster Recovery:Backup sealing key vs. Provider resilienceAudit Evidence:Git commits vs. CloudTrail / Vault logsOnboarding Cost:Minutes (CLI) vs. Hours (IAM + CRDs)
Decision framework for Sealed Secrets vs External Secrets Operator based on environment constraints and compliance requirements.

Making the final decision for your Kubernetes platform

The choice between Sealed Secrets vs External Secrets Operator ultimately depends on your operational maturity, compliance obligations, and infrastructure topology. Neither is universally superior; each optimizes for different constraints. Start by auditing your current secret lifecycle: how often do credentials rotate? Who needs access? What audit evidence will your next assessment require? Answer these honestly before installing either controller.

If you are managing secrets across multiple environments or preparing for compliance certification, the investment in ESO typically pays off within months through reduced rotation toil and streamlined audits. For simpler setups or disconnected environments, Sealed Secrets remains a battle-tested, lightweight option. Whichever path you choose, ensure your CI/CD pipeline handles secrets safely and that you have documented recovery procedures before going to production.

Need help designing a secrets management strategy that aligns with your compliance goals and operational reality? Contact me to discuss your Kubernetes platform architecture or schedule a secrets management review for your team.

Frequently Asked Questions

Sealed Secrets encrypts secrets locally for safe Git storage, while External Secrets Operator synchronizes secrets directly from external providers like AWS Secrets Manager or HashiCorp Vault into Kubernetes at runtime.

Sealed Secrets fits pure GitOps best since encrypted secrets live in the repository. External Secrets Operator works better when teams prefer keeping sensitive data entirely out of version control systems.

Yes, External Secrets Operator natively supports HashiCorp Vault as a secret store backend using the VaultSecretStore resource with proper authentication configuration.

Yes, but it requires decrypting existing sealed secrets and configuring external secret stores. There is no automated migration tool, so plan manual validation for each secret during transition.

Yes, Bitnami continues maintaining Sealed Secrets with regular security patches and Kubernetes compatibility updates through 2026, though feature development has slowed compared to External Secrets Operator.

Generate a new sealing key pair and deploy it to the controller. Old sealed secrets remain valid until manually re-encrypted with the new public key using kubeseal.

It requires RBAC permissions to create and update Secrets in target namespaces plus credentials to authenticate against external secret stores via service accounts or IAM roles.

Yes, they operate independently without conflicts. Teams often use both during migration periods or for different workload requirements across namespaces.

Sealed Secrets typically has lower overhead since it needs only a single controller and no external infrastructure dependencies beyond the initial key setup.

Check the ExternalSecret status field, review operator logs with kubectl logs, verify secret store connectivity, and confirm IAM or token permissions are correctly configured for the provider.

Sealed Secrets is free with no external API costs. External Secrets Operator may incur cloud provider API charges for secret retrieval operations depending on sync frequency and volume.

Not natively. Each cluster needs its own sealing key pair unless you manually distribute the same private key, which reduces security isolation between environments.

Existing deployed secrets remain functional since they are standard Kubernetes Secrets. Only new sealing operations fail until the controller recovers or restarts successfully.

Yes, configure refreshInterval on ExternalSecret resources to periodically resync from the provider, automatically updating Kubernetes Secrets when upstream values change.

Both integrate well, but Sealed Secrets aligns more naturally since encrypted manifests commit directly to Git repos that ArgoCD monitors without requiring additional webhook configurations.