Service-account key sprawl still haunts Google Cloud: 62% of audited projects ship long-lived JSON keys
We reviewed 340 customer projects over six months. Workload Identity Federation is available in every one of them, yet downloaded keys keep landing in CI variables and private repos. The migration is shorter than most teams expect.
We reviewed 340 Google Cloud projects across six months of audit work. In 62% of them, at least one service account had a downloaded JSON key that was still valid.
Why the key is the problem
A service-account key is a private credential with no expiry. It works from anywhere, it is trivially copied, and it survives the departure of whoever created it. Once it lands in a CI variable, a private repository, or a laptop, you have lost track of it — and rotating it means finding every copy first.
Workload Identity Federation removes the key entirely. The workload proves its identity with a token its own platform already issues, and Google exchanges that for short-lived credentials.
Where the keys actually live
| Location | Share of findings |
|---|---|
| CI/CD variables | 41% |
| Private Git repositories | 23% |
| Developer laptops | 19% |
| Kubernetes secrets, unencrypted | 11% |
| Documentation and wikis | 6% |
The wiki entries are the ones that tend to be oldest.
The migration is shorter than teams expect
- Inventory the keys. List service-account keys across every project and record who uses each one.
- Start with CI. GitHub Actions, GitLab CI and Cloud Build all support federation directly, and this is where most keys live.
- Configure a workload identity pool with a provider for each external platform, mapping its token claims to a principal.
- Grant the pool principal the role the service account had, then swap the workflow over.
- Disable the old key before you delete it — disabling is reversible, deleting is not.
- Add an org policy that forbids service-account key creation, so the problem does not come back.
Most teams complete a workload in under a day. The hard part is not technical: it is finding an owner for the keys nobody remembers creating.
The org policy is the real fix
Constraint iam.disableServiceAccountKeyCreation prevents new keys at the organisation level. Apply it with exceptions for the projects that genuinely need one, and the sprawl stops growing while you clean up what exists.