Safeguard
Supply Chain Security•

Compromised Dev Laptop: When to Wipe, What to Rotate, How to Rebuild

If a developer laptop is compromised, isolate it, rotate every credential from a clean device, wipe or replace it, then rebuild from verified installers.

Safeguard Security Team
37 min read

If your developer laptop was compromised, assume every credential it held is stolen, rotate those credentials from a different, clean device, and then wipe the disk and reinstall the operating system from verified media. Replace the hardware instead of wiping it when you have real reason to doubt its firmware. Rebuild projects from lockfiles with fresh caches, and restore data, not executables.

This is the incident path. If you are selling or handing on a laptop, or you lost one and it never came back, see the first hour checklist for a lost or stolen developer laptop instead. Here the device is still in your hands and the attacker may still be inside it.

Key takeaways

  • A developer laptop is a supply chain asset. It can publish packages, push code, deploy to cloud accounts and sign releases, so a compromise is rarely contained to one person's files.
  • Rotate first, wipe second. Credentials keep working after the disk is erased, and the attacker may already hold copies.
  • Do the rotation from a clean device. Typing new passwords into the compromised laptop hands them over.
  • Prefer a full erase plus an operating system reinstall from freshly downloaded, verified media over a "keep my files" refresh. On Windows, a local reinstall reuses files already on the PC, which is the wrong trust anchor after a compromise.
  • Replace the hardware when firmware or physical tampering is plausible. A disk wipe does not reach firmware.
  • Rebuild projects with npm ci, hash checked pip installs and fresh caches. Do not restore package caches, virtual environments or node_modules from backup.
  • After rotation, read the audit trails: your Git host's security log, registry publish history, cloud API logs and CI run history for the exposure window.

Why a developer laptop is different

A developer laptop typically holds tokens that can publish to a package registry, push to protected branches, register CI runners, pull production secrets, assume cloud roles, read Kubernetes clusters and sign artifacts. Its caches hold third-party code future builds will trust.

That is why the response has three parts that must happen in order:

  1. Contain the device and preserve what you need.
  2. Cut off every credential the device could reach.
  3. Rebuild the device and the projects on it from sources you can verify.

NIST frames incident response as part of overall cybersecurity risk management in SP 800-61 Rev. 3, published in April 2025 and aligned with the Cybersecurity Framework 2.0. CISA's #StopRansomware Guide gives the practical version for a single affected system: isolate it, image it, reset credentials, rebuild. The sequence scales down to one laptop well.

For a map of where secrets tend to live before anything goes wrong, see map where credentials live on a developer laptop and which files on a developer laptop hold credentials.

Which signs justify a full wipe vs targeted cleanup?

Targeted cleanup removes one known bad item and carries on. A full wipe erases the disk and reinstalls the operating system. The question is whether you know everything the attacker did.

Targeted cleanup is reasonable only when all of these are true:

  • You know exactly what ran, from a complete advisory describing narrow behaviour.
  • It had no administrator or root rights, installed no persistence and downloaded no second stage.
  • No credentials from the machine were used from somewhere unexpected.

A full wipe is justified when any of these is true:

  • Something you did not author ran with administrator or root rights.
  • You found unexplained persistence: new launch agents or daemons on macOS, new services or scheduled tasks on Windows, new systemd units or cron jobs on Linux, edited shell startup files.
  • Credentials from the machine were used from an IP address, device or location you do not recognise.
  • Security tooling on the machine was disabled or tampered with.
  • The advisory says it downloads further payloads, or is incomplete.
  • You cannot explain how the attacker got in.

Targeted cleanup is a bet that you found everything. On a machine with registry publish rights, that bet is expensive to lose. When in doubt, wipe.

When should the laptop be replaced rather than wiped?

Erasing the disk and reinstalling the operating system replaces the software stored on the disk. It does not replace firmware on the motherboard, the storage controller or peripherals, and it does nothing about hardware that was physically added.

