autojanet/skills/terrashark/references/secret-exposure.md
Zoë cfec11bb46
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix: convert skill submodules to plain directories
stop-slop, taste-skill, terrashark had embedded .git dirs causing
Woodpecker clone to fail on submodule update.
2026-05-30 15:44:44 -07:00

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 show outputs 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:

  1. external secret manager lookup
  2. workload identity federation for providers
  3. short-lived credentials from trusted broker

Avoid long-lived static credentials in repository or runner config.

Write-only and sensitive handling

  • sensitive = true masks display, but value can still exist in state depending on provider behavior
  • write_only arguments (where supported) reduce state persistence risk
  • always verify provider docs before assuming secret material is excluded from state

Rotation playbook

  1. create new secret version in manager
  2. update application to consume new version
  3. roll infrastructure safely
  4. revoke old credential
  5. 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 sensitive alone 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