Review exposure of Secrets in environment variables

Control how Secrets are delivered and how logs and diagnostic tools handle them.

Description

Injecting a Secret through env.value_from.secret_key_ref or env_from.secret_ref can expose its value in application logs, debugging output or process dumps. Referencing a Secret avoids embedding its value in configuration, but does not eliminate runtime exposure.

Consider mounting required Secrets as files when the application supports it. Authorized processes can still read those files, so changing the delivery method does not protect a secret from a compromised application.

Potential impact

  • Secret values may remain in logs or diagnostic material.
  • Leaked keys or passwords can enable access to other systems according to their permissions.

Remediation

  • Where possible, mount Secrets as read-only files only in the containers that need them, restrict file permissions and configure the application to read the files.
  • If environment variables are required, redact output and diagnostic material and minimize Secret and pod-debugging permissions. Environment variables do not automatically reflect Secret changes, so plan restarts during rotation.

Examples

Create db-secret in the same namespace first. The existing nginx image illustrates delivery only; it does not automatically use DB_PASSWORD or the mounted file. Configure the actual application’s reading method and use a maintained image.

Before

hcl
resource "kubernetes_pod" "example" {
  metadata {
    name = "app"
  }

  spec {
    container {
      name  = "web"
      image = "nginx:1.7.9"

      env {
        name = "DB_PASSWORD"

        value_from {
          secret_key_ref {
            name = "db-secret"
            key  = "password"
          }
        }
      }
    }
  }
}

After

hcl
resource "kubernetes_pod" "example" {
  metadata {
    name = "app"
  }

  spec {
    container {
      name  = "web"
      image = "nginx:1.7.9"

      volume_mount {
        name       = "db-secret"
        mount_path = "/var/run/secrets/db"
        read_only  = true
      }
    }

    volume {
      name = "db-secret"

      secret {
        secret_name = "db-secret"
      }
    }
  }
}

Explanation:

  • Before: The password key is delivered through DB_PASSWORD. Logs and diagnostic output need protection.
  • After: The Secret is mounted as read-only files. File permissions and the application’s actual read path must also be configured.

References