MITRE ATT&CK describes Hardware Additions (T1200) as an initial access technique in which adversaries physically add accessories or networking hardware to a system, and lists uses such as keystroke injection and DMA based memory reading. Replace the laptop, or at least send it for vendor inspection before reuse, when:

  • The device was out of your custody in a way you cannot account for, for example taken at a border, left in a hotel room during a targeted incident, or returned from a repair you did not arrange.
  • You have specific evidence of firmware level persistence, such as compromise that survived a previous reinstall.
  • The incident involved an adversary you believe is well resourced and targeting your organisation specifically.
  • The machine is old enough that its firmware no longer receives security updates from the vendor.

In the common case, a developer ran something malicious from a package or download and nothing points at firmware. Erase and reinstall.

Decision table: clean, reset, reinstall, replace

OptionWhat it removesWhat it keepsUse it when
Targeted cleanupOne known bad itemEverything else, including anything you missedYou know exactly what ran, it had no admin rights and left no persistence
Windows "Keep my files"Apps and settingsPersonal filesNot after a compromise; your files can carry the problem back
Windows "Remove everything" with cloud downloadPersonal files, apps and settings; fresh Windows from MicrosoftFirmwareStandard choice after compromise on Windows
Mac "Erase All Content and Settings"Data, settings and appsThe installed macOSFine for resale; after compromise, prefer a full erase and reinstall from Recovery
Erase disk, then reinstall from Recovery or verified mediaEverything on the internal diskFirmwareStandard choice after compromise on macOS and Linux
Replace or vendor inspectionEverythingNothingCustody doubts, firmware evidence, targeted adversary, unsupported firmware

Step 1: contain the device first

Before you rotate or wipe anything:

  1. Disconnect from networks. Wi-Fi off, Ethernet out, VPN down. CISA's guide says to isolate affected systems immediately. Do not power off yet if you plan to capture memory.
  2. Do not log in to anything new from it. Every password typed on that keyboard from now on should be assumed captured.
  3. Pick up a clean device. All rotation work happens there.
  4. Tell someone. Whoever owns the registry organisation and cloud accounts needs to know within minutes.
  5. Start a timeline. On the clean device: what you noticed, when, what you did.

How do you preserve evidence before wiping, if you need it?

You need evidence when there may be legal, contractual, insurance or regulatory follow-up, when you need to know what data left the machine, or when you need to understand the entry point so it does not happen again. If they apply, involve your incident response provider or insurer before you change anything.

CISA's #StopRansomware Guide recommends taking "a system image and memory capture of a sample of affected devices" and collecting relevant logs. For a single developer machine, that translates to:

  • Memory first, if at all. Memory disappears at power off. Memory capture needs specialised tools and, on modern macOS and Windows, usually needs the help of someone who does it professionally. If nobody available can do it properly, skip it rather than run random tools on a compromised host.
  • A disk image to external storage. On a Linux machine, or a machine booted from trusted Linux live media, a raw image can be written to an external drive and hashed.
  • Logs and artefacts you can copy without tooling. Shell history files, the list of installed packages, the list of browser extensions, launch agents and scheduled tasks, recent downloads.

Warning: this block writes a large file and reads the whole internal disk. dd will overwrite whatever you name after of= without asking. Confirm both device paths first and never point of= at a disk.

Identify the source disk and the evidence drive before anything else:

# Read-only: list disks with model and serial so you can tell them apart
lsblk -o NAME,SIZE,MODEL,SERIAL,TYPE,MOUNTPOINTS

Only when you are sure that /dev/nvme0n1 is the internal disk and /mnt/evidence is the mounted external drive:

# Image the internal disk to a FILE on the external drive, then hash it
sudo dd if=/dev/nvme0n1 of=/mnt/evidence/laptop-2026-10-23.img bs=4M status=progress conv=noerror,sync
sha256sum /mnt/evidence/laptop-2026-10-23.img | tee /mnt/evidence/laptop-2026-10-23.img.sha256

An encrypted volume produces an encrypted image; record where the recovery key is.

Store the image as sensitive data: it holds every secret the laptop held.

What is the full credential inventory on a developer machine?

Build the inventory on the clean device, from your password manager and, if you have one, a read-only look at the evidence image. Missing one credential is how incidents come back.

