Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
stop-slop, taste-skill, terrashark had embedded .git dirs causing Woodpecker clone to fail on submodule update.
2.5 KiB
2.5 KiB
Secret Exposure
Use this guide when secrets may leak into state, logs, defaults, or CI artifacts.
Symptoms
- secret values appear in plan output or logs
- credentials are defined in variable defaults
- sensitive outputs are printed in CI
- generated passwords are stored in state unintentionally
Exposure paths
- hardcoded defaults in
variables.tf - secret-bearing resources whose values are persisted in state
- logging
terraform showoutputs without redaction - artifact retention policies that keep plan/state exports too long
Prevention baseline
- never set secret defaults in code
- source secrets from managed secret stores at runtime
- mark secret variables and outputs as
sensitive = true - restrict state backend access aggressively
- avoid publishing raw plan JSON as broadly accessible artifact
Runtime patterns
Preferred order:
- external secret manager lookup
- workload identity federation for providers
- short-lived credentials from trusted broker
Avoid long-lived static credentials in repository or runner config.
Write-only and sensitive handling
sensitive = truemasks display, but value can still exist in state depending on provider behaviorwrite_onlyarguments (where supported) reduce state persistence risk- always verify provider docs before assuming secret material is excluded from state
Rotation playbook
- create new secret version in manager
- update application to consume new version
- roll infrastructure safely
- revoke old credential
- verify no leaked copies remain in logs/artifacts
Good example
variable "db_admin_username" {
description = "Database admin user"
type = string
}
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = "prod/db/admin"
}
resource "aws_db_instance" "core" {
identifier = "core-db-prod"
username = var.db_admin_username
password = jsondecode(data.aws_secretsmanager_secret_version.db_password.secret_string)["password"]
}
Bad example
variable "db_password" {
type = string
default = "ChangeMe123!"
}
LLM mistake checklist
Common model mistakes to correct:
- assumes
sensitivealone means "not in state" - proposes plaintext defaults for demo convenience
- uses outputs that expose full connection strings in PR comments
- forgets artifact retention and access controls in CI
Verification commands
terraform plan -out=plan.bin
terraform show -json plan.bin > plan.json
# Ensure secret fields are not emitted to shared artifacts/logs