Stale & long-lived credentials
Long-lived credentials are the quiet debt of a cloud estate: static access keys, service-account keys, and application secrets that were issued once to make something work and then never expired, rotated, or got cleaned up. Because they carry no session boundary, a single leak — in a public repo, a build log, a laptop backup, a stale Terraform state file — hands an attacker durable access that keeps working long after the person who created it has left. This page focuses specifically on the age, rotation, and dormancy dimension of identity: not whether a credential is over-privileged, but whether it should still exist at all and how it is issued going forward. We assess it as a read-only review of credential metadata — key age, last-used timestamps, active-key counts, and expiry policy — across your AWS, Azure, and Google Cloud accounts. Nothing is rotated, disabled, or deleted by us; the output is an evidence-backed inventory your team acts on.
Overview
What this check looks like in practice
Static keys that never expire are the credential most likely to leak and least likely to be noticed. Old access keys, unrotated service-account keys, and dormant users are standing liabilities.

Why it matters
From an attacker's point of view, a long-lived key is the ideal foothold: it does not trigger an MFA prompt, it does not expire on its own, and it often lives outside the logging most teams actually watch. Leaked static keys are one of the most common root causes in cloud incident reports precisely because they are so easy to exfiltrate and so rarely rotated. From an auditor's point of view, credential age and rotation are directly testable controls — a report that shows keys older than the policy threshold, or dormant identities that were never deprovisioned, is a finding they will write up under SOC 2, PCI-DSS, and CIS. The deeper problem is that dormant credentials also mask lateral movement: if an old key is used, nobody notices, because nobody expected it to be used at all. Reducing the population of standing credentials shrinks both the attack surface and the number of things you have to monitor.
What we assess
What we look for
- Access keys and service-account keys older than your rotation threshold (commonly 90 days), and any key with no last-used timestamp at all
- Identities — human users and service accounts — with no sign-in or API activity for an extended dormancy window, indicating deprovisioning gaps
- Multiple simultaneously active keys on a single identity, which usually means a rotation was started and never finished (the old key was never deleted)
- Root or top-level account access keys, which should not exist at all on any of the three clouds
- Whether preventive expiry and rotation controls are enforced by policy (key-expiry constraints, disable-key-creation org policy) rather than left to manual discipline
- Long-lived application secrets and certificates on service principals / OAuth apps that are near or past expiry, or set to multi-year lifetimes
- Credentials embedded in source code, container images, CI/CD variables, or infrastructure-as-code state, which are static by nature and cannot be centrally rotated
- Absence of short-lived alternatives (OIDC federation, workload identity, managed identities) where a static key is currently doing a machine-to-machine job
Across your clouds
AWS, Azure & Google Cloud
AWS
We pull the IAM credential report to age every access key and console password, cross-reference access-key last-used data (and service-last-accessed / Access Advisor signals) to spot identities that have gone quiet, and use IAM Access Analyzer unused-access findings to surface dormant keys and roles. Root access keys, keys past the rotation threshold, and any IAM user carrying two active keys are flagged.
Azure
We review Entra ID service principal and app-registration client secrets and certificates for long lifetimes and near-expiry, check managed-identity coverage where static secrets are still in use, and use Entra sign-in logs plus access reviews to find dormant users and service principals that were never deprovisioned.
Google Cloud
We age user-managed service-account keys, check whether the org-policy constraints iam.disableServiceAccountKeyCreation and iam.serviceAccountKeyExpiryHours are enforced, and use IAM Recommender / activity insights and Security Command Center to find unused service accounts and keys — flagging any that should move to workload identity federation.
Example finding
A production service account with two active keys, the oldest 640 days old and never rotated
Risk: The stale key predates the current team, is not tracked in the secrets vault, and shows sporadic use from an unexpected source range — a classic signature of a leaked credential that still grants API access and would not prompt for MFA.
Fix: Confirm which key the live workload actually uses via last-used data, migrate the workload to workload identity federation or a managed identity, delete both static keys once the cutover is verified, and enforce a key-expiry / disable-key-creation org policy so new long-lived keys cannot be minted.
Remediation
How to close it
- 1 Inventory every static credential across accounts — access keys, service-account keys, app secrets, certificates — with age and last-used data, so you are working from evidence, not guesses.
- 2 Retire the clearly dead first: delete keys and disable identities with no activity in the dormancy window, after a short confirmation window, starting with the highest-privilege ones.
- 3 For credentials that are in use, verify which key is live via last-used timestamps, then complete rotations end to end — issue the new secret, cut over, and delete the old one rather than leaving both active.
- 4 Replace machine-to-machine static keys with short-lived alternatives: OIDC federation for CI/CD, workload identity federation on GCP, and managed identities on Azure.
- 5 Enforce prevention in policy, not discipline: set key-expiry and disable-key-creation org policies, require rotation thresholds, and route all remaining secrets through a managed vault with rotation and an audit trail.
- 6 Add ongoing detection so age and dormancy are caught as they recur — scheduled credential-report review and alerts on new long-lived keys — since this is drift that returns without a standing control.
Compliance evidence
Questions
Isn't rotating keys enough — why remove long-lived credentials entirely?
Rotation shortens the window a leaked key is useful, but it is still a manual control that fails silently when someone forgets. Removing static keys in favor of short-lived, automatically issued credentials (OIDC, workload identity, managed identities) eliminates the standing liability instead of managing it, which is why we flag both unrotated keys and the opportunity to retire the key type altogether.
How do you tell a dormant credential apart from a rarely-used but legitimate one?
We use last-used metadata — access-key last-used data on AWS, sign-in logs on Azure, activity insights on GCP — rather than age alone, and we bring the candidates to your team before anything is recommended for removal. The assessment is read-only, so we identify and rank; you confirm and act.
Does finding embedded secrets in code count under this topic or secrets management?
There is overlap. Here we care about embedded credentials because they are inherently long-lived and can't be centrally rotated, so a hard-coded key is always a stale-credential risk. The broader lifecycle — vaulting, scoped access, and audit trails for secrets — is covered in depth under the secrets management sub-topic.
See where you stand
A health check finds and prioritizes real exposure. It is not a certification or a promise you will never be breached — closing the findings is what changes your risk.
Related domain surfaces
The rest of what we assess
The same read-only assessment covers every domain — see what else it looks at.




