Kubernetes Secrets and ConfigMaps Done Right

Khimananda Oli 6 min read Database
Kubernetes Secrets and ConfigMaps Done Right

By Khimananda Oli | Last reviewed: August 2026

Mismanaged configuration is the leading cause of preventable outages and security breaches in container orchestration. Getting Kubernetes Secrets and ConfigMaps done right requires moving beyond basic YAML manifests to implement encryption at rest, strict RBAC, and external secret stores. This guide covers the production-grade patterns I use daily to keep clusters secure and compliant, building on the foundational deployment concepts covered in Kubernetes basics: deploy your first app to a k8s cluster.

What is the difference between Kubernetes Secrets and ConfigMaps?

While both resources store key-value pairs for pod consumption, they serve fundamentally different security domains. ConfigMaps are designed for non-sensitive configuration data such as feature flags, logging levels, or application properties that can safely exist in version control. Secrets are specifically intended for sensitive material like database passwords, TLS certificates, and API tokens.

ConfigMapNon-Sensitive DataAPP_ENV=productionLOG_LEVEL=infonginx.confMounted as File / Env VarSecretSensitive CredentialsDB_PASSWORD (base64)TLS_CERT.pemAWS_ACCESS_KEY_IDtmpfs Volume Only
Kubernetes Secrets and ConfigMaps done right separates sensitive credentials from application configuration at the storage layer.

A common mistake is treating Secrets as truly encrypted by default. In standard Kubernetes installations, Secrets are only base64-encoded, not encrypted. Anyone with read access to the etcd datastore or the API server can decode them instantly. True security requires enabling EncryptionConfiguration at the API server level or delegating storage to an external provider. For teams adopting GitOps with ArgoCD, this distinction is critical because ConfigMaps can be safely synced from Git repositories while Secrets must be injected separately.

How do you securely manage Kubernetes Secrets in production?

Production environments demand more than native Kubernetes primitives. The most reliable approach combines encryption at rest with external secret synchronization. Native Secrets should be treated as ephemeral cache rather than source of truth.

Enable encryption at rest

Before storing any credentials natively, configure the API server to encrypt Secret objects in etcd. Create an encryption configuration file:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <base64-encoded-32-byte-key>
      - identity: {}

The identity provider acts as a fallback for reading unencrypted data during migration. Always test decryption procedures before applying this to production clusters.

Use External Secrets Operator

For SOC 2 or ISO 27001 compliance, native Secrets rarely suffice. The External Secrets Operator synchronizes credentials from HashiCorp Vault, AWS Secrets Manager, or GCP Secret Manager into Kubernetes automatically. This pattern ensures credentials never touch disk in plaintext and supports automatic rotation without pod restarts. See secrets management with HashiCorp Vault for detailed integration patterns.

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: db-credentials-secret
  data:
    - secretKey: password
      remoteRef:
        key: secret/data/prod/db
        property: password

When should you use ConfigMaps versus environment variables?

Choosing the right injection method affects both security and operational flexibility. Environment variables are convenient but leak easily through logs, crash dumps, and child processes. Volume mounts are safer and support dynamic updates without container restarts.

CriteriaEnvironment VariablesVolume Mounts
Security exposureHigh (visible in /proc, logs)Low (file permissions, tmpfs)
Dynamic updatesRequires pod restartAuto-updated (subPath excepted)
Binary/config filesNot supportedFull file support
Audit trailDifficult to trackFile access logging possible
Best forSimple flags, non-sensitive togglesCredentials, configs, certificates

In practice, I reserve environment variables exclusively for non-sensitive bootstrap parameters like POD_NAME or feature flags that genuinely need process-level visibility. Everything else gets mounted as a volume with restrictive file permissions (0400 for secrets, 0644 for configs).

Vault / AWS SMSource of TruthExternal SecretsOperator SyncK8s SecretEphemeral CachePod Volume Mount
Secure injection flow for Kubernetes Secrets and ConfigMaps done right using external providers and ephemeral native secrets.

How do you handle ConfigMap updates without downtime?

Applications react differently to configuration changes. Some watch files for modifications; others require explicit signals. Understanding your application's behavior determines the update strategy.

  1. Avoid subPath for mutable configs: Volumes mounted with subPath do not receive updates when the underlying ConfigMap changes. Use the full directory mount and adjust your application's config path accordingly.
  2. Implement config reloading: Use sidecars like stakater/reloader or application-native watchers to detect file changes. For Nginx, send SIGHUP; for Java apps, use Spring Cloud Kubernetes refresh endpoints.
  3. Version your ConfigMaps: Append content hashes to ConfigMap names (e.g., app-config-a1b2c3). This triggers rolling deployments automatically when used in pod specs, ensuring zero-downtime transitions.
  4. Validate before applying: Use admission controllers or OPA/Gatekeeper policies to reject malformed configurations before they reach the cluster. This prevents runtime failures caused by syntax errors or missing required keys.

For teams managing infrastructure declaratively, combining versioned ConfigMaps with infrastructure as code with Terraform ensures configuration drift is caught during plan stages rather than at runtime.

What are the best practices for auditing Kubernetes Secrets and ConfigMaps?

