Avoid hard-coded credentials in Terraform provider blocks by sourcing authentication from short-lived identity or external secret material rather than static values in code. Keep secrets out of configuration files and state where possible, restrict who can read plans and state, and rotate any credentials that have already been embedded. Review modules for default values and copied examples.
Where the credential actually belongs instead of the provider block
Provider blocks should describe machine and workload identities or other external authentication inputs, not embed reusable usernames, passwords, API keys, or tokens directly in code. For Terraform, the safer pattern is to let the runtime obtain authentication from an identity platform, a federated login path, or injected secret material that is managed outside the module.
That separation matters because provider configuration is often copied across repos, modules, and examples. If the credential lives in the block, it tends to spread with the code; if it is externalised, you can change, revoke, or scope it without editing every consumer. The same principle applies to teams sharing modules: the module should define what it provisions, while the execution environment supplies how it authenticates.
Terraform state also raises the stakes. Even when a provider block is no longer visible in the module source, a hard-coded value can still end up in plan output, state history, or logs if you are not careful about how the provider is wired. Treat provider authentication as runtime configuration, not as module content, and verify that your state backend, plan distribution, and CI logs are not retaining secret material.
What to use instead of static values
Prefer short-lived credentials, federated identity, or externally injected secret material over literal values in the provider block. In practice, that usually means using the cloud or platform's native auth flow, environment variables sourced by the runner, or a secrets manager that hands the execution environment a time-bound token instead of a long-lived secret. Static default values in modules are a common trap because they silently turn examples into production habits.
If a module needs a credential-like input, make it explicit and optional rather than prefilled. A well-designed module can accept authentication from the calling environment, document the required variables, and avoid shipping example values that look safe but are actually live secrets waiting to be reused. Review any copied snippets, nested modules, and default variable values for hidden credential material.
For teams standardising this pattern, the strongest baseline is to align provider authentication with a secrets management approach that centralises storage, supports rotation, and reduces secret sprawl. If the credential must exist, keep it outside the repository, keep it short-lived where possible, and make the consuming workflow responsible for retrieving it at run time.
How to find and remove embedded credentials safely
Start by scanning provider blocks, variable defaults, module examples, and CI/CD variable injection points for values that can authenticate to an environment. Look for hard-coded access keys, bearer tokens, client secrets, and "temporary" values that were never removed after testing. In Terraform estates, the highest-risk cases are often not the main root module but the shared module defaults and example folders that get copied into real deployments.
Once you find embedded credentials, remove them from code, revoke or rotate the exposed value, and check whether the same secret appears in state, logs, or commit history. If the secret has been used in more than one place, assume the blast radius is larger than the file where you found it. For practical hardening guidance, OWASP Non-Human Identity Top 10 and OWASP Cheat Sheet Series both reinforce the need to avoid secret leakage and to manage credentials with least privilege and rotation in mind.
Risk and Threat Considerations
Hard-coded provider credentials create a durable compromise path: anyone who can read the code, cloned repository, plan output, or state backend may be able to authenticate as the Terraform execution identity. That turns a configuration mistake into an access problem, and in shared modules it can propagate to multiple environments before anyone notices.
Failure mechanism: A static secret is copied, cached, logged, or committed, then reused long after the original deployment context has changed. Attackers and curious insiders both benefit because the secret outlives the intended session or environment boundary.
Impact: The result can be unauthorized infrastructure changes, data exposure, privilege escalation, or persistent access through a credential that was never meant to be durable.
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 and OWASP API Security Top 10 address the attack and risk surface, while NIST SP 800-53 Rev 5 sets the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP Non-Human Identity Top 10 | NHI-02 — Secret Leakage | Hard-coded provider secrets are credential leakage in IaC. |
| NHI-07 — Long-Lived Secrets | Static provider credentials are long-lived secrets that should be replaced. | |
| NHI-05 — Overprivileged NHI | Terraform provider credentials often grant broad infrastructure access. | |
| Recommendation — Move provider auth out of code and prevent secret leakage into source, plans, and state. Use short-lived authentication instead of static provider credentials. Scope provider credentials to the minimum privileges needed for deployment. | ||
| OWASP API Security Top 10 | API2 — Broken Authentication | Provider auth failures and leaked static tokens both undermine authentication security. |
| Recommendation — Replace embedded provider credentials with stronger authenticated runtime flows. | ||
| NIST SP 800-53 Rev 5 | IA-5 — Authenticator Management | Covers credential lifecycle, rotation, and control of authenticators used by providers. |
| Recommendation — Rotate and manage provider credentials through a controlled lifecycle. | ||
Practitioner Guidance
What to verify: Confirm that provider authentication is inherited from the execution environment or injected at runtime, not declared as a literal in source, defaults, or example modules. Also verify that plans, logs, and state do not retain the secret in readable form.
Common mistake: Teams fix the top-level module but leave copied examples, test fixtures, or provider aliases with embedded values. Those secondary paths are often how the same secret reappears after the initial cleanup.
Practitioner takeaway: The real control is not “hide the secret better in Terraform”, it is to make the provider authenticate through a bounded, short-lived mechanism so code can be shared without sharing standing access.
Related resources from NHI Mgmt Group
- Guide: Infrastructure as Code Security Guide
- How do you patch or mitigate CVE-2020-8657 (EyesOfNetwork Use of Hard-Coded Credentials)?
- How do you patch or mitigate CVE-2026-22769 (Dell RecoverPoint for Virtual Machines (RP4VMs) Use of Hard-coded Credentials)?
- How do you patch or mitigate CVE-2019-6693 (Fortinet FortiOS Use of Hard-Coded Credentials)?
- How do you patch or mitigate CVE-2021-44207 (Acclaim Systems USAHERDS Use of Hard-Coded Credentials Vulnerability)?
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 20, 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org