CategoryTypical locations on the machineWhere to rotate
Identity and emailBrowser sessions, OS keychainIdentity provider, mail provider
Password managerUnlocked vault in the browser or appPassword manager account settings
Git hosting~/.git-credentials, ~/.config/gh/hosts.yml, OS keychain, SSH keysGit host settings: tokens, SSH keys, OAuth and GitHub App authorizations
SSH~/.ssh/id_*, ~/.ssh/config, agentEvery server and service that trusts the public key
Commit and release signing~/.gnupg, SSH signing keys, signing tool configKey revocation, Git host signing key list, release process
npm and other JavaScript registries~/.npmrc, project .npmrcRegistry token pages
Python~/.pypirc, pip config, .netrcPyPI API tokens and account security
Java~/.m2/settings.xml, ~/.gradle/gradle.propertiesRepository manager or registry
Containers~/.docker/config.json, credential helperContainer registry tokens
Cloud CLIs~/.aws/credentials, ~/.config/gcloud, ~/.azureCloud IAM consoles
Kubernetes~/.kube/configCluster credentials, service account tokens
CI/CDRunner registration tokens, CLI tokens, deploy keysCI settings and repository settings
Project secrets.env files, local config, test fixturesEach third-party service the key belongs to
AI and SaaS developer toolsCLI config files, editor extension settingsEach provider's key management page

A few of these deserve a specific note from the vendors' own documentation:

  • Docker's docker login reference says that without a configured credential store, credentials are saved in config.json in base64 encoded form, which is encoding, not encryption.
  • AWS's access key guidance says credentials in the shared credentials file are stored in plaintext, and recommends temporary credentials such as IAM roles over long-term access keys.
  • Google Cloud's gcloud auth revoke reference says that for service accounts nothing is revoked server side, because "service account tokens are not revocable." Only the local copy is removed. If a service account key file was on the laptop, you must delete the key itself.

In what order do you rotate?

Some credentials can recover or mint others, so rotate the roots of that tree first.

  1. Email and identity provider. Whoever controls your mail can reset almost everything else. Change the password from the clean device, sign out all other sessions, check recovery addresses and phone numbers, and review registered second factors.
  2. Password manager. Change the master password and sign out other sessions. If the vault was unlocked on the compromised machine, treat every entry as exposed, starting with the ones in this list.
  3. Git hosting. Rotate the account password, review sessions, delete personal access tokens, revoke OAuth and app authorizations, and remove SSH and signing keys that lived on the laptop.
  4. Package registry publishing rights. These are the credentials an attacker most wants on a developer machine, because a malicious publish reaches everyone downstream.
  5. Cloud accounts and Kubernetes. Deactivate and then delete access keys, delete service account keys, rotate kubeconfig credentials.
  6. CI/CD. Runner registration tokens, deploy keys, CI CLI tokens, and any secrets the developer could read from CI settings.
  7. Container registries and infrastructure tools.
  8. Project and third-party API keys found in .env files and local config.
  9. SaaS and chat sessions, including AI developer tools and bots.

Git hosting, using GitHub as the example

GitHub's documentation describes several separate credential types. Rotate each one; changing the password alone is not enough.

  • Personal access tokens. Managing your personal access tokens explains how to delete tokens under Settings, Developer settings, Personal access tokens. Deleting a token that created a deploy key also deletes that deploy key.
  • OAuth apps and GitHub Apps. Token expiration and revocation says revoking an app's authorization also revokes its tokens, and that account settings include an option to revoke all credentials at once if your account may be compromised.
  • SSH keys. Reviewing your SSH keys says to delete keys you do not recognise or that are out of date. Delete the laptop's key even if you recognise it.

From the clean device, with the GitHub CLI authenticated there:

# Read-only: list SSH and GPG keys registered on the account
gh ssh-key list
gh gpg-key list

Then delete the laptop's keys in the web settings or with gh ssh-key delete for each key ID, after confirming the fingerprint matches the key that lived on the compromised machine.

npm

npm's revoking access tokens page documents both the web flow and the CLI. Run the CLI from the clean device:

npm login
npm token list
# delete each token ID that existed while the laptop was compromised
npm token delete 123456
npm token list

