frontdoor rule · FD020

Long-lived AWS access keys alongside OIDC federation

Long-lived keys alongside federation

Amazon Web Services, Google Cloud, Microsoft AzureUpdated Source on GitHub

Severity: medium.

What it means

The account uses federation — short-lived, audience-bound, revocable credentials — and also still has a static key sitting there. Both doors are open; only one of them is being watched.

Fires on a key that is active and either:

  • older than --max-key-age (default 90 days) and never rotated, or
  • never used, or
  • not used for --stale-days (default 90 days).

A fresh key in daily use is not flagged. That is how a lot of legitimate tooling still works, and burying the keys that matter under the ones that do not is how a finding gets ignored.

What an attacker does

Uses the key. From anywhere, indefinitely, with none of the short lifetime, audience binding or instant revocability that made federation worth adopting. A leaked static key in a git history, a CI log, or a laptop backup works until somebody notices — and a key that has never been used is a key nobody is watching for.

How to fix it

AWS

  1. CloudTrail, filtered to that access key id, tells you what still uses it.
  2. If nothing does, delete it.
  3. If something does, give that workload a role and let it assume the role through the OIDC provider you already have.
  4. Deactivate before deleting and wait a cycle, so a surprise consumer fails loudly rather than silently at 3am.

GCP

bash
gcloud iam service-accounts keys delete KEY_ID --iam-account=SA_EMAIL

Then set constraints/iam.disableServiceAccountKeyCreation as an org policy so the next one is not created.

Azure — remove the client secret or certificate from the app registration once its federated credential is working.

A reporting difference worth knowing

AWS reports when an access key was last used. GCP and Entra ID do not. For those, frontdoor flags on age and says "last use not reported by GCP" rather than "never used" — because those are different claims and only one of them is true.

frontdoor answers this once, when you run it; Secorvia checks it continuously across every account you connect, on a free tier that needs no card.