Most long-lived secrets survive not because teams like them but because the application that uses them reads a password from a config file once at start-up and cannot be changed. Moving that application to credentials that expire in minutes or hours needs an adapter between the credential issuer and the code: a file renderer, a credential process, a local metadata endpoint or a connection proxy. This guide shows how to assess how a legacy application consumes credentials, which adapter fits each consumption pattern on AWS, Azure, Google Cloud and HashiCorp Vault, and how to cut over and roll back without an outage. It is for platform engineers, application owners and NHI programme leads. For how dynamic secrets engines and token lifetimes work, see the Dynamic Secrets and Ephemeral Credentials Guide; for cryptographic changes on the same estate, see the Post-Quantum Migration for NHIs Guide.
Key takeaways
- Classify consumption before choosing a tool. Whether the application reads its credential per connection, on a timer, at start-up or only at build time decides the adapter, the restart needs and the safe lifetime.
- Adapters move the secret, not the code. Vault Agent templates, the IAM Roles Anywhere signing helper, Azure Arc's local identity endpoint, Google executable-sourced credentials and database auth proxies each let unmodified software use expiring credentials.
- The adapter becomes the new secret zero. Every adapter needs its own bootstrap identity, such as a certificate, a machine identity or an auth method, and that identity must be stronger than the secret it replaces.
- Keep the old credential valid but unused during cutover. Rollback is a configuration switch only while the static secret still works; revoke it after a quiet period, not on cutover day.
- Some systems will not move. Software that cannot reload credentials and cannot sit behind a proxy should get managed rotation of its static secret and tighter monitoring, documented as an exception.
Why legacy applications hold long-lived secrets
The OWASP NHI Top 10 lists long-lived secrets as NHI7, and NIST SP 800-53 Rev. 5 control IA-5(7) No Embedded Unencrypted Static Authenticators addresses the most common form directly. The obstacles in legacy estates are practical rather than policy:
- Read once: the application loads its configuration at start-up and keeps the credential in memory until restarted.
- Fixed formats: credentials live in property files, INI files, environment variables or Windows registry keys that the vendor documents and supports.
- Long-held connections: connection pools keep sessions open for days, so a database password change is invisible until a reconnect fails.
- No cloud identity: on-premises servers have no instance metadata service to issue platform credentials.
- Vendor support terms: changing how a packaged application authenticates may void support.
The cost of leaving these alone is well documented. In the EmeraldWhale campaign, Sysdig found attackers harvesting more than 15,000 cloud credentials from exposed Git configuration files and environment files, the kind of static, file-based secrets this migration removes. ATT&CK v20 tracks the theft as T1552.001 Credentials In Files.
Assessing how an application consumes credentials
For each application, answer these questions from code, configuration and a test run, not from documentation alone:
| Question | How to find out | Why it matters |
|---|---|---|
| Where does the credential come from? | Config file, environment variable, registry, command-line argument, compiled-in value | Determines whether a file renderer or environment injector can supply it |
| When is it read? | Change the value on a test host and observe: per connection, on a timer, on reload signal, at start-up only | Start-up-only readers need a restart on every rotation |
| Can it reload without restart? | Vendor documentation; test a reload signal or admin endpoint | A reload hook allows much shorter lifetimes |
| How long are connections held? | Pool maximum lifetime settings; database session views | Credentials must outlive the longest connection, or the pool must recycle sooner |
| Does the client support a credential provider? | AWS SDK credential chain, Google client libraries with credential configuration files, MSAL or Azure Identity libraries | Supported SDKs refresh tokens themselves |
| Does the target accept token authentication? | Database engine and version; API documentation | If yes, a proxy or token plugin can remove the password entirely |
| What breaks if the credential is invalid for one minute? | Failure test in non-production | Sets the safety margin between refresh and expiry |
Group applications by the answers. A typical estate falls into four buckets: SDK-based applications that only need an identity, file or environment readers that can be restarted, applications that hold database connections, and applications that cannot change at all.
Adapter patterns
| Pattern | How it works | Fits | Watch out for |
|---|---|---|---|
| File rendering agent (Vault Agent templates) | Agent authenticates, fetches secrets and writes them to a destination file in the application's existing format; exec runs a command when the rendered output changes | Applications that read a config file; restart or reload via the exec command | File permissions (perms), restart storms, rendered secrets on disk |
| Environment injection (Vault Agent process supervisor mode) | Agent renders env_template blocks into the child process environment and supervises it | Applications configured by environment variables | Every rotation means a process restart |
| Credential process | The SDK calls an external command that returns temporary credentials as JSON | AWS SDK and CLI clients on any host; IAM Roles Anywhere via aws_signing_helper credential-process | The command's own credential (certificate and key) must be protected |
| Local metadata endpoint | A local service imitates the cloud metadata endpoint so unmodified SDKs fetch tokens | aws_signing_helper serve on 127.0.0.1:9911; Azure Arc-enabled servers on localhost:40342 | Any local process that can reach the endpoint may get tokens; Arc uses a challenge file restricted to privileged groups |
| Federated credential configuration | A credential configuration file (no secret inside) tells Google client libraries how to obtain an external token and exchange it | Workloads outside Google Cloud with an OIDC or SAML source; file, URL or executable-sourced | Executable sources need GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES=1; file sources must be refreshed before expiry |
| Database auth proxy | A local proxy authenticates to the database with platform identity; the application connects to localhost | Cloud SQL Auth Proxy; applications that cannot handle tokens | No pooling in Cloud SQL Auth Proxy; run as a supervised service |
| Token as password | The application or a driver plugin generates an IAM token and presents it as the database password | Amazon RDS IAM database authentication for MariaDB, MySQL and PostgreSQL | Tokens last 15 minutes and are about 1 KB; tools that truncate passwords fail |
| Managed static rotation | The secret stays static in shape but is rotated by the platform and delivered by an adapter | Applications that cannot change usernames or handle tokens | Still a long-lived secret between rotations; treat as an exception |
Platform specifics
- Vault Agent renewal timing: Agent renews renewable secrets after two thirds of the lease, re-fetches non-renewable leased secrets such as dynamic database credentials at 90 per cent of the TTL (adjustable with lease_renewal_threshold) and polls KV v2 secrets every five minutes by default (static_secret_render_interval). Set error_on_missing_key to true, as HashiCorp recommends, so a missing field fails loudly instead of rendering an empty password. HashiCorp also notes that Agent is not a replacement for a process monitor, so run the application under systemd or a service manager.
- IAM Roles Anywhere: the signing helper exchanges an X.509 certificate for session credentials with a session duration from 900 to 43,200 seconds. The update mode writes credentials to the AWS credentials file and refreshes about five minutes before expiry; prefer credential-process or serve so credentials stay in memory. Keys can sit in a TPM or behind PKCS#11. See the AWS IAM Roles Anywhere Security Guide.
- Azure Arc: the local identity endpoint issues Entra tokens only after the caller reads a challenge secret from a file that only the local Administrators or Hybrid Agent Extension Applications group (Windows) or the himds group (Linux) can read, so the application's service account needs that membership. See the Azure Managed Identities Security Guide.
- Google Cloud: the credential configuration file contains no private key; the service account access token it leads to lasts one hour by default. Cloud SQL Auth Proxy uses ephemeral certificates that expire in about an hour and are refreshed automatically.
- Amazon RDS: IAM authentication needs 300 to 1,000 MiB of extra memory on the instance, and granting the rds_iam role to a PostgreSQL user stops that user logging in with a password, which is a useful cutover lever but a sharp rollback edge.
Choosing the adapter
| Application profile | First choice | Fallback |
|---|---|---|
| Uses a current cloud SDK, runs in that cloud | Native workload identity; delete the key | None needed |
| Uses a cloud SDK, runs on-premises | Roles Anywhere credential-process, Azure Arc managed identity, or Google credential configuration with executable source | Vault-issued cloud credentials rendered to a file |
| Reads a config file at start-up | File rendering agent with a restart command and a lifetime of hours or days | Managed static rotation with scheduled restart |
| Supports reload signal | File rendering agent with reload command and short lifetimes | Same with longer lifetimes |
| Connects to a database that accepts IAM tokens | Auth proxy on the host | Driver plugin generating tokens |
| Packaged application, no changes allowed | Managed static rotation through the vendor's supported config path | Exception with compensating monitoring |
Small organisations with a few legacy servers can often use the cloud provider's own adapter (Roles Anywhere, Arc or federation) and avoid running a broker. Large estates with many databases and mixed clouds usually standardise on one agent pattern for file and environment delivery, which gives one runbook and one audit trail, and treat native identity as the target for anything rebuilt.
Migration procedure
- Inventory and rank: list static credentials by target, privilege, age and exposure (files on disk, repositories, images). Start with high-privilege, widely copied secrets.
- Assess consumption: run the assessment table for each application and assign it to a bucket.
- Establish the adapter's identity: issue the certificate, onboard the server to Arc, configure the Vault auth method or federation trust. This is the new bootstrap; see the Secrets Zero Problem Guide.
- Pilot in non-production: deploy the adapter, point the application at its output, and test expiry mid-operation, adapter stopped, issuer unavailable and restart during peak load.
- Set lifetimes from evidence: lifetime must exceed the refresh interval plus the longest restart or reconnect time, with margin. Start longer, then shorten once refresh is proven.
- Run in parallel in production: switch the application to the adapter while the old static credential stays valid but unused. Confirm from the target's logs that only the new identity or new credentials are used.
- Roll back if needed: revert the configuration to the static credential, which still works. Record why, fix, and repeat.
- Retire the static credential: after an agreed quiet period, disable it, then delete it. Remove copies from files, images and repositories, and scan to confirm.
- Template and repeat: capture the adapter configuration as code per bucket and onboard the next wave.
Where identity fits
This migration changes what an application is from a holder of a shared password into a workload with its own identity. That brings benefits beyond expiry: logs show which workload acted, permissions can be scoped per workload, and revocation targets one identity instead of every consumer of a shared secret. It also brings a duty: register each new workload identity with an owner and purpose in the NHI inventory, and review it like any other non-human identity. Where an adapter uses a certificate, track its expiry and issuance as part of machine identity management. See the OWASP NHI Top 10 NHI7 Long-Lived Secrets Guide and the Workload Identity Federation Guide.
Detection and measurement
- Use of retired credentials: after cutover, alert on any authentication with the old static credential; it indicates a missed consumer or a stolen copy.
- Refresh failures: monitor adapter logs for authentication failures and render errors, and alert before credentials expire, not after.
- Token use from unexpected hosts: short-lived tokens should be used only from the host that obtained them; flag use from elsewhere.
- Gaps in native logging: CloudTrail and CloudWatch do not log RDS IAM authentication or generate-db-auth-token calls, so rely on database logs for those connections.
Metrics: share of in-scope applications using credentials with a lifetime under 24 hours; number of static credentials retired per quarter; number of documented exceptions and their review dates; incidents caused by credential expiry (should fall after the first waves); median days from pilot to retirement of the static credential.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| NIST SP 800-53 Rev. 5 | IA-5 Authenticator Management; IA-5(7) No Embedded Unencrypted Static Authenticators; IA-5(13) Expiration of Cached Authenticators | The core requirement this migration meets |
| NIST SP 800-53 Rev. 5 | SC-12 Cryptographic Key Establishment and Management; AC-2(3) Disable Accounts | Adapter certificates and retiring static accounts |
| NIST CSF 2.0 | PR.AA-01, PR.AA-05 | Managing service identities and least privilege |
| OWASP NHI Top 10 | NHI7 Long-Lived Secrets | Risk being reduced |
| MITRE ATT&CK v20 | T1552.001 Credentials In Files; T1078 Valid Accounts | Theft and misuse that short lifetimes limit |
Common failure patterns
- Lifetime shorter than the restart: credentials expire while a slow application is still starting, causing a loop of failed starts.
- Connection pools outliving credentials: pool maximum lifetime longer than the credential lifetime means failures appear hours later, at reconnect.
- Weak adapter bootstrap: replacing a database password with a Vault token stored in the same config file changes nothing.
- Credentials written to world-readable files: rendering agents and update modes put secrets on disk; set perms and run the application under its own account.
- Static credential revoked on cutover day: removes the only quick rollback when an unknown consumer surfaces.
- Old copies left behind: the secret is retired in the vault but still sits in an old image, a backup of the config file or a repository, as the EmeraldWhale harvest of Git configuration files shows.
Practitioner checklist
- Inventory static credentials in legacy applications with owner, target, privilege and every location they are stored.
- Run the consumption assessment and assign each application to an adapter bucket.
- Choose the adapter per bucket and document its bootstrap identity and how that identity is protected.
- Pilot each pattern in non-production with expiry, outage and restart tests.
- Set credential lifetimes from measured refresh and restart times, then shorten in steps.
- Cut over with the static credential still valid; confirm from target logs that it is unused.
- Retire the static credential after the quiet period and scan for remaining copies.
- Alert on any use of retired credentials and on adapter refresh failures.
- Record exceptions with compensating controls and a review date.
Standards and references
- NIST: SP 800-53 Rev. 5
- HashiCorp: Vault Agent templates
- AWS: IAM Roles Anywhere credential helper
- AWS: IAM database authentication for Amazon RDS
- Microsoft Learn: Authenticate against Azure resources with Azure Arc-enabled servers
- Google Cloud: Workload Identity Federation with other providers
- Google Cloud: About the Cloud SQL Auth Proxy
Related NHI Mgmt Group resources: Dynamic Secrets and Ephemeral Credentials Guide · Secrets Zero Problem Guide · Post-Quantum Migration for NHIs Guide · Secrets Rotation Runbook Template