The same page notes that you can revoke granular access tokens too, and that revocation can take up to an hour to take effect. Plan your audit window to include that hour.

PyPI

The PyPI help page says that if you suspect suspicious activity you should review the security history in your account settings, reset your password and contact the PyPI admins. Remove API tokens from your account settings and create new ones scoped to a single project where possible. For CI, the same page says PyPI strongly recommends Trusted Publishing over tokens where your CI provider supports it, which removes the long-lived upload token from both the laptop and CI.

AWS

Deactivate first, confirm nothing legitimate breaks, then delete. From the clean device, with an administrator session:

aws iam list-access-keys --user-name dev-alex
aws iam get-access-key-last-used --access-key-id AKIAIOSFODNN7EXAMPLE
aws iam update-access-key --user-name dev-alex --access-key-id AKIAIOSFODNN7EXAMPLE --status Inactive
# after confirming nothing legitimate broke
aws iam delete-access-key --user-name dev-alex --access-key-id AKIAIOSFODNN7EXAMPLE

The key ID above is AWS's own documentation example. AWS recommends CloudTrail for monitoring access key usage, which you will need in the audit step.

Google Cloud

On the clean device you do not have the compromised credentials, so the useful action is server side. For user accounts, sign out sessions and change the password through the account console. For service accounts whose key files were on the laptop, delete the keys:

gcloud iam service-accounts keys list --iam-account=builder@my-project.iam.gserviceaccount.com
gcloud iam service-accounts keys delete KEY_ID --iam-account=builder@my-project.iam.gserviceaccount.com

Remember the caveat from the gcloud reference: running gcloud auth revoke on a laptop only removes the local copy for service accounts.

SSH and signing keys

For SSH, generate a new key pair on the rebuilt machine, not before, and remove the old public key from every authorized_keys file, Git host and bastion that trusted it. For signing keys, NIST's SP 800-57 Part 1 Rev. 5 is the general reference on key management, including protection requirements for each key type. In practice, if a long-term signing key was on the laptop, publish its revocation through whatever channel your users check, remove it from your Git host's signing key list, and tell downstream consumers which releases were signed with the new key.

How do you rebuild from verified installers?

The aim is that the new operating system and toolchain came from an official source over a path you checked:

  • Download installers on a clean device, not on the compromised one.
  • Prefer the vendor's own recovery or cloud download path, which fetches a fresh copy.
  • Where the vendor publishes checksums and signatures, verify both.

macOS

Apple's Erase your Mac and reset it to factory settings describes Erase All Content and Settings, available on Macs with Apple silicon or the T2 Security Chip running macOS Monterey 12 or later. It erases data, settings and apps but keeps the currently installed macOS. That is fine before resale. After a compromise, you want the operating system replaced as well.

Apple's How to reinstall macOS covers reinstalling from macOS Recovery. Two points from that page matter here. First, Apple says reinstalling on its own does not remove your apps or personal data, so a reinstall without an erase is not a cleanup. Second, the page points to Disk Utility in Recovery to erase the startup disk. For Intel Macs it also lists the key combinations for Internet Recovery, which downloads the installer from Apple rather than using the local recovery partition.

Warning: erasing the startup disk destroys all data on it. Confirm you have your evidence image and your backup, and confirm the disk name in Disk Utility before you click Erase.

The sequence after a compromise is: start up in macOS Recovery, open Disk Utility, confirm the internal disk by name and size, erase it, then choose Reinstall macOS. Before erasing, list disks so you know what you are looking at:

# Read-only: run in the Recovery Terminal or before the erase to identify disks
diskutil list

Windows

Microsoft's Reset your PC page describes two choices that matter after a compromise.

  • Keep my files or Remove everything. Keep my files removes apps and settings but leaves personal files. Remove everything removes personal files, apps and settings. After a compromise, choose Remove everything and restore files from a backup you have reviewed.
  • Cloud download or Local reinstall. Cloud download fetches a fresh copy of Windows. Local reinstall uses files already on the PC. After a compromise, those local files are exactly what you do not trust, so choose Cloud download, or reinstall from installation media created on a clean machine.

