When a developer's laptop is compromised, the incident is not the laptop: it is every token, key and session that laptop could use, and every repository, package and pipeline those credentials can change. A developer workstation typically holds Git credentials, SSH keys, cloud CLI sessions, kubeconfig files, package registry publishing tokens, AI API keys and signed-in browser sessions to source control and CI. This playbook template gives [Organisation] a response for a confirmed or suspected developer workstation compromise, whatever the entry route: an infostealer, a malicious IDE or browser extension, a poisoned repository, a malicious package or a remote access trojan. It is for incident leads, SOC analysts, platform engineers and engineering managers, and it sits beside the narrower playbooks for packages, extensions and AI coding agents linked below.
How to use this template
- Adopt it as a sub-playbook of [Organisation]'s incident response plan. See the Incident Response Plan Template.
- Pre-fill the credential map in section 4 for your standard developer build before an incident. Under pressure, nobody remembers that the Terraform CLI, the container registry and the AI assistant each cache their own credential.
- Work from a clean device. Every revocation and rotation step is done from a trusted machine, never from the affected workstation, because anything typed there may be captured.
- Keep decision points explicit. Each "Decision" line names who decides and on what evidence.
- Use the right sibling playbook when the cause is known: the Malicious Open Source Package Response Playbook, the Malicious Package Worm Response Playbook, the Malicious Browser Extension Incident Playbook or the AI Coding Agent Incident Playbook. This template covers the workstation and its credentials in every case.
1. Scope and triggers
1.1 This playbook applies to any [Organisation] laptop, desktop, virtual desktop or cloud development environment used to write, build, sign or deploy code, including contractor devices with access to [Organisation] repositories, where there is evidence or reasonable suspicion that untrusted code ran or an attacker had access.
1.2 Common entry routes and the techniques to record in the case:
| Entry route | ATT&CK | What it means for response |
|---|---|---|
| Malicious IDE extension or extension update | T1176.002 IDE Extensions | Other developers with the same extension are in scope; check the extension ID across the fleet |
| Malicious browser extension | T1176.001 Browser Extensions | Signed-in sessions to source control, cloud consoles and CI are at risk |
| Malicious package or build script run locally | T1195.002 Compromise Software Supply Chain | Install-time code ran with the developer's full rights |
| Infostealer collecting browser data | T1555.003 Credentials from Web Browsers, T1539 Steal Web Session Cookie | MFA-satisfied sessions can be replayed; a password reset alone is not enough |
| Theft of credential files (.npmrc, .git-credentials, cloud CLI config, kubeconfig, .env) | T1552.001 Credentials In Files | Every file in the credential map is presumed copied |
| Theft of SSH or signing private keys | T1552.004 Private Keys | Servers, Git hosts and signing trust are in scope |
| Use of stolen tokens against source control or cloud APIs | T1550.001 Application Access Token | Look for pushes, releases and API calls from new networks |
| Cloning or reading private repositories | T1213.003 Code Repositories | Possible source code and embedded secret exposure |
1.3 Triggers: EDR detection of an infostealer or remote access tool on a developer device; an IDE or package process spawning a shell, downloading a binary or contacting a newly registered domain; a source control alert for an unknown SSH key, new personal access token or push from an unfamiliar network; a registry notice of a package version the owner did not publish; a cloud alert for API calls from a developer's identity at an unusual hour or location; an infostealer log entry naming an [Organisation] developer. See the Infostealer Logs Monitoring and Response Guide.
1.4 Severity: Critical if the developer holds production deployment rights, package publishing rights, code signing keys or administrator rights on source control or cloud; High for any other developer with write access to [Organisation] repositories; Medium where untrusted code was present but evidence shows it never executed.
2. Roles and contacts
| Role | Named lead | Responsibilities |
|---|---|---|
| Incident lead | [Name, phone] | Declares the incident, sets severity, owns the timeline and decision log |
| SOC and endpoint analyst | [Rota] | EDR isolation, triage, fleet-wide search for the same indicator |
| Source control administrator | [Name] | Revokes tokens and keys, reviews organisation audit log, protects branches |
| Cloud and platform engineer | [Name] | Revokes cloud sessions and keys, reviews cloud audit logs, Kubernetes access |
| Package and release owner | [Name] | Registry tokens, published versions, signing keys, deprecation or yank decisions |
| Affected developer and their manager | [Name] | Lists what was on the device, confirms legitimate activity, works on a loaner device |
| Forensics | [Internal or retained provider] | Memory and disk acquisition, timeline |
| Legal, privacy and communications | [Name] | Notification decisions, customer and registry communication |
3. Detection and triage
3.1 Confirm the device, the user and the earliest suspicious event. Record the EDR detection, process tree, any extension or package identifier, and network destinations.
3.2 Interview the developer from a separate channel: what they installed, cloned or ran in the last 14 days, which tools are signed in, and whether they use the device for personal accounts or other clients.
3.3 Search the fleet for the same indicator (extension ID and version, package name and version, file hash, domain). A shared extension or dependency means more than one workstation.
3.4 Decision (incident lead, with endpoint analyst): treat as confirmed compromise if untrusted code executed with the user's rights, or any credential from the device was used from an unfamiliar source. If in doubt, proceed: revoking developer credentials is disruptive but recoverable.
4. Containment
4.1 Isolate the workstation through EDR network containment. Do not power it off before memory acquisition if forensics is in scope. Issue the developer a clean loaner device.
4.2 Work through the credential map below from a trusted machine, highest blast radius first. For each credential, record the identifier, the time revoked and who did it.
| Credential on the workstation | Typical location | Containment action |
|---|---|---|
| Source control personal access tokens and OAuth app tokens | Git credential helper, IDE, CLI config | Revoke every token for the user. On GitHub, token types are identifiable by prefix (ghp_, github_pat_, gho_, ghu_, ghr_) and a revoked token cannot be restored; the user's "revoke all credentials" option, or organisation owners revoking SSO authorisations, cut access in one step |
| SSH keys for Git hosts and servers | ~/.ssh, ssh-agent, hardware key | Delete the public keys from Git hosts and from authorized_keys on servers. See the SSH Key Compromise Response Playbook |
| Identity provider sessions | Browser profiles, desktop apps | Disable or block sign-in, revoke refresh tokens and sessions. In Microsoft Entra ID, Revoke-MgUserSignInSession invalidates refresh tokens, but issued access tokens stay valid until they expire (one hour by default) unless the app supports continuous access evaluation |
| AWS CLI keys and role sessions | ~/.aws/credentials, SSO cache | Deactivate the user's access keys, revoke active role sessions for roles the user assumed, then review CloudTrail for keys, roles or policies the user did not create |
| Google Cloud CLI and Application Default Credentials | gcloud config directory, application_default_credentials.json | Revoke the user's OAuth grant for the Google Cloud CLI (user OAuth tokens can be revoked at the Google revocation endpoint); suspension or password reset alone does not invalidate tokens an attacker holds. Google Cloud documents that service account access tokens remain valid until they expire, so disable the service account or apply a deny policy if its key was on the device |
| Azure CLI and PowerShell tokens | Token cache in the user profile | Covered by the identity provider session revocation above; rotate any service principal secret stored on the device |
| Kubeconfig files | ~/.kube/config | Rotate the credentials it holds. See the Leaked Kubeconfig Response |
| Package registry tokens | .npmrc, .pypirc, registry CLI config | Revoke them. For npm, npm token list and npm token delete by token ID; npm's docs say revocation can take up to an hour, so watch for publishes in that window |
| Container registry credentials | Docker config, credential helper | Revoke and reissue |
| Code or artefact signing keys | Key files, keychains, hardware tokens | Revoke or suspend; follow the Compromised Code Signing Certificate Playbook |
| AI and SaaS API keys | .env files, IDE settings, shell history | Rotate in each provider console |
| Secrets in local project files | .env, test configs, scratch scripts | Treat as leaked: follow the Leaked Credential Response Playbook |
4.3 Protect what the credentials could change: temporarily require review on protected branches and release workflows for repositories the developer could write to, and pause automated publishing for packages they own until section 5 is complete.
4.4 Decision (incident lead, with platform owner): if the developer held standing production or publishing rights, consider freezing deployments for the affected services until pushes and releases are verified.
5. Eradication
5.1 Reimage the workstation from a known-good build. Cleaning in place is not acceptable for a device that ran untrusted code with developer rights.
5.2 Review source control for attacker actions since the earliest suspicious event: new SSH keys, tokens, OAuth authorisations and two-factor changes in the user's security log (GitHub keeps 90 days and supports filtering by operation, repo and actor, with JSON or CSV export); new deploy keys, webhooks, Actions workflow changes, branch protection changes and membership changes in the organisation audit log (GitHub organisation audit logs list 180 days of events).
5.3 Verify every commit, tag and release pushed by the user's identity in the window. Revert anything the developer does not recognise. See the GitHub Organisation Compromise Playbook if attacker activity reached organisation settings.
5.4 Review registries for versions published by the user's tokens. Deprecate or remove unauthorised versions and notify the registry where its process requires it.
5.5 Review cloud audit logs for the user's identities: new access keys, users, roles, service account keys, project-level SSH keys and resources in all regions. Google Cloud's guidance names new service account keys, new users and project SSH keys as items to look for; AWS's guidance asks you to check every Region. Remove persistence and follow the Cloud Credential Compromise Playbook where cloud activity is confirmed.
5.6 Check CI/CD: secrets the developer could read, pipeline definition changes and self-hosted runners they administered. Escalate to the CI/CD Pipeline Compromise Playbook if a pipeline was altered.
6. Recovery
- Reissue credentials in a better shape: fine-grained, short-lived tokens; SSH keys on hardware or platform authenticators; cloud access through SSO with short sessions instead of long-lived keys.
- Move publishing off the laptop. Where a registry supports it, publish from CI with federated, short-lived credentials so no publishing token sits on a workstation.
- Restore the developer on the rebuilt device with phishing-resistant MFA confirmed for source control, cloud and registry accounts.
- Lift branch and release freezes only after the owners in section 2 confirm their review is complete.
- Monitor the user's new and revoked identifiers for 30 days (our recommendation): any use of a revoked token or key is a strong signal the attacker kept a copy.
7. Communication and notification
- Internal: repository owners, release owners and the teams whose services the developer could deploy.
- Customers and downstream users: if an unauthorised package version, extension version or release was published, tell users which versions to remove and which are clean.
- Regulators: if personal data in repositories, test data or cloud stores was accessed, assess notification under the applicable law with legal; personal data breach rules such as UK GDPR Article 33 have a 72-hour clock from awareness.
- Platforms: report malicious extensions or packages to the marketplace or registry.
8. Post-incident review
8.1 Within ten working days, record the entry route, the full credential list, time from detection to last revocation, and which credentials were actually used by the attacker.
8.2 Typical improvements: extension allowlists and workspace trust settings (see the Developer Workstation and IDE Security Guide), removing long-lived credentials from endpoints (see Developer endpoints as NHI stores), and honeytokens in developer home directories.
Implementation guidance
Lessons from incidents. In the Bybit hack, a developer's macOS laptop was compromised after running a Docker project, Safe described the attack as hijacking AWS session tokens to bypass MFA, and malicious JavaScript was later served from its S3 bucket. The lesson for this playbook is section 4: cloud sessions on a developer device are revoked as urgently as passwords, and production write rights should not sit in a developer's day-to-day session. In the GlassWorm campaign, malicious editor extensions harvested npm, GitHub, Git and Open VSX credentials, and stolen publishing tokens were then used to push malicious code to further extensions and packages. Revoking publishing tokens and reviewing recent publishes (sections 4 and 5.4) is what stops that chain.
Rollout steps (our recommendation):
- Build the credential map in section 4 for each standard developer image and keep it with the playbook.
- Script the revocation steps for your source control, cloud and registry platforms and store the scripts where responders can run them from a clean device.
- Confirm EDR covers developer devices, including Linux and macOS, and that it records IDE and package manager child processes.
- Exercise the playbook twice a year with a test developer account holding test tokens. Time from first alert to last revocation is the measure that matters.
- Review after every real use and after any change to the developer toolchain.
Metrics: time from detection to isolation; time from isolation to last credential revoked; share of developer credentials that are short-lived or federated; number of workstations holding package publishing tokens (target zero); use of revoked credentials detected after incidents.
| Playbook phase | NIST CSF 2.0 | NIST SP 800-53 Rev. 5 |
|---|---|---|
| Detection and triage | DE.AE-02 | SI-4 |
| Containment and eradication | RS.MA-01 | IR-4 |
| Recovery | RC.RP-01 | IR-4 |
| Notification | RS.MA-01 | IR-6 |
| Post-incident review | RS.AN-03 | IR-4 |
References: NIST: SP 800-61 Rev. 3 Incident Response Recommendations and Considerations for Cybersecurity Risk Management · GitHub Docs: Token expiration and revocation · GitHub Docs: Reviewing your security log · GitHub Docs: Reviewing your SSH keys · Google Cloud: Handle compromised Google Cloud credentials · AWS: What do I do if I notice unauthorised activity in my AWS account · Microsoft Learn: Revoke user access in an emergency in Microsoft Entra ID · npm Docs: Revoking access tokens
This template is provided for guidance and must be adapted to your organisation. Related NHI Mgmt Group resources: Developer endpoints as NHI stores · Session Token Theft Response Playbook · Source Code Leak Response Playbook · Secrets Management Guide · Incident Response Guide