Machine identities are created in seconds and almost never retired, so service accounts, API keys, OAuth apps and tokens outlive the projects, pilots and people that needed them. OWASP ranks improper offboarding first in its Non-Human Identities Top 10 for 2025, rating it easy to exploit, widespread and hard to detect. This guide covers how to retire non-human identities (NHIs) safely: deciding what to retire, staging the shutdown so nothing breaks, the platform mechanics on AWS, Google Cloud, Entra ID, GitHub and Kubernetes, AI agents and devices, and the evidence an auditor will ask for. It is written for identity, cloud platform and security engineering teams. Human leavers are covered in the Employee Offboarding Security Guide, which links back here for the NHIs a leaver owns.
Key takeaways
- Retirement is a lifecycle stage, not a clean-up project. Every NHI needs an owner, a purpose and an end condition recorded at creation, or nobody will know when to retire it.
- Disable, observe, then delete. AWS, Google Cloud and Entra ID all support a reversible state (inactive key, disabled service account, deactivated app); use it as a watch period before permanent deletion.
- Retire the credential, not just the account. Keys, client secrets, certificates, PATs, SSH keys, refresh tokens and copies in pipelines and vaults each need revoking; removing one object rarely removes the others.
- "Unused" is a claim to verify. Cloudflare left four credentials unrotated because it believed they were unused, and an attacker used them; decide on last-used telemetry, not memory.
- Keep evidence. A decommissioning record (who approved, what was revoked, when, what logs were preserved) is what turns a deletion into an auditable control under NIST SP 800-53 AC-2 and ISO/IEC 27001.
What NHI offboarding covers and why it fails
OWASP's NHI1:2025 Improper Offboarding describes three situations that leave live machine credentials behind. Each needs a different trigger, which is why a single "delete unused accounts" job does not solve the problem.
| Situation | Typical example | Trigger that should start offboarding |
|---|---|---|
| Stale or dormant NHI | Service account for an application that was switched off, test app left connected to production | Application or service retirement in the CMDB or change process; no use within the dormancy window |
| Orphaned NHI | API key created by an engineer who has left, with no new owner | Owner leaves or changes role (HR leaver or mover event); owner field empty in the inventory |
| Exposed but still needed | Shared secret an administrator saw, who then left; credential exposed in a supplier breach | Human leaver with access to the secret; third-party incident notice |
| Ended engagement | Pilot, proof of concept or supplier integration that finished | Contract end, project closure, failed pilot |
| Superseded credential | Old key left active after rotation, legacy Secret-based token after a move to workload identity | Rotation or migration completed |
The Klue incident shows the "ended engagement" case: a GitHub personal access token created for a 2022 pilot stayed active for about four years with write access to code, and in June 2026 it was used to push code that harvested customers' Salesforce OAuth tokens. See the Klue OAuth Breach 2026.
The Identity Governance for AI Agents Guide covers registering and owning agents; this guide starts where that ends, at retirement.
Deciding what to retire
Retirement decisions need three facts for every NHI: who owns it, what it is for, and when it was last used. Without an inventory these are guesses. See the Service Account Inventory Template and the NHI Ownership Guide.
- Last-used telemetry: AWS reports access key last use in the console and through
aws iam get-access-key-last-used, and IAM Access Analyzer's unused access analyzer reports unused roles, unused IAM user access keys and passwords, and unused permissions (a paid feature, priced per analyzer per month). Google Cloud and Entra ID expose sign-in and activity logs for service accounts and service principals. - Dormancy window: set one per class. CIS Controls v8.1 safeguard 5.3 asks for dormant accounts to be deleted or disabled after 45 days of inactivity; batch jobs that run quarterly or annually need a longer window and an explicit exception.
- Ownership: an NHI with no owner and no use is a retirement candidate by default. An NHI with no owner but active use needs an owner assigned before anything else, because removing it blind is how outages happen.
- Privilege weighting: retire high-privilege dormant identities first. A dormant account with write access to source code or tenant-wide mail permissions is a bigger risk than a dormant read-only reporting key.
| Signal | Retire | Keep and fix |
|---|---|---|
| No owner, no use in window | Disable now, delete after watch period | Only if a business owner claims it with evidence of need |
| No owner, active use | No | Assign owner, rotate credential, review scope |
| Owner known, purpose ended | Yes, owner approves | No |
| Owner known, used rarely | No | Document schedule, add exception to dormancy rule |
| Credential exposed in a breach | Revoke the exposed credential regardless of use | Issue a new credential if the identity is still needed |
A staged decommissioning process
The vendors' own guidance converges on the same pattern: make the identity unusable in a reversible way, watch for breakage, then delete. AWS advises waiting several days and checking last use before removing an old key, and its console requires a key to be deactivated before it can be deleted. Google recommends disabling a service account before deleting it so you can confirm nothing critical depends on it. Microsoft notes that deactivating an enterprise application prevents token issuance and sign-in while keeping its configuration.
- Record the decision. Open a change or ticket naming the NHI, owner, reason (stale, orphaned, ended, superseded, exposed) and approver. For production identities, the application owner and the platform owner both sign off.
- Map dependencies. Use last-used data, logs and code search to find every consumer: pipelines, scheduled jobs, integrations, secrets in vaults and CI variables. Search repositories for the key ID or client ID.
- Remove privilege first where possible. Stripping roles or scopes before disabling exposes hidden dependencies with a smaller blast radius and is easy to reverse.
- Disable (reversible state). Set the AWS key to Inactive, disable the Google service account, deactivate the Entra app or disable the service principal, suspend the SaaS integration user.
- Watch period. Hold for a defined time (for example 14 to 30 days, longer for identities with monthly or quarterly jobs) and alert on any authentication failure from the disabled identity. A failure means a missed dependency: re-enable, migrate the consumer, disable again.
- Revoke every credential. Delete keys, client secrets and certificates, revoke tokens and grants, remove SSH and deploy keys, and delete the secret from the vault and from CI variables so it cannot be restored by mistake.
- Delete the identity and its role bindings, group memberships and federated credentials.
- Preserve evidence (see below) and close the ticket with the final state.
Rollback: during the watch period rollback is a re-enable. After deletion, rollback is limited: Google Cloud allows a service account to be undeleted within 30 days, and Entra keeps a deleted enterprise application in the recycle bin for 30 days before hard deletion; an AWS access key deletion cannot be undone. Plan the watch period so permanent deletion only happens once you are confident.
Break-safe exception: when an identity is exposed (a supplier breach, a leaked key), skip the watch period for the exposed credential. Revoke it immediately and accept a possible outage; issue a replacement through the normal process. Cloudflare's November 2023 incident followed exactly this gap: after the Okta support breach it rotated thousands of credentials but skipped a Moveworks token, Smartsheet and Bitbucket service accounts and an AWS credential it mistakenly believed were unused. See the Cloudflare Thanksgiving Breach 2023 and the Secrets Rotation Runbook Template.
Platform mechanics
Each platform separates the identity from its credentials and from its permission bindings. Retiring one does not always retire the others.
| Platform | Reversible step | Permanent step | Watch out for |
|---|---|---|---|
| AWS IAM user keys | aws iam update-access-key --status Inactive | aws iam delete-access-key | Up to two keys per user; delete is unrecoverable; also delete the IAM user, its console password and any roles it alone used |
| Google Cloud service account | gcloud iam service-accounts disable | Delete; undelete possible within 30 days | Role bindings are purged within up to 60 days and show with a deleted: prefix; a new account with the same name is a different identity and blocks undelete |
| Entra ID enterprise app (service principal) | Deactivate, or disable sign-in | Remove-MgServicePrincipal; 30 days in recycle bin, then hard deleted | The app registration (application object) and its secrets and certificates are separate from the service principal; review both |
| GitHub organisation tokens | Revoke fine-grained PAT access in organisation settings | Owner deletes token; remove deploy keys and GitHub App installations | Owners cannot review classic PATs, which work until expiry unless the organisation restricts them; SSH keys created with a revoked fine-grained token keep working |
| Kubernetes service account | Remove RoleBindings and ClusterRoleBindings | Delete the ServiceAccount and any long-lived Secret-based tokens | Legacy token Secrets created before bound tokens; see the Kubernetes Service Account Token Guide |
| SaaS integration users and OAuth grants | Suspend the integration user or block the connected app | Revoke OAuth grants and refresh tokens, uninstall the app | Refresh tokens held by the vendor; see the SaaS and OAuth App Governance Guide |
The Midnight Blizzard intrusion at Microsoft began with a legacy test tenant account without MFA and a legacy test OAuth application that still held elevated access to the corporate tenant. A test app that should have been retired became the path to executive mailboxes. See the Microsoft Midnight Blizzard Breach 2024 and the Entra ID Applications and Consent Guide.
Retiring APIs, signing keys and certificates
- API decommissioning: when an API version is retired, remove its gateway routes and DNS records, revoke the API keys and OAuth clients issued for it, and delete its backend service identity. A route left open keeps the old authentication path alive. See the API Key Management Guide.
- Signing keys: retiring a token or code signing key means removing it from the verifier's trusted key set, not just stopping its use for signing. Until the verifier stops trusting it, anyone holding a copy can mint valid tokens. See the Code Signing Security Guide.
- Certificates: revoke certificates for retired services at the issuing CA, remove them from load balancers and trust stores, and delete the private key. See the Machine Identity, PKI and Certificate Lifecycle Guide.
- Package registry publish rights: remove publishing tokens and maintainers from npm, PyPI and container registry organisations when a contributor or pipeline stops releasing. The Mastra attack in June 2026 used a former contributor's account whose npm scope access was never revoked to republish more than 140 packages. See the Mastra npm Supply Chain Attack 2026 and the Software Supply Chain Security Guide.
AI agents and models
AI agents add identities faster than most estates can track: each agent may hold its own service principal, OAuth grants to SaaS tools, LLM API keys and tool credentials. Agent decommissioning should be triggered by the agent's owner, its registry entry or a failed periodic review, and must cover all of these together.
- Revoke delegated grants: OAuth consents an agent obtained on behalf of users survive the agent being switched off unless they are revoked at the identity provider or SaaS platform.
- Rotate model provider keys: LLM API keys tied to a retired agent are attractive for resale and abuse. See the LLMjacking Guide.
- Remove tool and MCP server credentials, scheduled triggers and webhooks, which can restart a "retired" agent.
- Model retirement: when a model version or endpoint is retired, delete the endpoint's service identity and access keys, and handle stored prompts, fine-tuning data and logs under the data retention policy.
- Shadow agents: agents nobody registered cannot be retired on schedule. Discovery comes first; see the Shadow AI Discovery Guide.
Devices and embedded identities
Device decommissioning has two parts: retiring the device's identity and sanitising the media. Revoke device certificates and remove the device object from the directory, MDM and IoT registry so its credentials cannot be replayed from a cloned image. Then sanitise storage following NIST SP 800-88 Rev. 2 (final, September 2025, superseding Rev. 1), which sets out how to build a media sanitisation programme matched to data sensitivity, including cryptographic erase. Embedded keys in OT and IoT equipment are often shared across a fleet, so retiring one unit may mean rotating the key for all of them. See the Device and IoT Identity Guide and the Embedded Device Security Guide.
Decommissioning evidence
Auditors and incident responders need to show both that an identity was retired and what it did before. Keep, for each retirement:
- Decision record: ticket ID, reason, owner and approver, date of disable and date of delete.
- Revocation proof: list of credential IDs revoked (key IDs, secret IDs, certificate serial numbers, token or grant IDs), not the secret values.
- Activity history: export the identity's last 90 days or more of authentication and API logs before deletion, because some platforms age logs out by object. See the Cloud Logging and Audit Trail Guide.
- Post-deletion check: a scan a week later confirming the identity, its bindings and its secrets are gone, and that no new identity with the same name has appeared.
The Coupang case shows why logs matter: Korean regulators reported that about 13% of logs for the attack period were lost, which limited what could be reconstructed. See the Coupang Breach 2025.
Detection and metrics
Watch for authentication attempts by disabled or deleted NHIs (a sign of a missed dependency or of an attacker holding a copy), new credentials added to old applications (ATT&CK T1098.001 Additional Cloud Credentials), and use of dormant cloud accounts (T1078.004).
| Metric | What it shows | Target direction |
|---|---|---|
| Percentage of NHIs with a named owner and end condition | Whether retirement can be triggered at all | Towards 100% |
| Dormant NHIs beyond the window (count and privileged count) | Retirement backlog | Down |
| Median days from retirement trigger to credential revoked | Offboarding lag | Down |
| Disabled NHIs re-enabled during watch period | Dependency mapping quality | Low and falling |
| Credentials still valid after their identity was deleted | Partial offboarding | Zero |
| Retirements with a complete evidence record | Audit readiness | 100% |
Small and large organisations
Small teams can start with native tools: AWS key last-used data, Google and Entra sign-in logs, a shared inventory spreadsheet and a monthly review. The disable, watch, delete pattern works without any extra product. Large estates with thousands of NHIs across clouds and SaaS need automated discovery and last-used correlation, typically from ISPM or NHI management tooling, with retirement workflows wired into the change process. See the ISPM Guide. In both cases, choose automatic disablement only for low-privilege identities with good telemetry; for production integrations, keep a human approval step.
Framework mapping
| Framework | Reference | How it applies |
|---|---|---|
| NIST SP 800-53 Rev. 5 | AC-2 Account Management, AC-2(3) Disable Accounts | Disable accounts that have expired, are no longer associated with a user or individual, or have been inactive for a defined period |
| NIST SP 800-53 Rev. 5 | IA-4 Identifier Management, IA-5 Authenticator Management | Retire identifiers and revoke authenticators (keys, certificates, tokens) |
| NIST SP 800-53 Rev. 5 | CM-8 System Component Inventory, SR-12 Component Disposal, MP-6 Media Sanitization | Inventory as the basis for retirement; device and media disposal |
| NIST CSF 2.0 | PR.AA-01, ID.AM-08 | Identities and credentials for services and hardware are managed; assets managed through their life cycles |
| CIS Controls v8.1 | 5.3 Disable Dormant Accounts, 6.2 Establish an Access Revoking Process | Dormancy window and revocation process |
| ISO/IEC 27001:2022 Annex A | 5.9 Inventory of information and other associated assets, 5.18 Access rights, 8.10 Information deletion | Inventory, removal of access rights, secure deletion |
| MITRE ATT&CK v20 | T1078.004 Cloud Accounts, T1528 Steal Application Access Token, T1195.002 Compromise Software Supply Chain | Techniques that abuse identities left behind |
| MITRE D3FEND | D3-CR Credential Revocation, D3-AL Account Locking | Defensive techniques that retirement implements |
Common failure patterns
- Deleting the account but not the credential: secrets copied into CI variables, vaults and config files survive, and some platforms keep separate objects (Entra app registration versus service principal, SSH keys created by a GitHub token).
- Trusting "unused" without data: Cloudflare skipped four exposed credentials it believed were unused, and an attacker used them within weeks.
- Pilots and test environments with no end date: Klue's 2022 pilot token and Microsoft's legacy test OAuth app both outlived their purpose with high privilege.
- Registry and code platform rights outside the IdP: npm, PyPI and GitHub publish rights are rarely tied to HR or IdP events, so former contributors keep them, as at Mastra.
- Signing keys left trusted: a key that is no longer used to sign but is still accepted by verifiers remains a live NHI, as the Coupang forged token case showed.
- Deleting without a watch period: hard deletes of production identities cause outages, and the resulting pain makes teams stop retiring anything.
Practitioner checklist
- Record owner, purpose and end condition (date, project or contract) for every new NHI.
- Set a dormancy window per NHI class and report identities beyond it weekly, privileged ones first.
- Wire HR leaver, project closure and contract end events to NHI ownership review.
- Use disable, watch, delete for planned retirements, with a defined watch period and alerting on failures.
- Revoke immediately, without a watch period, any credential exposed in a breach or supplier incident.
- Revoke every credential type: keys, secrets, certificates, PATs, SSH and deploy keys, OAuth grants, refresh tokens and vault copies.
- Remove retired signing keys from verifiers' trusted key sets.
- Remove registry publish rights and GitHub organisation access when contributors or pipelines stop releasing.
- Export activity logs and keep a decommissioning record before deletion.
- Re-scan a week after deletion to confirm identities, bindings and secrets are gone.
Standards and references
- OWASP: NHI1:2025 Improper Offboarding
- NIST: SP 800-53 Rev. 5
- NIST: SP 800-88 Rev. 2 Guidelines for Media Sanitization
- NIST: Cybersecurity Framework 2.0
- AWS: Update access keys
- Google Cloud: Delete and undelete service accounts
- Microsoft Learn: Delete an enterprise application
- GitHub Docs: Reviewing and revoking personal access tokens in your organization
Related NHI Mgmt Group resources: Top 10 NHI Risks · Joiner-Mover-Leaver Guide · NHI Ownership Attestation Campaigns Guide · Service Account Security Guide · Employee Offboarding Security Guide