Warning: Remove everything deletes all personal files, apps and settings. Confirm your backup and evidence image first. If BitLocker is on, have the recovery key ready, because Microsoft notes you will need it to reset from the Windows Recovery Environment.

Microsoft also notes that the optional Clean data step makes removed files harder to recover, but that it does not meet government or industry data erasure standards. For that bar, see NIST SP 800-88 Rev. 2, the September 2025 revision of the media sanitization guidelines that supersedes Rev. 1 from 2014.

Linux

Most distributions publish signed checksum files. Ubuntu's How to verify your Ubuntu download is a good model. On the clean device, with the ISO, SHA256SUMS and SHA256SUMS.gpg in one directory:

# 1. Verify the signature on the checksum file
gpg --keyid-format long --verify SHA256SUMS.gpg SHA256SUMS

# 2. If gpg reports missing keys, fetch them and compare fingerprints
#    against the ones printed in Ubuntu's tutorial before trusting them
gpg --keyid-format long --keyserver hkp://keyserver.ubuntu.com --recv-keys 0x46181433FBB75451 0xD94AA3F0EFE21092
gpg --keyid-format long --list-keys --with-fingerprint 0x46181433FBB75451 0xD94AA3F0EFE21092

# 3. Verify the ISO against the signed checksums
sha256sum -c SHA256SUMS 2>&1 | grep OK

Ubuntu's tutorial says a "Good signature" result confirms the file was signed by the matching key, and that no output from the last command means the ISO is corrupted or altered.

Warning: writing an image to a USB stick destroys everything on that stick. Pointing of= at the wrong device will destroy that device instead. Check the path before every write.

Identify the USB stick by size and model:

# Read-only: run before and after plugging in the stick; the new entry is the stick
lsblk -o NAME,SIZE,MODEL,TRAN,TYPE,MOUNTPOINTS

Only when you are sure /dev/sdX is the USB stick:

sudo dd if=ubuntu.iso of=/dev/sdX bs=4M status=progress conv=fsync

Then boot the laptop from the stick and let the installer erase the internal disk.

Which dotfiles, shell history and configs are safe to restore?

The rule is simple to state: restore data you can read, not behaviour you cannot. Anything that runs automatically when you open a terminal, log in, start an editor or run a build is behaviour.

ItemRestore?Why
Documents, notes, design filesYes, from a backup taken before the incident if possibleData; scan or open with care if the incident involved document payloads
Source code in GitRe-clone from the remote, then compareThe remote is the reference; local clones may contain hooks or uncommitted changes you did not make
Uncommitted local workOnly after reading the diffIt might contain injected changes
.bashrc, .zshrc, .profile, shell pluginsRewrite from your dotfiles repository after reviewing every lineShell startup is a classic persistence point
.gitconfigYes, after checking core.hooksPath, credential.helper, aliases and include entriesAliases and hook paths execute code
~/.ssh/configYes, after review; never the private keysConfig is data; keys are compromised
~/.ssh/known_hostsOptional; regenerate if you are unsureAn attacker could have added hosts; low risk but cheap to rebuild
~/.npmrc, ~/.pypirc, ~/.docker/config.json, cloud credential filesNeverThey hold the credentials you just rotated
Shell historyKeep a copy as evidence; do not restore into the new shellIt can contain secrets typed on the command line
Editor and browser extensionsReinstall from the official marketplace, one at a time, only the ones you needExtensions run code with broad access
Package caches, node_modules, virtual environments, ~/.m2, Go module cacheNeverRebuild them from lockfiles; see below
Login items, launch agents, services, scheduled tasksNever restore; recreate deliberatelyThese are persistence by design
Global npm or pip packagesReinstall at pinned versionsGlobal installs run on PATH for every project

Git hooks deserve a separate mention. Hooks live in .git/hooks inside each clone and are not pushed to the remote, so a fresh clone gives you a clean set. That is one reason to re-clone rather than copy repository folders across.

How do you reinstall SDKs and toolchains without pulling a poisoned cache?

Restored package caches let a compromise survive a rebuild: the next install may be served from ~/.npm or ~/.cache/pip instead of the registry.

