Marking a variable sensitive suppresses it in plan and apply output, and the state file holds every value in plain text regardless.
variable "database_password" {
type = string
sensitive = true
}
# in the plan: + database_password = (sensitive value)
# in the state: the plaintext value, always
# so the state backend needs encryption at rest and
# access control, and a pipeline that uploads the plan
# as an artifact is subject to the same problem as one
# that comments it on a pull request.
The sensitivity marking propagates to any output derived from the value, which occasionally makes an unrelated output unreadable and is the correct behaviour. The state file being the real exposure is the part that gets missed, because the plan output is what people are looking at when they think about this.