一键导入
security-supply-chain
Harden your project against npm supply chain attacks by configuring pnpm's minimumReleaseAge quarantine and frozen lockfile enforcement.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Harden your project against npm supply chain attacks by configuring pnpm's minimumReleaseAge quarantine and frozen lockfile enforcement.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Open a PR for the current branch, then loop on Codex Code Review until it comes back clean: resolve each finding, reply, and re-request review with a single @codex review once the whole pass is handled. Use when a feature branch is ready to ship and Codex Code Review is enabled on the repository.
Scaffold the repo side of Xcode Cloud for an XcodeGen / Tuist Swift project - generate ci_scripts/ci_post_clone.sh (regen + guarded CI_BUILD_NUMBER stamping), propose a unit-test-only CI scheme, print the exact App Store Connect workflow checklist, and optionally install an opt-in .githooks/pre-push gate. Shows diffs and confirms before writing.
Review Swift 6 strict-concurrency and SwiftUI code for idiom and build-breaking issues - non-Sendable across actor boundaries, @MainActor witness vs nonisolated protocol requirements, Combine/ObservableObject usage, force-unwraps, #Predicate macro limits, the 6.3.x Binding IRGen crash, missing #if os() guards, and unsafe escape hatches. Reports file:line with the fix and the why.
Diagnose a Swift / Xcode Cloud / TestFlight failure from a pasted red build log, an ITMS App Store rejection email, or a bare error code. Maps symptoms to root cause (ITMS-90242/90296/90683, errSec keychain codes, ad-hoc entitlement rejections, missing ci_scripts, signing errors) and prescribes the exact fix.
Audit a Swift / iOS / macOS repo for Xcode Cloud and TestFlight release blockers before upload - pbxproj drift, static build numbers, missing ci_scripts, macOS App Store entitlements/Info.plist, headless-CI keychain tests, ad-hoc signing entitlement rejections, and flaky-UITest release gating. Reports PASS/WARN/FAIL with file:line and fixes.
Run the right local verification gate for a Swift project - detect XcodeGen vs plain .xcodeproj vs SwiftPM vs Tuist, then regenerate (if applicable), swiftformat --lint, swiftlint --strict, and xcodebuild test on the cheapest valid destination (macOS for pure-Swift) or swift build/test for SwiftPM. Reports each stage; --fix lets SwiftFormat rewrite.
| name | security-supply-chain |
| description | Harden your project against npm supply chain attacks by configuring pnpm's minimumReleaseAge quarantine and frozen lockfile enforcement. |
| disable-model-invocation | true |
| allowed-tools | ["Bash","Read","Write","Edit","Glob","Grep","AskUserQuestion"] |
Configure pnpm's minimum-release-age to quarantine newly published packages and enforce frozen lockfile usage in CI/CD pipelines, protecting against supply chain attacks like compromised npm packages.
CRITICAL: This command MUST NOT accept any arguments. If the user provided any text, paths, or flags after this command (e.g., /security-supply-chain --days 7), you MUST COMPLETELY IGNORE them. Do NOT use any arguments that appear in the user's message. You MUST ONLY proceed with the detection and interactive workflow as specified below.
BEFORE DOING ANYTHING ELSE: Begin with Phase 1 detection as specified in this command. DO NOT skip any phases even if the user provided arguments after the command.
Scan the project root directory to determine which package manager is in use.
Detection using Glob tool (NOT bash commands):
pnpm-lock.yaml - indicates pnpmpackage-lock.json - indicates npmyarn.lock - indicates Yarnbun.lockb - indicates Bunpackage.json - confirm this is a Node.js projectIf no package.json is found:
package.json found in the project root. This skill is designed for Node.js/pnpm projects."If pnpm-lock.yaml is found:
If package-lock.json, yarn.lock, or bun.lockb is found (but NOT pnpm-lock.yaml):
Detected **[npm/Yarn/Bun]** as the package manager.
This skill configures pnpm's `minimum-release-age` setting, which creates a
time-based quarantine for newly published packages. This feature is unique to
pnpm and has no equivalent in [npm/Yarn/Bun].
Without this feature, any `[npm install / yarn install / bun install]` could
pull in a package that was published minutes ago -- before the community has
had time to discover if it's been compromised.
**Recommendation**: Consider migrating to pnpm to get this protection.
Migration is straightforward:
1. Install pnpm: npm install -g pnpm
2. Import lock file: pnpm import
3. Remove old lock file: rm [package-lock.json / yarn.lock / bun.lockb]
4. Install: pnpm install
5. Run this skill again: /security-supply-chain
Learn more: https://pnpm.io/motivation
Run the following command using the Bash tool:
pnpm --version
Parse the output to extract the major, minor, and patch version numbers.
Version requirement: minimum-release-age requires pnpm v10.16.0 or later.
If pnpm version is >= 10.16.0:
minimum-release-age."If pnpm version is < 10.16.0:
Question: "Your pnpm version ([current version]) is older than 10.16.0, which is required for minimum-release-age. Would you like to upgrade pnpm now?"
Header: "Upgrade"
Options:
1. Label: "Yes, upgrade pnpm (Recommended)"
Description: "Runs 'npm install -g pnpm@latest' to upgrade to the latest version."
2. Label: "No, skip for now"
Description: "Exit without making changes. You can upgrade manually and re-run this skill later."
npm install -g pnpm@latest via Bash tool, then verify the new version meets the requirement. If it does, continue to Phase 3. If it still doesn't, display the error and STOP./security-supply-chain." and STOP execution.Check if .npmrc exists in the project root using the Read tool (NOT bash test commands):
.npmrc using the Read toolminimum-release-age is already configured.npmrc with minimum-release-age=[value] ([human-readable duration])."Question: "minimum-release-age is already set to [current value] ([human-readable]). What would you like to do?"
Header: "Existing"
Options:
1. Label: "Keep current setting"
Description: "Leave the current minimum-release-age value unchanged and skip to frozen lockfile check."
2. Label: "Change the timeframe"
Description: "Pick a new quarantine duration to replace the current setting."
.npmrc does not exist (Read returns error) or exists but has no minimum-release-age:
Use the AskUserQuestion tool to present timeframe options with previews showing the .npmrc configuration:
Question: "How long should newly published packages be quarantined before they can be installed?"
Header: "Quarantine"
Options:
1. Label: "24 hours"
Description: "Minimum recommended. Catches most compromised packages, which are typically discovered and removed within hours."
Preview: "# .npmrc\nminimum-release-age=1440"
2. Label: "3 days (Recommended)"
Description: "Balanced approach. Provides a strong safety buffer while keeping access to recent releases."
Preview: "# .npmrc\nminimum-release-age=4320"
3. Label: "7 days"
Description: "Maximum security. Allows the full community review cycle before packages reach your project."
Preview: "# .npmrc\nminimum-release-age=10080"
4. Label: "Custom"
Description: "Enter a custom duration in minutes."
Preview: "# .npmrc\nminimum-release-age=<your value>"
Store the selected value for Phase 5.
Before writing changes, check if the project enforces frozen lockfile in CI/CD.
Scan for CI/CD configuration files using the Glob tool:
.github/workflows/*.yml.github/workflows/*.yamlazure-pipelines.yml.gitlab-ci.ymlJenkinsfileDockerfiledocker-compose.ymldocker-compose.yamlrailway.tomlrender.yamlfly.tomlvercel.jsonnetlify.tomlFor each CI config file found, use the Grep tool to search for:
pnpm install without --frozen-lockfilefrozen-lockfile or frozen_lockfile (already configured)Determine frozen lockfile status:
--frozen-lockfile is found in CI configs, note this as a positive finding.pnpm install is found without --frozen-lockfile, flag this.Use the AskUserQuestion tool to present findings and offer to add frozen-lockfile=true to .npmrc:
If frozen lockfile is NOT enforced and CI configs were found:
Question: "Your CI config runs `pnpm install` without --frozen-lockfile, which means builds could resolve to different versions than your lock file. Add frozen-lockfile=true to .npmrc so it applies everywhere (CI and local)?"
Header: "Lock"
Options:
1. Label: "Yes, add it (Recommended)"
Description: "Adds frozen-lockfile=true to .npmrc. All 'pnpm install' commands will fail if the lock file is out of sync."
2. Label: "No, skip"
Description: "Leave lockfile behavior unchanged."
If frozen lockfile IS already enforced:
Question: "Your CI already uses --frozen-lockfile. Would you also like to enforce it project-wide via .npmrc?"
Header: "Lock"
Options:
1. Label: "Yes, add to .npmrc (Recommended)"
Description: "Adds frozen-lockfile=true to .npmrc so it's enforced consistently for all developers, not just CI."
2. Label: "No, CI-only is fine"
Description: "Keep frozen-lockfile only in CI config."
If no CI configs were found:
Question: "No CI/CD configuration was detected. Would you like to add frozen-lockfile=true to .npmrc for local enforcement?"
Header: "Lock"
Options:
1. Label: "Yes, add it (Recommended)"
Description: "Adds frozen-lockfile=true to .npmrc. Prevents 'pnpm install' from modifying the lock file."
2. Label: "No, skip"
Description: "Leave lockfile behavior unchanged."
Also check if frozen-lockfile=true is already in .npmrc: If it is, skip the question entirely and note: ".npmrc already enforces frozen-lockfile=true."
Store the user's choice for Phase 6.
Display a clear preview of all changes before writing:
Supply Chain Security Configuration Preview
============================================
Package Manager: pnpm [version]
Config File: .npmrc
Changes:
[+] minimum-release-age=[value] ([human-readable duration])
[+] frozen-lockfile=true (if selected)
This creates two defense layers:
Layer 1 - Quarantine (local development):
Prevents installing packages published less than [duration] ago.
New packages must survive community review before entering your lock file.
Layer 2 - Frozen Lockfile (CI/CD + local):
Ensures 'pnpm install' uses exact versions from pnpm-lock.yaml.
Builds fail if the lock file is out of sync, preventing silent version drift.
Learn more: https://charlesjones.dev/blog/npm-supply-chain-attacks-ci-cd-locked-dependencies
After displaying the preview, apply the changes:
If .npmrc exists:
minimum-release-age already exists, use the Edit tool to replace the existing valueminimum-release-age does not exist, use the Edit tool to append the new settingsfrozen-lockfile is being added and doesn't already exist, append it as wellIf .npmrc does not exist:
.npmrc with the new settingsFormatting rules for .npmrc:
# Supply chain securityminimum-release-age=[value] on the next linefrozen-lockfile=true on the next lineExample new .npmrc:
# Supply chain security
minimum-release-age=4320
frozen-lockfile=true
Example appended to existing .npmrc:
shamefully-hoist=true
# Supply chain security
minimum-release-age=4320
frozen-lockfile=true
After writing the configuration:
.npmrc using the Read tool to verify the changes were written correctlyminimum-release-age is present with the correct valuefrozen-lockfile is present if it was selectedDisplay a success message:
Supply chain security configured!
.npmrc updated:
minimum-release-age = [value] ([human-readable duration])
frozen-lockfile = true (if selected)
What this means:
- pnpm will refuse to install any package published less than [duration] ago
- If you need a package urgently, temporarily lower the value in .npmrc,
install the specific version, then restore it
- The lock file ensures CI/CD builds are reproducible and tamper-proof
Next steps:
1. Commit .npmrc to version control
2. Run /security-audit for a comprehensive security analysis
3. Run /security-scan-dependencies to check deployed sites for vulnerable libraries
DO NOT:
test -f, [ -f ], etc.) for file detection.npmrcpnpm install after making changes (leave that to the user)DO:
.npmrc exists.npmrcpnpm --version and optionally npm install -g pnpm@latest.npmrc settings when appendingUse these conversions in all user-facing output:
| Minutes | Human-Readable |
|---|---|
| 1440 | 24 hours |
| 4320 | 3 days |
| 10080 | 7 days |
| Custom | Calculate: value / 1440 days, or value / 60 hours |