npm's own cache documentation explains that the cache is content-addressable and that data "is fully verified for integrity on both insertion and extraction." That integrity check protects against corruption relative to what was stored. It does not tell you whether a package was malicious when it was stored. So the answer is not to verify an old cache but to start without one.

On the rebuilt machine:

  1. Install language runtimes from official installers or a version manager, at the versions pinned in each project: .nvmrc or .node-version, .python-version, .tool-versions, the go and toolchain lines in go.mod, rust-toolchain.toml, the Gradle or Maven wrapper properties.
  2. Start with empty caches. Do not restore them. If you are rebuilding in place rather than on a fresh disk, clear them explicitly.
  3. Install from lockfiles, not from manifests.

For JavaScript, npm's npm ci reference describes the behaviour you want: it requires an existing lockfile, fails if the lockfile and package.json disagree, deletes any existing node_modules, and never writes to package.json or the lockfile.

# Fresh clone, empty cache, lockfile install, scripts off for the first pass
git clone git@github.com:acme/web-app.git && cd web-app
npm ci --ignore-scripts
# list installed packages that declare install time scripts, and review them
grep -lE '"(preinstall|install|postinstall)"[[:space:]]*:' node_modules/*/package.json node_modules/@*/*/package.json
# then run the full install when satisfied
npm ci

The first pass with scripts disabled shows which dependencies want to run code at install time, so you look before they run.

For Python, pip's secure installs guide describes hash-checking mode. When --require-hashes is set, every requirement and every dependency must be pinned with == and carry a hash, and unlisted dependencies cause an error. The same guide recommends --only-binary :all: alongside hash checking to disallow source distributions.

python3 -m venv .venv && . .venv/bin/activate
python -m pip install --require-hashes --no-cache-dir -r requirements.txt

For other ecosystems, the principle is the same: use the lockfile or checksum database the ecosystem provides (go.sum, Cargo.lock, Gradle dependency verification metadata, Maven checksum policies), and start with an empty local repository directory.

For containers, pull base images by digest rather than by tag on the rebuilt machine, and do not import an old local image store.

How do you check that CI, registries and repositories were not touched?

Rotation stops future misuse but does not show what already happened. For the exposure window, from the earliest possible compromise until the last credential was revoked plus any revocation delay, check each system the laptop could reach.

Git hosting

GitHub's security log lists actions in your personal account for the last 90 days, under Settings, Archives, Security log. Look at event categories such as oauth_access, personal_access_token, public_key and repo for anything you did not do. If you belong to an organisation, ask an owner to check the organisation audit log for the same window.

Then look at the repositories themselves:

# On a fresh clone: commits on every branch during the exposure window
git fetch --all --tags
git log --all --since="2026-10-15" --until="2026-10-23" --format='%h %an %ae %cI %s'

# Tags created or moved recently
git for-each-ref --sort=-creatordate --format='%(creatordate:iso) %(refname:short)' refs/tags | head -20

# Workflow files changed in the window
git log --all --since="2026-10-15" --name-only --format='%h %s' -- .github/workflows

In the web settings, check for new deploy keys, new webhooks, changed branch protection rules, new collaborators, new GitHub App installations and new self-hosted runners. Check the Actions run history for runs triggered by your account that you did not start.

Package registries

For each package you can publish, compare published versions against your release records:

npm view @acme/web-sdk time --json

A version you did not publish is an incident for everyone who installed it: report and deprecate it, publish a clean version and tell your users. On PyPI, check the account security history and each project's release history.

If a malicious version did go out, the playbook in incident response for a compromised dependency covers the downstream side. What to reset after a poisoned build covers CI runners and caches that may also have been exposed.

Cloud and CI

  • AWS: search CloudTrail for API calls made with the rotated access key IDs during the window, and for any new IAM users, keys, roles or policy changes.
  • Google Cloud: check audit logs for activity by the user and service accounts whose credentials were on the laptop.
  • Kubernetes: check the API server audit log for the user or service account in the old kubeconfig.
  • CI: check for new or modified secrets, new runners, and pipeline runs triggered by the developer's identity.

