Secrets can leak into Git history, CI logs, crash reports, and state files, which turns a deployment convenience into a persistent exposure path. The failure is not just storage, but uncontrolled propagation across planning, execution, and recovery artefacts. Teams need a runtime retrieval model instead of static injection.
Why static tfvars and environment injection fail as a secrets pattern
Using .tfvars files or environment variables for secrets creates a brittle trust boundary because the values stop living only in source control and start moving through the entire workflow. Once a secret is present at plan time or run time, it can be captured by logs, cached output, crash artefacts, shell history, or CI/CD metadata, which makes later cleanup incomplete even if the file is deleted.
The real break is that OpenTofu inherits the operational behaviour of the surrounding tooling. If the pipeline, runner, or workstation treats secrets as ordinary configuration, the secret can be copied, displayed, serialized, or reused outside the moment it was intended for.
Where the exposure path usually expands
.tfvars files are attractive because they are easy to parameterise, but they are also easy to commit, copy, archive, or attach to tickets and build artefacts. Environment variables look less permanent, yet they often end up in process inspection output, debug traces, wrapper scripts, and failure reports, especially when teams enable verbose plan/apply behaviour during troubleshooting.
This is why the safer pattern is not "hide the same secret better", but "avoid static injection altogether". A runtime retrieval model, such as fetching a short-lived secret only when needed, narrows the places where the value exists and shortens the window during which it can be exposed.
What changes when secrets are retrieved at runtime instead
Runtime retrieval changes both the blast radius and the recovery model. A secret that is loaded just-in-time can be scoped to a narrow use case, rotated without editing infrastructure code, and revoked without hunting through every place it may have been copied. That also makes it easier to separate configuration from sensitive material, which is important when plans, state, and logs are stored in shared systems.
For teams operating across CI/CD, the key decision is whether the workflow needs a secret at all, or only an authenticated path to obtain one. In practice, a secretless or short-lived credential flow is easier to govern than a file-based or environment-based pattern because the sensitive value is no longer part of the durable deployment inputs.
Risk and Threat Considerations
Static secret injection turns routine delivery artefacts into long-lived exposure points. If a secret lands in source control, state, logs, or crash output, the compromise is no longer limited to one pipeline run, because the value can be replayed from any copy that survives backup, cache, or replication.
Failure mechanism: The secret is propagated into systems that were never meant to be secret stores, then persists in places with broader access and weaker revocation hygiene than the original workflow.
Impact: An attacker, insider, or later maintainer can recover the secret after the original job has finished, which extends compromise from a transient deployment event into an ongoing credential exposure problem.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP Non-Human Identity Top 10 addresses the attack surface, NIST SP 800-53 Rev 5, CIS Controls v8 and OWASP ASVS set the technical controls, and ISO/IEC 27001:2022 defines the regulatory obligations.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP Non-Human Identity Top 10 | NHI-02 — Secret Leakage | Static tfvars and env secrets leak into logs, state and artifacts. |
| NHI-07 — Long-Lived Secrets | The question centers on persistent exposure from long-lived deployment secrets. | |
| NHI-05 — Overprivileged NHI | Deployment secrets often grant broader access than the workflow needs. | |
| Recommendation — Move secrets out of static injection and restrict their runtime exposure. Replace long-lived credentials with short-lived, rotating alternatives. Scope each secret to the minimum access needed for the task. | ||
| NIST SP 800-53 Rev 5 | IA-5 — Authenticator Management | Secret lifecycle, storage and rotation are central to the failure mode. |
| AC-6 — Least Privilege | Reducing blast radius requires limiting what injected secrets can do. | |
| Recommendation — Manage secret creation, storage, rotation and revocation centrally. Restrict each credential to the minimum privileges required. | ||
| ISO/IEC 27001:2022 | A.8.24 — Use of cryptography | Protecting secrets in transit and at rest is part of preventing exposure. |
| Recommendation — Apply approved cryptographic protection where secrets must be stored or transmitted. | ||
| CIS Controls v8 | CIS-5 — Account Management | The issue is fundamentally about managing and revoking deployment credentials. |
| Recommendation — Inventory, rotate and remove credentials tied to automated workflows. | ||
| OWASP ASVS | V14 — Data Protection | The answer concerns preventing sensitive values from persisting in files and logs. |
| V6 — Authentication | Static secrets are being used as authenticators for workflow access. | |
| Recommendation — Keep secrets out of durable outputs and protect sensitive data at rest and in transit. Prefer stronger, short-lived authentication mechanisms over shared static secrets. | ||
Practitioner Guidance
What to verify: Check whether any OpenTofu variable, wrapper script, or pipeline step causes the secret to appear in plan output, debug logs, state, artifact bundles, or crash diagnostics. If it does, treat the workflow as unsafe even if the secret is "not committed" to the repository.
Decision rule: If the value grants production access, rotate it out of static injection first and move to a retrieval path with short-lived credentials or tightly scoped runtime issuance. If the secret is only used for local testing, still prevent it from being reused in shared CI contexts.
Common mistake: Teams often focus on whether the .tfvars file is ignored by Git, while missing the larger problem that the same value may already have been copied into plan files, logs, or remote state.
Practitioner takeaway: The control objective is not to make static secrets harder to see, but to stop them from becoming durable workflow data in the first place.
Related resources from NHI Mgmt Group
- What breaks when developers put secrets in Docker Compose files or environment variables?
- What breaks when teams rely only on sensitive variables and encrypted state for OpenTofu secrets?
- What breaks when developers rely on copied secrets and synced files across modern delivery workflows?
- What breaks when MCP servers rely on environment variables for secrets?
Deepen Your Knowledge
Free weekly newsletter
Subscribe to the NHI & AI Identity Journal
The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.
Bonus 33% off our NHI Course when you subscribe.
Reviewed and updated by the NHIMG editorial team on October 11, 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org