npm Supply Chain Security
bodadotsh/npm-security-best-practices
Applies safer package manager defaults and dependency vetting to JavaScript and TypeScript projects to reduce supply-chain attack risk.
Install-time cooldowns for npm/bun plus a sandboxed pre-install scan for bypasses.
The automated check flagged lines worth reading first. See the safety section below.
$ npx skills add jamditis/claude-skills-journalism --skill supply-chain-hardening -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install jamditis/claude-skills-journalism supply-chain-hardening --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/jamditis/claude-skills-journalism.git skills-src && mkdir -p .claude/skills && cp -r skills-src/security-toolkit/skills/supply-chain-hardening .claude/skills/supply-chain-hardening && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "supply-chain-hardening" agent skill from https://github.com/jamditis/claude-skills-journalism/tree/master/security-toolkit/skills/supply-chain-hardening into .claude/skills/supply-chain-hardening/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "supply-chain-hardening", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/jamditis/claude-skills-journalism/tree/master/security-toolkit/skills/supply-chain-hardeningType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add jamditis/claude-skills-journalism --skill supply-chain-hardening -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install jamditis/claude-skills-journalism supply-chain-hardening --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jamditis/claude-skills-journalism.git skills-src && mkdir -p .agents/skills && cp -r skills-src/security-toolkit/skills/supply-chain-hardening .agents/skills/supply-chain-hardening && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "supply-chain-hardening" agent skill from https://github.com/jamditis/claude-skills-journalism/tree/master/security-toolkit/skills/supply-chain-hardening into .agents/skills/supply-chain-hardening/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "supply-chain-hardening", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jamditis/claude-skills-journalism --skill supply-chain-hardening -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install jamditis/claude-skills-journalism supply-chain-hardening --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jamditis/claude-skills-journalism.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/security-toolkit/skills/supply-chain-hardening .cursor/skills/supply-chain-hardening && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "supply-chain-hardening" agent skill from https://github.com/jamditis/claude-skills-journalism/tree/master/security-toolkit/skills/supply-chain-hardening into .cursor/skills/supply-chain-hardening/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "supply-chain-hardening", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/jamditis/claude-skills-journalism.git --path security-toolkit/skills/supply-chain-hardening--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add jamditis/claude-skills-journalism --skill supply-chain-hardening -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install jamditis/claude-skills-journalism supply-chain-hardening --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jamditis/claude-skills-journalism.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/security-toolkit/skills/supply-chain-hardening .gemini/skills/supply-chain-hardening && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "supply-chain-hardening" agent skill from https://github.com/jamditis/claude-skills-journalism/tree/master/security-toolkit/skills/supply-chain-hardening into .gemini/skills/supply-chain-hardening/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "supply-chain-hardening", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install jamditis/claude-skills-journalism supply-chain-hardeningInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add jamditis/claude-skills-journalism --skill supply-chain-hardening -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/jamditis/claude-skills-journalism.git skills-src && mkdir -p .github/skills && cp -r skills-src/security-toolkit/skills/supply-chain-hardening .github/skills/supply-chain-hardening && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "supply-chain-hardening" agent skill from https://github.com/jamditis/claude-skills-journalism/tree/master/security-toolkit/skills/supply-chain-hardening into .github/skills/supply-chain-hardening/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "supply-chain-hardening", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jamditis/claude-skills-journalism --skill supply-chain-hardening -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install jamditis/claude-skills-journalism supply-chain-hardening --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jamditis/claude-skills-journalism.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/security-toolkit/skills/supply-chain-hardening .opencode/skills/supply-chain-hardening && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "supply-chain-hardening" agent skill from https://github.com/jamditis/claude-skills-journalism/tree/master/security-toolkit/skills/supply-chain-hardening into .opencode/skills/supply-chain-hardening/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "supply-chain-hardening", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
supply-chain-hardeningInstall-time cooldowns for npm/bun plus a sandboxed pre-install scan for bypasses.
Supply Chain Hardening is an agent skill from jamditis/claude-skills-journalism. Install-time cooldowns for npm/bun plus a sandboxed pre-install scan for bypasses. Use for supply-chain attacks or npm security.
Its SKILL.md is about 2k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files (for example `agents/openai.yaml`).
It sits in Security, covering Supply chain security. It works with npm and TanStack. The repository describes itself as: Claude Code skills for journalism, media, and academia - verification, FOIA, data journalism, academic writing, and more. The licence is MIT.
3 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit e3e2172. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
npmbunjqFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
github.comstepsecurity.iodocs.npmjs.combun.comosv.devFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
GITHUB_TOKENAWS_SECRETFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Supply Chain Hardening loads about 2k tokens when it runs. Until then it costs about 38 tokens; SKILL.md has 928 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found patterns that need a careful read before installing.
| npm | `~/.npmrc` (or project `.npmrc`) | `min-release-age` | days | none yet, proposed in [npm/cli#8994](https://githu# ~/.npmrcJS files referencing `.ssh/`, `.aws/`, `.npmrc`, `GITHUB_TOKEN`, `AWS_SECRET`, kube config | Credential exfiltration | Y11: `npm --version`. If older, upgrade (`sudo npm i -g npm@latest` or tarball-swap if self-upgrade races).2. Write `~/.npmrc` and `~/.bunfig.toml` with the config above.Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from jamditis/claude-skills-journalism at commit e3e2172, republished under its MIT licence (© jamditis). 928 words, ~2,016 tokens.
.claude/skills/supply-chain-hardening/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.Defends a journalism toolchain against the dominant npm/bun supply-chain attack pattern: a maintainer account or CI pipeline is compromised, a malicious version ships, and machines install it before anyone notices. Recent example: the Mini Shai-Hulud TanStack attack (2026-05-11) compromised 84 versions across 42 @tanstack/* packages and exfiltrated AWS / GCP / Vault / GitHub / SSH credentials via a postinstall script.
The defense is layered and intentionally simple:
bwrap/firejail/unshare so a malicious package can't escape the inspection.--ignore-scripts at install, postinstall is the #1 attack vector. Skip lifecycle scripts on every cooldown-bypass install.These three together would have blocked the Mini Shai-Hulud TanStack attack on a stock laptop with no human in the loop.
Verified config keys (npm v11+ and bun 1.3+):
| Manager | File | Key | Units | Exclusion key |
|---|---|---|---|---|
| npm | ~/.npmrc (or project .npmrc) | min-release-age | days | none yet, proposed in npm/cli#8994 |
| bun | ~/.bunfig.toml (or project bunfig.toml) | [install] minimumReleaseAge | seconds | [install] minimumReleaseAgeExcludes = [] (exact names, no globs) |
Minimal config:
# ~/.npmrc
min-release-age=7# ~/.bunfig.toml
[install]
minimumReleaseAge = 604800 # 7 days
minimumReleaseAgeExcludes = []Requires npm 11+. Older npm silently ignores unknown keys, so the config looks correct but does nothing. Check with npm --version and npm config get min-release-age (should echo 7, not null).
When the cooldown blocks an install you actually want:
npm install <pkg>@<version> --min-release-age=0 --ignore-scripts
bun add <pkg>@<version> --minimum-release-age=0 --ignore-scriptsThe bun add --minimum-release-age=0 CLI flag works in 1.3+ even though the docs don't list it, it follows bun's bunfig key → kebab-case flag convention.
Always pair the bypass with --ignore-scripts. Postinstall is the most common payload-execution path in supply-chain malware (Mini Shai-Hulud, event-stream, ua-parser-js, coa, all used it). Native modules that legitimately need postinstall can have the script run manually after a human-readable review:
(cd node_modules/<pkg> && cat package.json | jq .scripts) # eyeball it
(cd node_modules/<pkg> && npm run postinstall) # run if it checks outThe scan is for the dangerous moment: you've decided to bypass the cooldown and need a sanity check. The skill ships a reference script (scripts/hotpatch.example.sh) implementing the heuristics. Adapt it to your machine, Bash assumes bwrap (Linux); macOS users substitute sandbox-exec or skip the sandbox layer with the trade-off documented.
Static checks the scan should perform (each backed by a real attack):
| Check | Diagnostic of | Severity |
|---|---|---|
optionalDependencies / dependencies containing github: or git+ URLs | Mini Shai-Hulud (delivered payload via github:tanstack/router#<sha> ref) | RED |
Large JS file at package root not referenced by main/module/exports/bin/files | Planted payload pattern (router_init.js in Mini Shai-Hulud) | RED |
| Unpacked size >3x the prior stable version | Bulk payload smuggling | RED |
fileCount delta of 1–4 paired with >2x size jump | Single planted file | RED |
preinstall/install/postinstall/prepare scripts present | Lifecycle-script attack vector (event-stream, ua-parser-js, etc.) | YELLOW |
JS files referencing .ssh/, .aws/, .npmrc, GITHUB_TOKEN, AWS_SECRET, kube config | Credential exfiltration | YELLOW |
Version flagged deprecated in npm registry with "security"/"compromised"/"malicious" wording | Maintainer/registry yank | RED |
OSV.dev returns known vulnerabilities for <pkg>@<version> | Disclosed CVE | RED (severity-dependent) |
Why prerelease versions are skipped from the size-delta baseline: dev/beta/rc versions have wildly different sizes than stable releases and produce false positives.
Be honest about the limits with whoever you're configuring this for:
<pkg> you install can pull in a compromised transitive. Defenses: scan against the resolved tree (npm audit, osv-scanner), and keep the cooldown active globally so transitive resolution also waits.npm ci against an existing lockfile. The cooldown applies during resolution, not installation of already-pinned versions. If your lockfile pins a compromised version, npm ci will install it. Mitigation: scan lockfiles in CI with osv-scanner --lockfile=package-lock.json.node_modules. Hardening protects future installs, not past ones. Audit existing deps separately (npm audit, osv-scanner, manual review of recently-published deps in your tree).npm --version. If older, upgrade (sudo npm i -g npm@latest or tarball-swap if self-upgrade races).~/.npmrc and ~/.bunfig.toml with the config above.npm config get min-release-age returns 7. cat ~/.bunfig.toml shows the [install] block.scripts/hotpatch.example.sh to ~/.claude/hotpatch.sh (or wherever fits). Make executable. Run ./hotpatch.sh --self-test against the synthetic Mini Shai-Hulud fixture (also shipped) to confirm the heuristics fire.| Defends against | Doesn't defend against |
|---|---|
| Maintainer account compromise (npm token theft) | Targeted attack tailored to wait through the cooldown |
| CI/CD pipeline hijack (Mini Shai-Hulud, valid OIDC tokens, SLSA-attested malice) | Compromise of a transitive dep already pinned in a lockfile |
Typosquatting (lookalike package names), when paired with npm pkg fix and lockfile review | Malicious code in your own dev dependencies that you authored |
Postinstall payload execution (cooldown + --ignore-scripts = belt and suspenders) | Runtime supply-chain attacks (e.g., dynamic loading of bad code from a CDN) |
Drive-by npm install of a brand-new transitive | Compromise of the registry itself (very rare; out of scope) |
min-release-age config: https://docs.npmjs.com/cli/v11/using-npm/configminimumReleaseAge config: https://bun.com/docs/runtime/bunfig© jamditis, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file in security-toolkit/skills/supply-chain-hardening of jamditis/claude-skills-journalism.
Open the folder on GitHubat commit e3e2172
Supply Chain Hardening next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Supply Chain Hardening this skilljamditis/claude-skills-journalism | 416 | — | ~2k | Automated safety check: Warn | MIT | |
| npm Supply Chain Securitybodadotsh/npm-security-best-practices | 858 | — | ~1k | Automated safety check: Warn | MIT | |
| Dependency Update Auditbacknotprop/plannotator | 9.3k | — | ~1.8k | Automated safety check: Pass | Apache-2.0 | |
| Hol Guard Protectionhashgraph-online/hol-guard | 845 | — | ~605 | Automated safety check: Pass | Apache-2.0 | |
| npm Supply Chain Checkmajiayu000/spellbook | 287 | — | ~1.5k | Automated safety check: Pass | MIT | |
| Interlinked Supply ChainQuentinCody/interlinked-cli | 178 | — | ~2.8k | Automated safety check: Pass | MIT |
bodadotsh/npm-security-best-practices
Applies safer package manager defaults and dependency vetting to JavaScript and TypeScript projects to reduce supply-chain attack risk.
backnotprop/plannotator
Audits outdated npm and Bun packages for supply chain integrity before bumping them, deferring risky ones and logging every decision.
hashgraph-online/hol-guard
Use HOL Guard to preview and protect AI-agent package installs, Cursor surfaces, CI, and automation workflows.
majiayu000/spellbook
Scans a repository, its lockfiles and node_modules for known malicious npm package versions and install-time indicators, using a read-only Python scanner.
QuentinCody/interlinked-cli
Respond to blocked package installs and manage the Interlinked supply-chain allowlist.
nubjs/nub
Run a large sharded measurement sweep over npm packages (the build-jail catalog probe, or any harness that installs thousands of package-versions and records a verdict per run).
jamditis/claude-skills-journalism
A skill your agent uses when creating distinct website directions, a client review picker, asset catalog, previews, and Cloudflare-ready handoffs.
jamditis/claude-skills-journalism
Builds an Open Knowledge Format (OKF) knowledge base from existing docs, notes, or a repo.
jamditis/claude-skills-journalism
Local Gitleaks scans for staged changes, push ranges, and full history in private repos, with redacted reports.
jamditis/claude-skills-journalism
Acquire, clean, analyze, verify, visualize, and explain data for journalism.
jamditis/claude-skills-journalism
Creates print-ready HTML that exports to PDF. An agent skill from jamditis/claude-skills-journalism.
jamditis/claude-skills-journalism
Establishes how to find and use skills, requiring Skill tool invocation before any response.
Categories
Install-time cooldowns for npm/bun plus a sandboxed pre-install scan for bypasses. Supply Chain Hardening is an agent skill from jamditis/claude-skills-journalism. Install-time cooldowns for npm/bun plus a sandboxed pre-install scan for bypasses.
Supply Chain Hardening fits situations like: supply-chain attacks; tasks that involve Supply chain security.
Run `npx skills add jamditis/claude-skills-journalism --skill supply-chain-hardening -a claude-code`. Or copy the skill folder (security-toolkit/skills/supply-chain-hardening in jamditis/claude-skills-journalism) into .claude/skills/supply-chain-hardening in your project. Claude Code loads it when a task matches its description.
Run `npx skills add jamditis/claude-skills-journalism --skill supply-chain-hardening -a codex`. Or copy the skill folder (security-toolkit/skills/supply-chain-hardening in jamditis/claude-skills-journalism) into .agents/skills/supply-chain-hardening in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jamditis/claude-skills-journalism --skill supply-chain-hardening -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/supply-chain-hardening, .gemini/skills/supply-chain-hardening, .github/skills/supply-chain-hardening and .opencode/skills/supply-chain-hardening in your project.
Going by SKILL.md and its folder, Supply Chain Hardening needs the command-line tools its instructions call (npm, bun and jq) and credentials named GITHUB_TOKEN and AWS_SECRET. Our summary lists: Node.js; A credential in GITHUB_TOKEN; A credential in AWS_SECRET.
SKILL.md names 5 domains. As links in the text: github.com, stepsecurity.io, docs.npmjs.com, bun.com and osv.dev. This is read from the text; nothing was executed.
Our automated static check of SKILL.md flagged 4 warning(s): mentions a credentials file (ssh keys, cloud or package-manager tokens). Read the flagged lines before installing; the check is not a guarantee either way.
Supply Chain Hardening is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2k tokens (SKILL.md is roughly 8.1k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Supply Chain Hardening: npm Supply Chain Security (bodadotsh/npm-security-best-practices, 858 stars), Dependency Update Audit (backnotprop/plannotator, 9.3k stars), Hol Guard Protection (hashgraph-online/hol-guard, 845 stars) and npm Supply Chain Check (majiayu000/spellbook, 287 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
jamditis (a GitHub user) maintains it in jamditis/claude-skills-journalism, which has 416 GitHub stars. The repository holds 53 skills in this directory. The repository was last updated on October 4, 2026.
Source: jamditis/claude-skills-journalism on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.