Service accounts, workload identities and secrets: avoiding long-lived keys
In short: Applications need identities too, and they often outnumber people. Long-lived keys stored in code or pipelines are a leading cause of cloud breaches. Platform-issued workload identities and federation give short-lived credentials automatically, so there is no secret to leak.
Non-human identities
Every virtual machine, function, container and deployment pipeline that calls a cloud API needs an identity. These non-human or workload identities usually far outnumber staff accounts and are easy to forget. They often have broad permissions, no MFA and no owner, which makes them attractive to attackers.
The traditional approach was a service account with a password or an access key (an ID plus a secret) pasted into a configuration file. Those keys tend to live for years, get copied into source code, chat messages and laptops, and turn up in public repositories.
Platform-issued identities
Each major cloud can give a workload an identity without any stored secret. The platform delivers short-lived credentials through a local metadata endpoint, and the SDK picks them up automatically.
| Platform | Feature | Used by |
|---|---|---|
| AWS | IAM roles (instance profiles, task roles, execution roles) | EC2, ECS, Lambda, EKS pods |
| Azure | Managed identities (system- or user-assigned) | VMs, App Service, Functions, AKS |
| Google Cloud | Attached service accounts, Workload Identity Federation for GKE | Compute Engine, Cloud Run, GKE |
| Kubernetes | Projected service account tokens | Pods calling the API server or a cloud |
On AWS EC2, require IMDSv2 (Instance Metadata Service version 2), which uses a session token and makes it much harder for a server-side request forgery bug to steal the instance's role credentials.
Workload identity federation
Workloads outside a cloud, such as a GitHub Actions or GitLab pipeline, can also avoid stored keys. The CI system issues a signed OpenID Connect token describing the job (repository, branch, environment). You configure the cloud to trust that issuer and to accept only tokens with specific claims, for example only the main branch of one repository. The cloud then exchanges the token for temporary credentials.
Tip: make the trust condition specific. Trusting every repository in an organisation, or any branch, lets a pull request from a fork or a test branch deploy to production.
When you must have a secret
Some third-party APIs and databases still need passwords or keys. In that case:
- Store the secret in a managed secret store such as AWS Secrets Manager, Azure Key Vault or HashiCorp Vault, not in code or plain environment files.
- Let the workload read it using its platform identity, so only the vault access needs governing.
- Rotate it automatically on a schedule and after any suspected exposure.
- Enable secret scanning in your repositories and pipelines to catch leaks early.
- Give every service account an owner, a description and a review date.
A useful quick check: list all access keys in your cloud accounts with their age and last use. Keys older than 90 days, or unused for months, are candidates for removal. For background on hashing and why secrets must never be stored in plain text, try the hash tool.
Practice
A developer commits an AWS access key to a public repository and deletes it a minute later. Is the key safe?
What does an Azure managed identity remove from your application?
Why restrict a federated CI trust to one repository and branch?
Key takeaways
- Workloads need identities and often outnumber people.
- Long-lived keys leak through code, pipelines and laptops.
- Use IAM roles, managed identities and attached service accounts instead.
- Federate CI/CD with OIDC and tight trust conditions.
- If a secret is unavoidable, vault it, rotate it and scan for leaks.
Original content written by Mohamed Fayas for FM TecHub. © 2026 FM TecHub. You're welcome to share a link to this page; please don't copy the text elsewhere without permission.