If you find nothing, record what you checked and over what window.

What should the post-incident note say?

Keep it short and factual. A template:

# Post-incident note: developer laptop compromise, 2026-10-23

## Summary
One or two sentences: what happened, impact, current status.

## Timeline (all times UTC)
- First suspicious sign:
- Device isolated:
- First credential rotated:
- Last credential rotated (plus revocation delay):
- Device wiped / replaced:
- Rebuild complete:

## Entry point
What we know, what we suspect, and what we could not determine.

## Credentials rotated
Table: credential, system, rotated at, old credential used after exposure? (yes/no/unknown)

## Audit checks performed
System, log source, window checked, result.

## Downstream impact
Packages published, commits pushed, deployments made, data accessed. "None found" with scope.

## What made this slower than it should have been
## Changes we are making
Owner and date for each.

The section on what slowed you down is the one that pays off next time.

How do you shorten next time?

  • Short-lived and scoped tokens. GitHub recommends fine-grained personal access tokens with an expiration on every token, and notes that GitHub App user access tokens expire after eight hours by default. AWS recommends temporary credentials such as IAM roles over long-term access keys.
  • Trusted publishing. PyPI strongly recommends Trusted Publishing from CI over API tokens. The laptop then never holds a publish token.
  • Hardware-backed keys. FIDO2 security keys for account sign-in and for SSH (ssh-keygen -t ed25519-sk) keep the private key off the disk, so a disk compromise does not yield a reusable key. Keep the recovery codes for those accounts offline, not on the laptop.
  • Credential helpers instead of plaintext files. Docker documents OS credential stores for docker login.
  • Managed devices. Device management enforces encryption and updates and allows remote wipe. The NCSC device security guidance links platform guides with recommended configurations for Android, Chrome OS, iOS and iPadOS, macOS and Windows.
  • A scripted rebuild. A dotfiles repository you trust, a list of tools at pinned versions, and a bootstrap script turn "a lost week" into "an afternoon." Test it once a year on a spare machine.
  • An SBOM per project, kept outside the laptop. Compare the rebuilt dependency set against it instead of memory.
  • Offline backups of what cannot be reissued. CISA's guide recommends keeping offline, encrypted backups of critical data and testing backup procedures regularly. For developers, that includes recovery codes, signing key revocation certificates and the dotfiles repository.

For the full revocation list per package manager, see which package manager credentials to revoke after a lost or reimaged laptop.

Common mistakes

  • Wiping before rotating. The disk is clean, the attacker still has your npm token. Rotate first.
  • Rotating from the compromised machine. New passwords typed into an infected session are new passwords for the attacker.
  • Changing the Git host password and stopping there. GitHub documents tokens, app authorizations and SSH keys as separate credentials. Revoke each one.
  • Forgetting service account keys. gcloud auth revoke on the laptop does not revoke a service account key server side. Delete the key.
  • Using a reset that keeps the old install. Windows "Keep my files" and Local reinstall, or Mac Erase All Content and Settings, all keep something from before.
  • Restoring the whole home directory from backup. That brings back the persistence and the stolen keys.
  • Copying repositories across instead of re-cloning. Local hooks and uncommitted changes come with them.
  • Not checking downstream. A compromise that published a package version is a supply chain incident for your users, not just a laptop problem.
  • Skipping the post-incident note. Without it, the next responder starts from zero.

Fix it without waiting for upstream

A rebuilt laptop pulls every dependency again, which is a natural moment to make sure you are rebuilding onto fixed versions rather than whatever was in the old lockfile or cache. The fit here is indirect: none of what follows cleans a laptop or detects malware on it, but it does shape what your rebuilt projects install and ship.

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

Where Safeguard fits, and where it does not

To be plain about it: Safeguard does not detect malware on a laptop, does not tell you whether a machine is compromised, does not wipe or manage devices, and does not rotate your credentials. Those steps belong to your operating system vendor, your identity and device management tools and the services that issued each credential.