Compliance frameworks require proof that sensitive data access is logged, reviewed, and restricted. Native Kubernetes audit logs capture API calls but lack granularity for secret value access.

  • Enable audit policy for secrets: Configure the API server audit policy to log get, list, and watch operations on Secret resources at the Metadata level minimum. Never log RequestResponse for secrets unless absolutely necessary for debugging.
  • Restrict RBAC aggressively: Apply least-privilege principles. Service accounts should only access specific named secrets, not wildcard permissions. Use ResourceNames in Role bindings to limit scope.
  • Integrate with SIEM: Forward audit logs to centralized logging systems. Alert on anomalous patterns like bulk secret listing or access from unexpected service accounts.
  • Rotate credentials proactively: Set maximum TTLs for all secrets. Automate rotation via External Secrets Operator or Vault dynamic secrets. Test rotation procedures quarterly.
Native K8s SecretsBase64 Encoded OnlyManual RotationLimited Audit Trailetcd Encryption RequiredExternal Secret StoreAES-256 / HSM BackedAutomated RotationFull Access LoggingDynamic CredentialsUpgrade Path
Why Kubernetes Secrets and ConfigMaps done right requires external stores for compliance and operational maturity.

Next steps for secure configuration management

Getting Kubernetes Secrets and ConfigMaps done right is not a one-time setup but an ongoing discipline. Start by auditing your current cluster for plaintext secrets in Git history and overly permissive RBAC roles. Migrate sensitive workloads to External Secrets Operator, enable etcd encryption, and establish rotation schedules aligned with your compliance requirements. If your team needs help implementing these patterns or preparing for a security audit, reach out to discuss your infrastructure. Secure configuration is the foundation every resilient platform depends on.

Frequently Asked Questions

ConfigMaps store non-sensitive configuration data as plain text, while Secrets are designed for sensitive information like passwords and tokens. Secrets use base64 encoding by default and support encryption at rest, whereas ConfigMaps do not provide any built-in security mechanisms for protecting stored values.

No, Secrets are only base64 encoded by default, which is not encryption. You must explicitly enable encryption at rest using an EncryptionConfiguration file with providers like aescbc or secretbox in your API server configuration to protect Secret data stored in etcd from unauthorized access.

Use the envFrom field in your container spec with a configMapRef to load all keys as environment variables. Alternatively, reference individual keys using valueFrom and configMapKeyRef for selective injection. Both methods work identically for Secrets when handling sensitive credential data.

Yes, if mounted as volumes, ConfigMap changes propagate automatically within seconds. However, environment variable injections require a Pod restart to take effect. Use tools like Stakater Reloader or custom controllers to automate rolling restarts when ConfigMap or Secret content changes in production clusters.

Both Secrets and ConfigMaps have a hard limit of 1 MiB per object in etcd. Exceeding this causes API errors during creation or updates. For larger configurations, mount external files via PersistentVolumes, use cloud-native secret managers, or split data across multiple objects.

Never commit raw Secrets to version control. Use Sealed Secrets, External Secrets Operator, or SOPS to encrypt manifests before committing. These tools decrypt resources cluster-side during deployment, keeping sensitive values out of Git history while maintaining declarative infrastructure-as-code workflows safely.

It synchronizes secrets from external providers like AWS Secrets Manager, HashiCorp Vault, or GCP Secret Manager into native Kubernetes Secrets. This centralizes credential lifecycle management, enables automatic rotation, and removes manual Secret creation steps while preserving standard Kubernetes consumption patterns for applications.

Kubernetes stores Secrets as base64-encoded strings internally. Use kubectl get secret name -o jsonpath='{.data.key}' | base64 -d to decode values locally. In Kubernetes 1.29+, use the --show-managed-fields flag or stringData field during creation to avoid manual encoding steps entirely.

Implement RBAC policies limiting service account permissions to specific Secret resources. Combine with NetworkPolicies to control pod-to-API-server traffic. For stronger isolation, use dedicated namespaces per application tier and consider policy engines like Kyverno or OPA Gatekeeper to enforce Secret access constraints declaratively.

The Pod enters a CrashLoopBackOff state and fails scheduling until the missing Secret is created. Set optional: true in volume mounts or env references to allow startup without the resource. Always validate Secret existence in CI pipelines before deploying dependent workloads to prevent runtime failures.

Yes. Store boolean or string flags in ConfigMaps and mount them as volumes for dynamic reloading without redeployment. Applications must watch the mounted file path for changes. Pair with feature flag services like Unleash or LaunchDarkly for advanced targeting beyond simple key-value toggles.

Create new Secrets alongside existing ones, update deployments to reference both temporarily, then remove old references after verification. Automate this pattern with cert-manager for TLS certificates or External Secrets Operator for managed credentials. Never overwrite Secrets in-place; always use additive rotation strategies.

Only if you encrypt values before templating. Raw Helm values files expose Secrets in chart repositories and release metadata. Use helm-secrets plugin with SOPS or integrate with Vault Agent Injector to render decrypted values at install time. Avoid storing plaintext credentials anywhere in Helm charts.

Storage footprint is identical since both are stored as opaque byte blobs in etcd. However, encrypted Secrets increase CPU overhead on API servers due to cryptographic operations. Monitor etcd compaction frequency and enable watch cache tuning when managing thousands of encrypted Secrets in large-scale 2026 clusters.

Run kubectl describe pod name to check Events for FailedMount warnings. Verify mount paths match container filesystem expectations and confirm ConfigMap keys exist exactly as referenced. Use kubectl exec to inspect /etc/config directories directly. Check kubelet logs for permission or SELinux denials blocking volume attachments.