Where it helps is the project side of the rebuild. After you re-clone and install from lockfiles, safeguard scan --dir . scans the project's dependencies and writes the component inventory and vulnerability results as JSON under ./output. You can compare that inventory with the SBOM you kept from before the incident to see whether the rebuilt dependency set matches what you expected. The platform shows which of your projects contain a given component and version, which is useful when a malicious or vulnerable version is named in an advisory and you need to know where else it landed. Reachability analysis and policies and gates help you decide what to fix first and stop a known bad version from shipping again. Because the scanner runs as part of the Safeguard CLI on your own machine and uploads only results, it works the same on a freshly rebuilt laptop; see how the local runner and offline mode work. You can get the CLI from safeguard.sh/download and read the CLI docs.

FAQ

Should I wipe my laptop after installing a malicious npm package?

Usually yes, if it ran code on your machine and no complete advisory tells you exactly what it did. Rotate every credential from a different device first, then erase and reinstall.

Does a factory reset remove malware?

A full erase and reinstall from fresh media removes software stored on the internal disk. It does not reach firmware or hardware that was physically added. On Windows, choose Remove everything with Cloud download. On a Mac, erase the disk in Recovery and reinstall, because Apple documents that Erase All Content and Settings keeps the installed macOS.

What should I rotate first after a laptop compromise?

Start with the accounts that can reset others: email and identity provider, then the password manager. Next, Git hosting and package registry publishing rights, because those reach your users. Then cloud accounts, CI/CD, container registries, project API keys and SaaS sessions.

Does changing my GitHub password revoke personal access tokens and SSH keys?

Do not rely on it. GitHub documents separate steps for personal access tokens, OAuth and GitHub App authorizations and SSH keys, plus an option to revoke all credentials at once. Do each explicitly.

Can I restore my dotfiles after a compromise?

Restore them from a dotfiles repository after reading every line, not from the compromised machine. Never restore credential files, private keys, caches, login items or launch agents.

Should I clear my npm and pip caches after a compromise?

Start with empty caches and never restore them. npm's integrity check confirms data matches what was stored, not that it was safe when stored. Install with npm ci and pip's hash-checking mode.

When should I replace a compromised laptop instead of wiping it?

When firmware or physical tampering is plausible: unexplained loss of custody, evidence that a compromise survived a previous reinstall, a targeted and well resourced adversary, or firmware that no longer gets vendor updates. A disk erase does not reach firmware.

How do I know if my stolen tokens were used?

Read the audit trails for the exposure window: your Git host's security log (GitHub keeps 90 days for personal accounts) and organisation audit log, registry publish history and account security history, cloud logs such as AWS CloudTrail, and CI run history.

See how Safeguard would help

The first demo is a real CLI session. It installs the Safeguard CLI, opens the interactive terminal with safeguard, asks it to "fix the lodash CVE in this repo", and shows it reading the finding and advisory, asking before each command, editing package.json to lodash 4.17.21, running npm install and npm test with approval, and printing a summary without pushing anything. On a rebuilt machine, the same flow moves a re-cloned project onto fixed versions with your approval on each command.

Click through it at your own pace, or open it full screen.

The second demo sets up the local runner on your own machine, approves it with its device code and then scans from the terminal. After a rebuild, it gives you dependency inventory for each re-cloned project to compare with your pre-incident SBOM.

Click through it at your own pace, or open it full screen.

The third demo is a real Android session: it sends work to a computer running the CLI and approves the command on the phone with Allow once, Allow for turn or Deny. While you work between a loaner and the new laptop, every command still needs your approval.

Click through it at your own pace, or open it full screen.

Quick check

You have erased and reinstalled your compromised laptop. Is your npm publish token now safe?

No. Erasing the disk removes the attacker's foothold on the device, but any token already copied off the machine keeps working until you delete it with npm token delete or in the npm website settings, from a clean device. Revocation can take up to an hour, so audit publish history through that window.

On Windows, which reset options should you pick after a compromise?

Remove everything, with Cloud download, or a reinstall from installation media made on a clean machine. Keep my files leaves personal files in place, and Local reinstall uses files already on the PC, which is exactly what you no longer trust.

Sources

Last reviewed: 23 October 2026. Vendor steps change; check the linked documentation before you act.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.