
Sap Dependency Security
- 243 installs
- 399 repo stars
- Updated August 4, 2026
- secondsky/sap-skills
SAP dependency security and MCP executable trust policy with secure upgrades, cooldowns, staged rollout, and supply-chain protection.
About
Provides secure dependency-upgrade and MCP trust workflows to prevent supply-chain attacks across SAP CAP/UI5/Fiori/HANA stacks. A developer uses it when upgrading deps, pinning SAP MCP servers, or configuring security policies.
- Secure upgrades with cooldowns and staged rollout
- Pins SAP MCP servers for supply-chain protection
Sap Dependency Security by the numbers
- 243 all-time installs (skills.sh)
- +31 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #700 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/secondsky/sap-skills --skill sap-dependency-securityAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 243 |
|---|---|
| repo stars | ★ 399 |
| Last updated | August 4, 2026 |
| Repository | secondsky/sap-skills ↗ |
What it does
SAP dependency security and MCP executable trust policy with secure upgrades, cooldowns, staged rollout, and supply-chain protection.
Files
SAP Dependency Security
Related Skills
- sap-hana-cli: For dependency-aware database tooling workflows and upgrade guidance
- sap-cap-capire: For CAP dependency-safe runtime and service configuration guidance
- sap-fiori-tools: For secure UI5/Fiori dependency strategy when tooling touches frontend packages
- sapui5: For SAPUI5/OpenUI5 frontend dependency and MCP tooling review
- sap-datasphere: For tenant-connected Datasphere MCP and CLI dependency review
- sap-sac-scripting: For source-pinned SAC MCP setup and local install records
Manage SAP dependency security and upgrades with supply chain protection, compatibility analysis, staged rollout, and comprehensive testing across all major package managers.
When to Use This Skill
- Upgrading major framework or library versions
- Configuring supply chain attack prevention (cooldown, script blocking, lockfile hardening)
- Setting up secure package manager configuration
- Resolving dependency conflicts or peer dependency issues
- Planning incremental upgrade paths with testing
- Automating dependency updates with Renovate, Dependabot, or Snyk
- Auditing dependencies for vulnerabilities
- Setting up CI/CD dependency security workflows
- Pinning or reviewing SAP MCP servers in
.mcp.json - Reviewing SAP CAP, UI5/Fiori, HANA, Datasphere, SAC, SAP Cloud SDK, BTP/CF/mbt, or ABAP/gCTS dependency workflows
Common Issues
| Issue | Recommended response |
|---|---|
Floating MCP package or @latest in .mcp.json | Replace with an exact version or approved source commit and run npm run validate:mcp-security. |
| Lockfile changed unexpectedly | Review package manager config, block lifecycle scripts, and regenerate only after dependency intent is clear. |
| Dependency is too new for cooldown policy | Hold the upgrade unless a documented security exception justifies immediate adoption. |
| Tenant-connected tool changed source | Verify the source URL, commit, and build steps before using credentials. |
Two Modes of Operation
Interactive — Walk through setup questions to generate tailored config. Use for fresh setup.
Default — Apply recommended defaults immediately: 7-day cooldown, block all scripts, frozen-lockfile, lockfile-lint, Dependabot with cooldown. Customization optional.
SAP Development Mode — Use a stricter SAP posture: 14-day cooldown, exact pins for MCP servers and executable tooling, no floating @latest, source commit pins for local MCP servers, and manual review for tenant-connected tools.
SAP Development Mode
Use SAP Development Mode when dependency work touches SAP projects, SAP BTP deployment tooling, SAP SDKs, or any MCP server shipped by this repository.
Core rules:
1. Default to 14-day cooldown for SAP enterprise projects. Record explicit exceptions in the SAP MCP inventory or project review notes. 2. Treat MCP servers as executable dependencies. In .mcp.json, use exact npm pins such as @ui5/mcp-server@0.2.11, never @latest or bare package names. 3. Pin local-source MCPs by commit. SAC uses the trusted secondsky/sap_analytics_cloud_mcp fork and must record commit 2020235505d98111c2889598ab2217c1619b6943. 4. Keep runtime authorization separate. This skill covers package/source/executable trust; use the relevant SAP skill for tenant role design and business authorization. 5. Validate MCP drift with npm run validate:mcp-security after any .mcp.json or SAP MCP inventory change.
Load references/sap-dependency-risk-matrix.md for SAP stack coverage and references/sap-mcp-security.md for MCP update workflow and SAC source-install policy. Use references/sap-mcp-inventory.json as the machine-readable approved MCP package/source list.
Interactive Setup Flow
When the user wants tailored configuration, walk through these decisions. Skip this section entirely if using default mode.
Tier 1: Required Decisions
Always ask these 3 questions before generating any config:
1. Package Manager
"Which package manager does this project use?"
| Answer | Generates |
|---|---|
| npm | .npmrc |
| Bun | bunfig.toml |
| pnpm | pnpm-workspace.yaml |
| Yarn | .yarnrc.yml |
| Deno | deno.json config |
2. Cooldown Period
"How many days should newly published packages age before install? This prevents supply chain attacks where malicious packages are discovered and unpublished within days."
| Option | Days | Use Case |
|---|---|---|
| Aggressive | 3 | Catches most typosquatting |
| Recommended | 7 | Good balance for most projects |
| Conservative | 14 | Critical/production systems |
| Paranoid | 21 | Matches Snyk's built-in default |
| Custom | N | User specifies |
3. Post-Install Script Policy
"How should lifecycle scripts (postinstall, preinstall) be handled? These are the #1 attack vector for supply chain attacks."
| Option | Behavior |
|---|---|
| Block all (recommended) | --ignore-scripts + allow-git=none |
| Allowlist | Block by default, allow specific trusted packages |
| Review only | Warn but don't block |
Tier 2: Security Tooling (Offer as Batch)
"Which of these security features would you like to configure? Select any that apply."
4. CI/CD Automation Tool
| Answer | Generates |
|---|---|
| Dependabot | .github/dependabot.yml with cooldown |
| Renovate | renovate.json with minimumReleaseAge |
| Snyk | No config needed (21-day cooldown built-in) |
| None | Skip |
5. Automerge Policy
| Option | Behavior |
|---|---|
| None | All updates require manual review |
| Minor+Patch only | Auto-merge safe updates, review majors |
| All with approval | Auto-merge after team approval |
6. Update Schedule
| Option | Config Value |
|---|---|
| Daily | "daily" |
| Weekly (default) | "weekly" |
| Biweekly | "biweekly" |
| Monthly | "monthly" |
7. Install-Time Security Tooling
"Which security tools should protect dependency installation?"
| Option | Free? | What It Does |
|---|---|---|
| socket npm wrapper | Yes (beta) | Wraps npm/npx, blocks malicious packages before install. Run socket wrapper on to enable system-wide. |
| npq | Yes | Pre-install auditor (CVE, typosquat, age, provenance checks) |
| Socket Firewall (sfw) | No | Real-time deep analysis, blocks malicious packages |
| socket npm + npq | Yes | Both free tools combined |
| None | — | Skip |
Load references/socket-cli-guide.md for full Socket CLI setup including authentication and free vs authenticated features.
8. Lockfile Validation
| Option | Behavior |
|---|---|
| Yes (recommended) | Adds lockfile-lint + CI script |
| No | Skip |
Tier 3: Advanced Options (Only If User Opts In)
"Would you like to configure any advanced options?"
9. Dev Containers — Generate hardened .devcontainer/devcontainer.json (Yes/No)
10. Secrets Manager — 1Password CLI / Infisical / None
11. pnpm Trust Policy — Enable trustPolicy: no-downgrade (pnpm 10.21+ only, Yes/No)
12. Cooldown Exclusions — Package names that bypass cooldown (e.g., @types/react, typescript, esbuild)
Security-First Upgrade Principles
1. Cooldown before installing — Wait 7 days for general projects or 14 days for SAP enterprise/MCP workflows so new package versions are vetted by the community 2. Block post-install scripts — Prevent arbitrary code execution during npm install 3. Freeze lockfiles in CI — Use deterministic installs (npm ci, --frozen-lockfile) 4. Validate lockfile integrity — Use lockfile-lint to detect injection 5. Audit before trusting — Use npq or Socket CLI to check packages before installing 6. Upgrade incrementally — One major version at a time with testing between each 7. Never blindly upgrade — Avoid npm update or npm-check-updates -u without review 8. Scan before and after — Use socket scan to detect supply chain issues beyond CVEs 9. Pin SAP MCP executables — Use exact npm versions or source commit pins before letting MCP servers access SAP projects or tenants
Cooldown Period: Prevent Supply Chain Attacks
Newly published packages may contain malicious code discovered within hours. Configure a cooldown period to delay installation.
Quick Setup
npm (.npmrc):
min-release-age=7Bun (bunfig.toml):
[install]
minimumReleaseAge = 604800 # 7 days in seconds
minimumReleaseAgeExcludes = ["@types/bun", "typescript"]pnpm (pnpm-workspace.yaml):
minimumReleaseAge: 10080 # 7 days in minutes
minimumReleaseAgeExclude:
- '@types/react'
- typescriptYarn (.yarnrc.yml):
npmMinimalAgeGate: "7d"
npmPreapprovedPackages:
- "@types/react"
- "typescript"Load references/cooldown-config-guide.md for detailed per-PM configuration, CI tool integration, and exclusion patterns.
Use templates/<pm>-security.tmpl for copy-paste ready config files.
Disable Post-Install Scripts
Post-install scripts are the most common supply chain attack vector (Shai-Hulud, Nx, event-stream incidents).
Quick Setup
npm:
npm config set ignore-scripts true
npm config set allow-git noneBun: Disabled by default. Allow specific packages in package.json:
{ "trustedDependencies": ["esbuild", "sharp"] }pnpm (10.0+): Disabled by default. Allow specific packages in pnpm-workspace.yaml:
allowBuilds:
esbuild: true
strictDepBuilds: true # Hard error on unreviewed scriptsLoad references/package-manager-security.md for full per-PM hardening including pnpm trustPolicy, blockExoticSubdeps, and @lavamoat/allow-scripts.
Deterministic & Frozen Installs
Always use frozen install commands in CI to ensure reproducible builds:
| Package Manager | Command | What It Does |
|---|---|---|
| npm | npm ci | Deletes node_modules, installs exact lockfile versions |
| Bun | bun install --frozen-lockfile | Fails if lockfile is out of sync |
| pnpm | pnpm install --frozen-lockfile | Fails if lockfile is out of sync |
| Yarn | yarn install --immutable --immutable-cache | Validates lockfile and cache |
| Deno | deno install --frozen | Frozen installation |
Commit all lockfiles to version control: package-lock.json, bun.lock, pnpm-lock.yaml, yarn.lock, deno.lock.
Lockfile Validation
Install and configure lockfile-lint to detect lockfile injection attacks:
npm install --save-dev lockfile-lint{
"scripts": {
"lint:lockfile": "lockfile-lint --path package-lock.json --type npm --allowed-hosts npm --validate-https",
"preinstall": "npm run lint:lockfile"
}
}Note: lockfile-lint does not currently support Bun's bun.lock / bun.lockb formats.
Pre-Install Security Auditing
npq — Pre-Install Auditor
npm install -g npq
npq install <package> # Audit before installing
npq install <package> --dry-run # Audit without installing
# Shell alias for seamless use
alias npm='npq-hero'
# Use with other PMs
NPQ_PKG_MGR=pnpm npq install <package>
NPQ_PKG_MGR=bun npq install <package>Socket Firewall (sfw) — Real-Time Blocker
npm install -g sfw
sfw npm install <package> # Blocks malicious packages
sfw pnpm add <package>
sfw yarn add <package>Load references/supply-chain-security.md for full comparison of npq vs sfw and what each validates.
Socket CLI Integration
Socket CLI provides proactive supply chain security beyond basic vulnerability scanning — covering malware detection, typosquatting, protestware, install script risks, and license compliance.
Proactive Upgrade Workflow
1. PRE-UPGRADE: socket scan create --report → establish baseline
2. EVALUATE: socket package score npm <pkg>@<ver> → assess target package safety
3. SAFE INSTALL: socket npm install <pkg> → block malicious packages
4. POST-UPGRADE: socket scan create --report → verify no new alerts
5. DIFF: socket scan diff <before> <after> → see exactly what changed
6. FIX: socket fix --minimum-release-age 7d → auto-fix any new CVEs
7. OPTIMIZE: socket optimize → apply security overridesQuick Reference
# Install
npm install -g socket
# Authenticate (required for scans, fixes, package scores)
socket login
# Check a package before upgrading
socket package score npm <package>
# Scan your whole project
socket scan create --report
# Auto-fix CVEs (complements Dependabot/Renovate)
socket fix --minimum-release-age 7d
# Gate CI on security policy
socket ci
# Safe npm wrapper (free, no auth needed)
socket wrapper onLoad references/socket-cli-guide.md for comprehensive command reference, CI workflow templates, alert categories, and free vs authenticated feature matrix.
Dependency Analysis
# Audit for vulnerabilities
bun audit # Bun
npm audit # npm
yarn audit # Yarn
# Socket: deep security assessment (CVEs + supply chain + license)
socket package score npm <package>
socket scan create --report
# Check for outdated packages
bun outdated
npm outdated
# Interactive upgrade (safe — review each)
bunx npm-check-updates --interactive
# Analyze dependency tree
npm ls <package-name>
yarn why <package-name>Staged Upgrade Strategy
Upgrade one dependency at a time with testing between each:
# 1. Create feature branch
git checkout -b upgrade/<package>-<version>
# 2. (Optional) Baseline scan — capture current state
socket scan create --report
# 3. Evaluate target package before upgrading
socket package score npm <package>@<version>
# 4. Upgrade single package
bun add <package>@<version>
# 5. Test immediately
bun test && bunx tsc --noEmit && bun run build
# 6. (Optional) Post-upgrade scan — verify no new alerts
socket scan create --report
# 7. Commit and continue
git add -A && git commit -m "chore: upgrade <package> to <version>"Load references/staged-upgrades.md for codemod automation, custom migration scripts, and peer dependency handling.
Load references/compatibility-matrix.md for version compatibility tables (React 18/19, Next.js 13-15, TypeScript, Tailwind 3/4).
Automated Updates with Cooldown
Configure CI/CD tools to respect cooldown periods:
Dependabot (.github/dependabot.yml)
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
cooldown:
default-days: 7Renovate (renovate.json)
{
"extends": ["config:base"],
"minimumReleaseAge": "7 days",
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch"],
"automerge": true
},
{
"matchUpdateTypes": ["major"],
"automerge": false,
"minimumReleaseAge": "14 days"
}
]
}Snyk
Snyk includes a built-in 21-day cooldown for upgrade PRs. No configuration needed.
Socket Fix (complements Dependabot/Renovate)
Socket Fix automatically resolves CVEs with intelligent upgrade planning. Runs alongside other automation tools — it focuses on CVE remediation specifically:
# Fix all fixable CVEs with cooldown alignment
socket fix --minimum-release-age 7d
# Conservative: no major version bumps
socket fix --minimum-release-age 7d --no-major-updates
# Target specific CVEs
socket fix --id GHSA-hhq3-ff78-jv3g --minimum-release-age 7d
# Preview without applying
socket fix --no-apply-fixes --minimum-release-age 7dFor CI autopilot mode (auto-creates and auto-merges fix PRs), use templates/socket-fix-ci.tmpl.
Load references/socket-cli-guide.md for full socket fix options including --autopilot, --range-style, and --pr-limit.
Use templates/dependabot-security.tmpl or templates/renovate-security.tmpl for complete config files.
Publishing Security
For package maintainers:
# Enable 2FA
npm profile enable-2fa auth-and-writes
# Publish with provenance (cryptographic build proof)
npm publish --provenance
# Trusted publishing via OIDC (eliminates long-lived tokens)
# Configure on npmjs.com, then:
# In GitHub Actions: permissions: id-token: writeLoad references/supply-chain-security.md for full publishing security guide including OIDC setup and dependency tree reduction.
Dev Environment Hardening
Isolate dependency execution from the host system:
- Dev containers — limit blast radius of malicious packages
- Secrets management — use 1Password CLI or Infisical instead of plaintext
.envfiles - Dependency tree reduction — replace common packages with native JS
Use templates/devcontainer-security.tmpl for a hardened dev container config.
Load references/secrets-and-containers.md for dev container setup, secrets management, and dependency reduction patterns.
Testing Strategy
Run tests at every level after each upgrade:
# 1. Static analysis (fastest)
bunx tsc --noEmit && bun run lint
# 2. Unit tests
bun test
# 3. Build check
bun run build
# 4. Integration / E2E (after major upgrades)
bun run test:e2eLoad references/testing-strategy.md for full testing pyramid, CI integration, and bundle analysis.
Rollback Plan
#!/bin/bash
git stash
git checkout -b upgrade/<package>
bun add <package>@latest
if bun test && bun run build; then
git add package.json bun.lock
git commit -m "chore: upgrade <package>"
else
echo "Upgrade failed, rolling back"
git checkout main
git branch -D upgrade/<package>
bun install
fiUpgrade Checklist
Pre-Upgrade:
- [ ] Review current dependency versions
- [ ] Read changelogs for breaking changes
- [ ] Create feature branch
- [ ] Tag current state (git tag pre-upgrade)
- [ ] Run full test suite (baseline)
- [ ] Verify cooldown period is configured
- [ ] For SAP MCP changes, verify exact package/source pins against `references/sap-mcp-inventory.json`
Security Pre-Checks:
- [ ] Post-install scripts are disabled
- [ ] Lockfile validation is active
- [ ] Install auditing tools configured (if applicable)
- [ ] CI uses frozen-lockfile install
- [ ] Run `socket scan create --report` for baseline (if Socket available)
During Upgrade:
- [ ] Upgrade one dependency at a time
- [ ] Check target package: `socket package score npm <pkg>` (if Socket available)
- [ ] Respect cooldown period (don't force latest)
- [ ] Update peer dependencies
- [ ] Fix TypeScript errors
- [ ] Run test suite after each upgrade
- [ ] Check bundle size impact
Post-Upgrade:
- [ ] Post-upgrade scan: `socket scan diff` to verify no new alerts (if Socket available)
- [ ] Consider `socket fix --minimum-release-age 7d` for any new CVEs
- [ ] Full regression testing
- [ ] Performance testing
- [ ] Update documentation
- [ ] Deploy to staging
- [ ] Monitor for errors
- [ ] Deploy to productionCommon Pitfalls
- Upgrading all dependencies at once (use incremental upgrades)
- Blindly running
npm updateornpm-check-updates -uwithout review - Not testing after each individual upgrade
- Ignoring peer dependency warnings
- Forgetting to update or commit the lock file
- Not reading breaking change notes in changelogs
- Skipping major versions instead of stepping through them
- Not having a rollback plan
- Trusting npmjs.org displayed source code (can differ from actual tarball)
- Leaving post-install scripts enabled (most common attack vector)
- Not configuring a cooldown period for new package versions
- Shipping SAP MCP configs with
@latest, barenpxpackages, or unpinned local source paths
When to Load References
Load these reference files when the user needs detailed information beyond the quick-reference in SKILL.md:
| Load This File | When |
|---|---|
references/cooldown-config-guide.md | Configuring cooldown for a specific PM, CI tool integration, or exclusion patterns |
references/package-manager-security.md | Full per-PM hardening guide including pnpm trust policy, blockExoticSubdeps, cross-PM cheat sheet |
references/supply-chain-security.md | Understanding attack vectors, incident history, npq vs sfw vs Socket CLI comparison, publisher security (2FA, provenance, OIDC) |
references/secrets-and-containers.md | Setting up dev containers, secrets management with 1Password/Infisical |
references/socket-cli-guide.md | Using Socket CLI for scans, fixes, package scoring, CI integration, wrapper mode, alert categories |
references/compatibility-matrix.md | Checking version compatibility for React, Next.js, TypeScript, Tailwind upgrades |
references/staged-upgrades.md | Codemod automation, custom migration scripts, peer dependency handling, workspace upgrades |
references/testing-strategy.md | Full testing pyramid, CI integration, bundle analysis, performance testing |
references/sap-dependency-risk-matrix.md | SAP stack-specific dependency review across Node, Java, Python, containers, BTP/CF/mbt, ABAP/gCTS, and MCP |
references/sap-mcp-security.md | SAP MCP exact-pin policy, SAC source-install policy, and MCP update workflow |
references/sap-mcp-inventory.json | Machine-readable approved SAP MCP package/source pins used by npm run validate:mcp-security |
Template Files
Ready-to-use config files in templates/:
| Template | Purpose |
|---|---|
npmrc-security.tmpl | Secure .npmrc with scripts disabled + cooldown |
bunfig-security.tmpl | Secure bunfig.toml with cooldown + exclusions |
pnpm-workspace-security.tmpl | Secure pnpm-workspace.yaml with cooldown, allowBuilds, trustPolicy |
yarnrc-security.tmpl | Secure .yarnrc.yml with age gate + preapproved packages |
dependabot-security.tmpl | Dependabot config with 7-day cooldown |
renovate-security.tmpl | Renovate config with minimumReleaseAge + automerge rules |
devcontainer-security.tmpl | Hardened dev container with security options |
socket-fix-ci.tmpl | GitHub Actions: Socket Fix autopilot with cooldown-aligned CVE remediation |
socket-scan-ci.tmpl | GitHub Actions: Socket CI security gate for every push/PR |
sap-mcp-config.tmpl | Review-ready SAP MCP config candidate with exact-pin checklist |
maven-security.tmpl | Maven checksum/enforcer/dependency scan fragment for SAP Java projects |
gradle-security.tmpl | Gradle dependency locking and verification fragment |
python-security.tmpl | Python lock/audit workflow for SAP AI SDK, HANA ML, and data tooling |
container-trivy.tmpl | Container image scan workflow with Trivy and digest-pin reminders |
btp-cf-mbt-review.tmpl | BTP, Cloud Foundry, and MBT dependency/deployment review checklist |
abap-gcts-review.tmpl | ABAP, gCTS, and transport dependency review checklist |
SAP Dependency Security Skill
SAP dependency security and upgrade orchestration guidance for JavaScript, Node.js, MCP servers, and multi-language projects.
Capability Index
| Capability | Status |
|---|---|
| Commands | 1: /sap-dependency-upgrade-plan |
| Agents | 0 |
| Hooks | Yes: hooks/hooks.json |
| MCP | No |
| LSP | No |
| Source Freshness | last_verified: 2026-06-14; dependency-security hook behavior validated locally. |
| Verification | npm run validate; package registry freshness depends on current lockfile evidence. |
Trigger Keywords
- dependency upgrades
- supply-chain protection
- lockfile hardening
- package manager security
- cooldown policy
- Dependabot
- Renovate
- npm
- pnpm
- Bun
- Yarn
- Deno
- CI security
- SAP dependency security
- SAP MCP server pins
- CAP/UI5/Fiori dependency policy
- HANA/Datasphere/SAC MCP trust
- BTP/CF/mbt dependency review
- ABAP/gCTS transport review
Dependency Compatibility Matrix
Common version compatibility requirements for major frameworks and libraries.
React Ecosystem
| React | react-dom | react-router | @testing-library/react | Next.js |
|---|---|---|---|---|
| 18.x | ^18.0.0 | ^6.0.0 | ^14.0.0 | 13.x-14.x |
| 19.x | ^19.0.0 | ^7.0.0 | ^16.0.0 | 15.x |
React 18 → 19 Migration
bun add react@19 react-dom@19
bun add -D @testing-library/react@16 @types/react@19 @types/react-dom@19Key breaking changes:
- Ref as prop (no more
forwardRefneeded) useDeferredValueinitial value support- Improved hydration mismatch reporting
refcleanup functions return value is ignored
React Router 6 → 7
bun add react-router@7 react-router-dom@7React Router v7 is the successor to Remix and React Router v6. Key changes:
- Framework mode (Remix-like) vs library mode
- New
createRootRoute,createRouterAPI - Data loading via
loaderandaction
Next.js
| Next.js | React | Node.js | TypeScript |
|---|---|---|---|
| 13.x | 18.x | >=16.8 | >=4.5 |
| 14.x | 18.x | >=18.17 | >=4.5 |
| 15.x | 18.x-19.x | >=20.9 | >=4.5 |
Next.js 14 → 15 Migration
bun add next@15Key breaking changes:
- Turbopack as default dev bundler
- Improved caching defaults (fetch requests no longer cached by default)
next/imagechanges- Node.js >=20.9 required
TypeScript
| TypeScript | Node.js target | Key feature |
|---|---|---|
| 5.3 | ES2022+ | using keyword, Symbol.dispose |
| 5.4 | ES2022+ | NoInfer utility type |
| 5.5 | ES2022+ | Inferred type predicates |
| 5.6 | ES2022+ | Iterator helpers |
| 5.7 | ES2024+ | --target es2024, path renaming |
TypeScript Upgrade
bun add -D typescript@latestTypeScript upgrades are typically backward compatible. Run type-check after upgrade:
bunx tsc --noEmitTailwind CSS
| Tailwind | PostCSS | Framework support |
|---|---|---|
| 3.x | >=8.4 | All frameworks |
| 4.x | Built-in | All frameworks (new engine) |
Tailwind 3 → 4 Migration
bun add -D tailwindcss@4 @tailwindcss/viteKey changes:
- CSS-first configuration (
@themeinstead oftailwind.config.js) - Required primary entrypoint:
@import "tailwindcss" - PostCSS plugin via
@tailwindcss/postcsspackage (must install and configure) - Lightning CSS can replace PostCSS in some setups per official Tailwind recommendations
- New
@source inline("class-name")pattern for safelisting utilities
Node.js Version Compatibility
| Node.js | npm version | npm ci support |
|---|---|---|
| 18 LTS | 9.x | Yes |
| 20 LTS | 10.x | Yes |
| 22 LTS | 10.x | Yes |
See Node.js Release Schedule for LTS dates.
Checking Compatibility
# Check peer dependency warnings
npm ls 2>&1 | grep -i "peer dep"
# Check for outdated with compatibility info
npm outdated
# Use npm-check-updates for safe upgrade analysis
bunx npm-check-updates --interactive
# Check for known vulnerabilities
npm audit
bun auditCooldown Period Configuration Guide
Detailed configuration for delaying installation of newly published packages across all major package managers and CI/CD tools.
Why a Cooldown Period?
Newly released packages may contain malicious code that the community discovers within hours or days. A cooldown period prevents installing versions before they've been vetted.
Recommended minimum: 7 days — balances security with developer productivity.
| Period | Risk Level | Use Case |
|---|---|---|
| 3 days | Aggressive | Catches most typosquatting; may miss delayed discoveries |
| 7 days | Recommended | Good balance; catches most supply chain incidents |
| 14 days | Conservative | Critical/production systems |
| 21 days | Paranoid | Matches Snyk's built-in default |
Package Manager Configuration
npm
# .npmrc — project-level
min-release-age=7# Global config (all projects on machine)
npm config set min-release-age 7
# Per-command with dynamic date
npm install express --before="$(date -v -7d)"
# Per-command with specific date
npm install express --before=2025-01-01Notes:
min-release-ageis persistent and works with all install commands--beforerequires manual date management; prefermin-release-agefor automation
Bun (1.3+)
# bunfig.toml
[install]
# Only install versions published at least 7 days ago
minimumReleaseAge = 604800 # seconds (7 days)
# Packages that bypass the cooldown
minimumReleaseAgeExcludes = ["@types/bun", "typescript"]The minimumReleaseAge value is in seconds:
- 3 days = 259200
- 7 days = 604800
- 14 days = 1209600
- 21 days = 1814400
pnpm (10.16+)
# pnpm-workspace.yaml
minimumReleaseAge: 10080 # 7 days (in minutes)
# Packages that bypass the cooldown
minimumReleaseAgeExclude:
- '@types/react'
- typescriptThe minimumReleaseAge value is in minutes:
- 3 days = 4320
- 7 days = 10080
- 14 days = 20160
- 21 days = 30240
Yarn (4.10+)
# .yarnrc.yml
# Only consider versions published at least 7 days ago
npmMinimalAgeGate: "7d"
# Packages that bypass the age gate (descriptors or glob patterns)
npmPreapprovedPackages:
- "@types/react"
- "typescript"The npmMinimalAgeGate accepts human-readable durations: "3d", "7d", "14d", "21d".
CI/CD Tool Configuration
Dependabot
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
# Wait 7 days after a new version is published before creating a PR
cooldown:
default-days: 7
open-pull-requests-limit: 5Renovate Bot
{
"extends": ["config:base"],
"minimumReleaseAge": "7 days",
"packageRules": [
{
"matchUpdateTypes": ["minor", "patch"],
"automerge": true,
"minimumReleaseAge": "7 days"
},
{
"matchUpdateTypes": ["major"],
"automerge": false,
"minimumReleaseAge": "14 days",
"labels": ["major-update"]
}
]
}Snyk
Snyk includes a built-in 21-day cooldown for automated dependency upgrade PRs. No configuration needed — it automatically avoids recommending versions less than 21 days old to prevent:
- Versions with functional bugs that get unpublished
- Versions from compromised accounts
To adjust, use Snyk's upgrade PR settings in the dashboard.
Cooldown Exclusions
Some packages should bypass the cooldown because they are closely tied to the toolchain and need rapid updates:
Common Exclusions
| Package | Reason |
|---|---|
@types/react | Type definitions must match React version exactly |
@types/node | Type definitions must match Node version |
typescript | Build tooling; often needs same-day patches |
@types/bun | Bun type definitions must match runtime version |
esbuild | Build tool; security patches need fast rollout |
@cloudflare/workers-types | Platform types must match runtime |
Configuring Exclusions
npm: No built-in exclusion mechanism. Use --before flag manually for excluded packages.
Bun:
minimumReleaseAgeExcludes = ["@types/bun", "typescript", "esbuild"]pnpm:
minimumReleaseAgeExclude:
- '@types/react'
- typescript
- esbuildYarn:
npmPreapprovedPackages:
- "@types/react"
- "typescript"
- "esbuild"Multi-PM Projects
For projects that support multiple package managers, ensure cooldown is configured in all relevant files:
| PM | Config File | Setting |
|---|---|---|
| npm | .npmrc | min-release-age=7 |
| Bun | bunfig.toml | minimumReleaseAge = 604800 |
| pnpm | pnpm-workspace.yaml | minimumReleaseAge: 10080 |
| Yarn | .yarnrc.yml | npmMinimalAgeGate: "7d" |
| Dependabot | .github/dependabot.yml | cooldown.default-days: 7 |
| Renovate | renovate.json | "minimumReleaseAge": "7 days" |
Verifying Cooldown Is Active
# npm — check config
npm config get min-release-age
# Bun — verify bunfig.toml is loaded
cat bunfig.toml | grep minimumReleaseAge
# pnpm — verify workspace config
cat pnpm-workspace.yaml | grep minimumReleaseAge
# Yarn — verify config
cat .yarnrc.yml | grep npmMinimalAgeGatePackage Manager Security Hardening
Per-package-manager security configuration covering post-install scripts, deterministic installs, and supply chain protections.
npm
Disable Lifecycle Scripts
# .npmrc
ignore-scripts=true
allow-git=none# Global
npm config set ignore-scripts true
npm config set allow-git none--allow-git=none (npm CLI 11.10.0+) prevents git-based dependencies from shipping .npmrc files that re-enable lifecycle scripts, closing a bypass vector.
Deterministic Installs
# CI/CD — strict lockfile adherence
npm ci
npm ci --only=production
# Never use npm install in CInpm ci:
- Deletes
node_modulesbefore installing - Requires
package-lock.jsonto exist - Fails if lockfile is out of sync with
package.json - Installs exact versions from lockfile only
Lockfile Validation
npm install --save-dev lockfile-lint
npx lockfile-lint \
--path package-lock.json \
--type npm \
--allowed-hosts npm yarn \
--validate-httpsCooldown
# .npmrc
min-release-age=7Bun
Post-Install Script Control
Bun disables postinstall scripts by default. Allow specific packages via package.json:
{
"trustedDependencies": [
"esbuild",
"sharp"
]
}Deterministic Installs
# Frozen lockfile mode (CI)
bun install --frozen-lockfileCooldown
# bunfig.toml
[install]
minimumReleaseAge = 604800 # 7 days in seconds
minimumReleaseAgeExcludes = ["@types/bun", "typescript"]Lockfile Notes
Bun uses bun.lock (text, default since v1.2) or bun.lockb (binary). lockfile-lint does not support Bun lockfile formats currently.
pnpm
Post-Install Script Control (10.0+)
pnpm disables postinstall scripts by default since v10.0.
# pnpm-workspace.yaml
# Preferred (pnpm 10.26+)
allowBuilds:
esbuild: true
fsevents: true
nx@21.6.4 || 21.6.5: true
core-js: false
# Legacy (still supported)
# onlyBuiltDependencies:
# - esbuild
# - fsevents
# Hard error on unreviewed scripts (pnpm 10.3+)
strictDepBuilds: trueTrust Policy (pnpm 10.21+)
Detect when a package's trust level has decreased — early signal of account compromise:
# pnpm-workspace.yaml
trustPolicy: no-downgrade
trustPolicyExclude:
- 'chokidar@4.0.3'
- 'webpack@4.47.0 || 5.102.1'
# Ignore packages published >30 days ago (pnpm 10.27+)
trustPolicyIgnoreAfter: 43200 # minutesTrust levels (strongest → weakest): 1. Trusted Publisher (OIDC/GitHub Actions) 2. Provenance (npm provenance attestation) 3. Signatures (registry signature) 4. No evidence
Block Exotic Transitive Dependencies (pnpm 10.26+)
# pnpm-workspace.yaml
blockExoticSubdeps: truePrevents transitive dependencies from using git repos or direct tarball URLs. Only direct dependencies in package.json may use exotic sources.
Deterministic Installs
# Frozen lockfile (CI)
pnpm install --frozen-lockfileLockfile Security
pnpm is inherently more resistant to lockfile injection:
- Doesn't maintain modifiable tarball sources
- Won't install lockfile packages not declared in
package.json pnpm-lock.yamlformat is more resistant to injection
Cooldown
# pnpm-workspace.yaml
minimumReleaseAge: 10080 # 7 days in minutes
minimumReleaseAgeExclude:
- '@types/react'
- typescriptYarn
Deterministic Installs
# Validate lockfile did not mutate
yarn install --immutable --immutable-cacheCooldown (Yarn 4.10+)
# .yarnrc.yml
npmMinimalAgeGate: "7d"
npmPreapprovedPackages:
- "@types/react"
- "typescript"Lockfile Validation
npx lockfile-lint \
--path yarn.lock \
--type yarn \
--allowed-hosts npm yarn \
--validate-httpsDeno
Deterministic Installs
deno install --frozenLockfile
Deno uses deno.lock. Ensure it's committed to version control.
Cross-PM Cheat Sheet
| Feature | npm | Bun | pnpm | Yarn | Deno |
|---|---|---|---|---|---|
| Disable scripts | ignore-scripts=true | Default off | Default off (10.0+) | N/A | N/A |
| Script allowlist | @lavamoat/allow-scripts | trustedDependencies | allowBuilds | N/A | N/A |
| Frozen install | npm ci | --frozen-lockfile | --frozen-lockfile | --immutable | --frozen |
| Cooldown | min-release-age | minimumReleaseAge (sec) | minimumReleaseAge (min) | npmMinimalAgeGate | N/A |
| Lockfile format | package-lock.json | bun.lock / bun.lockb | pnpm-lock.yaml | yarn.lock | deno.lock |
| Lockfile lint | lockfile-lint | Not supported | lockfile-lint | lockfile-lint | N/A |
| Trust policy | N/A | N/A | trustPolicy (10.21+) | N/A | N/A |
| Block exotic deps | N/A | N/A | blockExoticSubdeps (10.26+) | N/A | N/A |
| Lockfile to commit | package-lock.json | bun.lock | pnpm-lock.yaml | yarn.lock | deno.lock |
Committing Lockfiles
Always commit lockfiles to version control:
git add package-lock.json # npm
git add bun.lock # Bun
git add pnpm-lock.yaml # pnpm
git add yarn.lock # Yarn
git add deno.lock # DenoNever add lockfiles to .gitignore. They are the source of truth for reproducible installs.
SAP Dependency Risk Matrix
Use this reference when a dependency update touches SAP development tooling, SAP runtime libraries, deployment assets, or MCP servers. The default SAP posture is stricter than the generic dependency workflow: 14-day cooldown, exact pins for executable tooling, frozen installs, and manual review for tenant-connected tools.
Ecosystem Matrix
| Area | Typical Artifacts | Main Risks | Required Checks |
|---|---|---|---|
| CAP / UI5 / Fiori Node tooling | package.json, lockfiles, .npmrc, ui5.yaml, mta.yaml | Lifecycle scripts, transitive tooling compromise, UI build drift | Exact tool pins, frozen install, script blocking, lockfile review, npm audit or Socket/OSV |
| SAP MCP servers | .mcp.json, env vars, local source checkout | Executing unreviewed packages with SAP project or tenant access | Exact npm pin or source commit pin, no @latest, inventory entry, validator pass |
| SAP Cloud SDK Java / CAP Java | pom.xml, mvnw, .mvn/maven.config | BOM drift, repository substitution, vulnerable transitive JARs | Maven wrapper, strict checksums, dependency tree review, OSV-Scanner |
| Gradle Java services | build.gradle, settings.gradle, gradle.lockfile | Dynamic versions, unverified artifacts, plugin portal drift | Dependency locking, verification metadata, no dynamic versions, OSV-Scanner |
| SAP AI SDK / HANA ML Python | pyproject.toml, requirements*.txt, uv.lock | Unlocked wheels, extras pulling broad provider trees, typosquats | Lockfile, hashes where practical, pip-audit, uv pip compile or equivalent |
| Containers / Kyma | Dockerfile, Helm/Kubernetes manifests | Base image CVEs, mutable tags, privileged runtime | Digest-pinned base images, Trivy scan, non-root user, minimal capabilities |
| BTP / CF / mbt tooling | mta.yaml, xs-security.json, pipeline scripts | Global CLI drift, service binding changes, accidental deploy target changes | Pin CLI versions in CI, review service bindings, verify cf target, inspect MTAR diff |
| ABAP / gCTS / transports | Software components, transport requests, abapGit repos | Transport dependency gaps, unreviewed generated objects, cross-system drift | Import queue review, dependency order check, ATC/security checks, rollback transport |
SAP Defaults
- Use a 14-day cooldown for SAP enterprise projects unless a maintainer records an exception.
- Prefer project-local tooling over global installs in CI.
- Treat MCP servers as executable dependencies, not passive documentation.
- Keep runtime authorization design in the relevant SAP skill. This skill covers dependency, package, source, and executable trust.
- For credentialed MCPs, review both package/source trust and whether the configured credential is least-privilege.
Review Prompts
- What executable code changes during this update: package tarball, JAR, wheel, container layer, or source checkout?
- Does the update alter tenant access, deployment targets, service bindings, or generated artifacts?
- Is the new version old enough for the SAP cooldown, or is there an explicit exception?
- Can CI reproduce the install from locked inputs without network-time latest resolution?
- Is rollback possible without manually reconstructing tool versions or generated output?
{
"policy": {
"sapCooldownDays": 14,
"lastVerified": "2026-06-15",
"freshnessEvidence": "docs/project/package-evidence/2026-06-15.json",
"notes": "SAP MCP servers are executable dependencies. Use exact npm pins or documented source commits; no @latest or bare npx package specs. Observed latest versions are freshness evidence only; do not update approvedVersion without compatibility review."
},
"npmPackages": {
"@cap-js/mcp-server": {
"approvedVersion": "0.0.5",
"observedLatest": "0.0.5",
"observedAt": "2026-06-15",
"source": "npm view @cap-js/mcp-server version dist-tags --json",
"cooldownUntil": "2026-06-29",
"approvalReason": "Current approved exact pin remains aligned with public latest.",
"owner": "CAP project",
"usedBy": "plugins/sap-cap-capire/.mcp.json",
"operationClasses": ["local-only"],
"approvalRequired": false,
"trust": "CAP model and documentation access; no tenant credentials in the bundled config.",
"envContract": [],
"scan": "npm view @cap-js/mcp-server@0.0.5 version dist.integrity && npm audit --package-lock-only"
},
"@mariodefe/sap-datasphere-mcp": {
"approvedVersion": "1.2.1",
"observedLatest": "1.4.0",
"observedAt": "2026-06-15",
"source": "npm view @mariodefe/sap-datasphere-mcp version dist-tags --json",
"cooldownUntil": "2026-06-29",
"approvalReason": "Upgrade candidate only; tenant-safe masking and tool compatibility must be reviewed before pin changes.",
"owner": "Community package",
"usedBy": "plugins/sap-datasphere/.mcp.json",
"operationClasses": ["read-only tenant", "mutating tenant", "destructive"],
"approvalRequired": true,
"trust": "Datasphere tenant access through OAuth environment variables; update only after explicit review.",
"envContract": [
{"name": "DATASPHERE_BASE_URL", "secret": false, "required": true, "format": "https URL for the tenant", "access": "tenant metadata/API endpoint"},
{"name": "DATASPHERE_CLIENT_ID", "secret": true, "required": true, "format": "OAuth client id placeholder", "access": "tenant OAuth client"},
{"name": "DATASPHERE_CLIENT_SECRET", "secret": true, "required": true, "format": "environment placeholder only", "access": "tenant OAuth secret"},
{"name": "DATASPHERE_TOKEN_URL", "secret": false, "required": true, "format": "https OAuth token URL", "access": "tenant OAuth endpoint"}
],
"scan": "npm view @mariodefe/sap-datasphere-mcp@1.2.1 version dist.integrity && npm audit --package-lock-only"
},
"@sap-ux/fiori-mcp-server": {
"approvedVersion": "1.4.0",
"observedLatest": "1.4.0",
"observedAt": "2026-06-15",
"source": "npm view @sap-ux/fiori-mcp-server version dist-tags --json",
"cooldownUntil": "2026-06-29",
"approvalReason": "Current approved exact pin remains aligned with public latest.",
"owner": "SAP Fiori tools / open-ux-tools",
"usedBy": "plugins/sap-fiori-tools/.mcp.json",
"operationClasses": ["local-only"],
"approvalRequired": false,
"trust": "Newest exact pin approved by maintainer request on 2026-06-14 despite the SAP 14-day cooldown default.",
"envContract": [],
"scan": "npm view @sap-ux/fiori-mcp-server@1.4.0 version dist.integrity && npm audit --package-lock-only"
},
"@ui5/mcp-server": {
"approvedVersion": "0.2.11",
"observedLatest": "0.2.12",
"observedAt": "2026-06-15",
"source": "npm view @ui5/mcp-server version dist-tags --json",
"cooldownUntil": "2026-06-29",
"approvalReason": "Upgrade candidate only; tool-name and lint/scaffold compatibility must be reviewed before pin changes.",
"owner": "UI5 project",
"usedBy": "plugins/sapui5/.mcp.json",
"operationClasses": ["local-only"],
"approvalRequired": false,
"trust": "UI5 documentation, scaffolding, and lint tooling; no tenant credentials in the bundled config.",
"envContract": [
{"name": "UI5_MCP_SERVER_RESPONSE_NO_RESOURCES", "secret": false, "required": false, "format": "boolean string", "access": "response-size compatibility flag"}
],
"scan": "npm view @ui5/mcp-server@0.2.11 version dist.integrity && npm audit --package-lock-only"
},
"hana-mcp-server": {
"approvedVersion": "0.3.1",
"observedLatest": "0.3.1",
"observedAt": "2026-06-15",
"source": "npm view hana-mcp-server version dist-tags --json",
"cooldownUntil": "2026-06-29",
"approvalReason": "Current approved exact pin remains aligned with public latest.",
"owner": "Community package",
"usedBy": "plugins/sap-hana-cli/.mcp.json",
"operationClasses": ["read-only tenant", "mutating tenant", "destructive"],
"approvalRequired": true,
"trust": "HANA database access through environment variables; update only after explicit review.",
"envContract": [
{"name": "HANA_HOST", "secret": false, "required": true, "format": "hostname", "access": "HANA endpoint"},
{"name": "HANA_PORT", "secret": false, "required": true, "format": "numeric port", "access": "HANA endpoint"},
{"name": "HANA_USER", "secret": true, "required": true, "format": "database username placeholder", "access": "HANA database user"},
{"name": "HANA_PASSWORD", "secret": true, "required": true, "format": "environment placeholder only", "access": "HANA database password"},
{"name": "HANA_ENCRYPT", "secret": false, "required": false, "format": "boolean string; default true", "access": "TLS mode"},
{"name": "HANA_DATABASE", "secret": false, "required": false, "format": "database name", "access": "database selector"},
{"name": "HANA_CONNECTION_TYPE", "secret": false, "required": false, "format": "single-container or hdi style", "access": "connection mode"}
],
"scan": "npm view hana-mcp-server@0.3.1 version dist.integrity && npm audit --package-lock-only"
}
},
"sourceServers": {
"plugins/sap-sac-scripting/.mcp.json:sac-mcp": {
"repo": "https://github.com/secondsky/sap_analytics_cloud_mcp",
"commit": "2020235505d98111c2889598ab2217c1619b6943",
"observedLatest": "source-commit",
"observedAt": "2026-06-15",
"source": "Pinned source install; verify with git rev-parse before runtime use.",
"cooldownUntil": "2026-06-29",
"approvalReason": "Source MCP remains pinned by commit and path token; update only after source review.",
"pathEnv": "SAC_MCP_PATH",
"commitEnv": "SAC_MCP_COMMIT",
"usedBy": "plugins/sap-sac-scripting/.mcp.json",
"operationClasses": ["read-only tenant", "mutating tenant", "destructive"],
"approvalRequired": true,
"trust": "Trusted secondsky fork source install. This MCP uses SAC OAuth credentials and exposes read/write SAC REST API tools.",
"envContract": [
{"name": "SAC_MCP_PATH", "secret": false, "required": true, "format": "local path placeholder", "access": "local source checkout"},
{"name": "SAC_MCP_COMMIT", "secret": false, "required": true, "format": "exact git commit", "access": "source provenance"},
{"name": "SAC_BASE_URL", "secret": false, "required": true, "format": "https SAC tenant URL", "access": "SAC tenant endpoint"},
{"name": "SAC_TOKEN_URL", "secret": false, "required": true, "format": "https OAuth token URL", "access": "SAC OAuth endpoint"},
{"name": "SAC_CLIENT_ID", "secret": true, "required": true, "format": "OAuth client id placeholder", "access": "SAC OAuth client"},
{"name": "SAC_CLIENT_SECRET", "secret": true, "required": true, "format": "environment placeholder only", "access": "SAC OAuth secret"}
],
"scan": "git -C \"$SAC_MCP_PATH\" rev-parse HEAD && npm --prefix \"$SAC_MCP_PATH\" ci --ignore-scripts && npm --prefix \"$SAC_MCP_PATH\" audit"
}
}
}
SAP MCP Security Policy
Use this reference when configuring, updating, or reviewing SAP MCP servers. MCP servers are executable dependencies. Some only read local project metadata, while others use SAP tenant credentials and can call live APIs.
Operation Safety Classes
local-only: Operates on local files, local package metadata, local project models, or cached docs.read-only tenant: Reads tenant/system metadata or data and must not mutate tenant state.mutating tenant: Creates, updates, deploys, publishes, triggers, or otherwise changes tenant/system state.destructive: Deletes, drops, revokes, removes, disables, resets, or risks irreversible tenant/system impact.
Require explicit user approval before any mutating tenant or destructive MCP operation. Keep credentials, tokens, service keys, destinations, and tenant URLs in environment variables or local secret managers.
Policy
- Use exact npm package pins in
.mcp.json; never use@latestor a bare package name. - Use the SAP MCP inventory (
sap-mcp-inventory.json) as the source of approved package/source pins. - Use a 14-day SAP cooldown by default. A newer version can be approved only when the inventory records the exception.
- For local-source MCPs, pin the trusted repository and exact commit SHA. Do not trust a moving branch.
- Keep tenant credentials in environment variables or local secret managers. Do not commit
.env, service keys, or generated local install records. - Run
npm run validate:mcp-securityafter changing any plugin.mcp.json.
Current Approved MCP Pins
| Plugin | MCP Package / Source | Approved Pin |
|---|---|---|
sap-cap-capire | @cap-js/mcp-server | 0.0.5 |
sapui5 | @ui5/mcp-server | 0.2.11 |
sap-fiori-tools | @sap-ux/fiori-mcp-server | 1.4.0 |
sap-hana-cli | hana-mcp-server | 0.3.1 |
sap-datasphere | @mariodefe/sap-datasphere-mcp | 1.2.1 |
sap-sac-scripting | secondsky/sap_analytics_cloud_mcp | 2020235505d98111c2889598ab2217c1619b6943 |
SAC Source MCP
The SAC MCP server is source-installed because the trusted secondsky/sap_analytics_cloud_mcp fork is not published as a versioned npm package in this repo. Treat it like a package with a source commit pin:
git clone https://github.com/secondsky/sap_analytics_cloud_mcp
cd sap_analytics_cloud_mcp
git checkout 2020235505d98111c2889598ab2217c1619b6943
npm ci --ignore-scripts
npm run buildRecord the installation in .claude/sac-mcp.local.md:
# SAC MCP Installation Record
- Repository: https://github.com/secondsky/sap_analytics_cloud_mcp
- Commit: 2020235505d98111c2889598ab2217c1619b6943
- Path: /absolute/path/to/sap_analytics_cloud_mcp/build/index.js
- Build command: npm ci --ignore-scripts && npm run build
- Env vars configured: SAC_MCP_PATH, SAC_MCP_COMMIT, SAC_BASE_URL, SAC_TOKEN_URL, SAC_CLIENT_ID, SAC_CLIENT_SECRETUpdate Workflow
1. Check the current package or source release metadata. 2. Apply the 14-day cooldown unless a maintainer records an exception. 3. Scan the package/source using the command in sap-mcp-inventory.json. 4. Update .mcp.json manually with the exact version or source commit marker. 5. Update sap-mcp-inventory.json in the same change. 6. Run npm run validate:mcp-security and the affected SAP plugin checks.
Dev Environment Hardening: Secrets & Containers
Isolate dependency execution and protect sensitive data from supply chain attacks.
Dev Containers
Running npm install on a host machine exposes the entire system to malicious packages. Dev containers limit blast radius.
Basic Setup
Create .devcontainer/devcontainer.json:
{
"name": "Node.js Dev Container",
"image": "mcr.microsoft.com/devcontainers/javascript-node:20",
"features": {
"ghcr.io/devcontainers/features/1password:1": {}
},
"postCreateCommand": "npm ci",
"customizations": {
"vscode": {
"extensions": ["dbaeumer.vscode-eslint"]
}
}
}Hardened Setup
{
"name": "Node.js Hardened Dev Container",
"image": "mcr.microsoft.com/devcontainers/javascript-node:20",
"runArgs": [
"--security-opt=no-new-privileges:true",
"--cap-drop=ALL",
"--cap-add=CHOWN",
"--cap-add=SETUID",
"--cap-add=SETGID"
],
"containerEnv": {
"NODE_OPTIONS": "--disable-proto=delete"
},
"postCreateCommand": "npm ci"
}Security controls:
no-new-privileges:true— prevents privilege escalation--cap-drop=ALL— drops all Linux capabilities- Minimal capabilities added back:
CHOWN,SETUID,SETGID(needed for npm) --disable-proto=delete— hardens JavaScript prototype chain
What This Prevents
When a malicious package executes during npm install:
- Without container: Access to all files, SSH keys, env vars, other projects
- With container: Confined to container filesystem, no host access
Secrets Management
The Problem with .env Files
Plaintext secrets in .env files are accessible to any code running in the process:
# DANGEROUS — plaintext secrets
DATABASE_PASSWORD=my-secret-password
API_KEY=sk-1234567890abcdefSupply chain attacks can read process.env or scan for .env files on the filesystem.
1Password CLI Integration
# Install 1Password CLI
brew install 1password-cli
# Use secret references in .env
DATABASE_PASSWORD=op://vault/database/password
API_KEY=op://vault/project/api-key
# Run with secret injection
op run -- npm start
# With explicit env file
op run --env-file="./.env" -- node --env-file="./.env" server.jsSecret references are resolved at runtime with additional authentication (Touch ID on macOS). The actual secret values never exist in files.
Infisical Integration
# Install Infisical CLI
brew install infisical
# Use secret references
DATABASE_PASSWORD=infisical://project/env/api-key
# Run with secret injection
infisical run -- npm startBun-Specific Notes
# Bun supports .env files natively
# Use with secret manager:
op run -- bun run dev
# Bun also supports --env-file flag
op run -- bun --env-file=./.env run devResources
Socket CLI Guide
Comprehensive reference for using Socket CLI to secure dependency upgrades with proactive scanning, automated CVE fixing, and CI enforcement.
Installation & Authentication
npm install -g socketAuthentication
# Interactive login (stores token locally)
socket login
# Or set API token via environment variable
export SOCKET_SECURITY_API_TOKEN=your-token-here
# Or per-command
SOCKET_SECURITY_API_TOKEN=xyz socket scan create --reportGenerate API tokens at: https://socket.dev/settings/api-keys
Required permissions vary per command (see each section below).
Free vs Authenticated Features
| Feature | Free (No Token) | Authenticated |
|---|---|---|
socket npm / socket npx | Yes (beta, default issues only) | Yes |
socket wrapper on/off | Yes | Yes |
socket package shallow | No | Yes (1 unit/pkg) |
socket package score (deep) | No | Yes (1 unit/pkg) |
socket scan create | No | Yes (1 unit) |
socket scan report | No | Yes (2 units) |
socket ci | No | Yes (1 unit + report) |
socket fix | No | Yes (101 units) |
socket optimize | No | Yes |
Package Assessment
Evaluate packages before adding or upgrading them.
Shallow Score (package only)
Quick assessment of a single package excluding its dependencies:
socket package shallow npm express
socket package shallow npm express@4.18.2
# Multiple packages, mixed ecosystems
socket package shallow pkg:npm/express pkg:pypi/requests
# Output formats
socket package shallow npm express --json
socket package shallow npm express --markdownReturns scores for: Supply Chain Risk, Maintenance, Quality, Vulnerabilities, License. Also lists detected alerts with severity levels.
Deep Score (package + all transitives)
Full assessment including all transitive dependencies:
socket package score npm eslint
socket package score npm eslint --markdown
# Specify exact version via purl
socket package score 'pkg:npm/[email protected]'The deep score reflects the minimum score across all transitive dependencies. A package with a high shallow score can have a low deep score if one of its dependencies is risky.
When to Use Each
| Scenario | Use | Why |
|---|---|---|
| Quick check before installing | shallow | Fast, evaluates just the target |
| Evaluating a major upgrade | score (deep) | Catches transitive supply chain risks |
| CI policy gate | scan (not package) | Evaluates your whole project |
| Comparing two packages | shallow | Quick side-by-side comparison |
Project Scanning
Scan your entire project for security issues.
Create a Scan
# Basic scan (auto-detects manifest files)
socket scan create
# Scan with policy report (recommended)
socket scan create --report
# Associate with repo/branch (for dashboard)
socket scan create --repo=my-project --branch=main --default-branch --report
# JSON output for automation
socket scan create --report --json
# Markdown output for sharing
socket scan create --report --markdownA scan uploads manifest files (package.json, requirements.txt, etc.) to Socket for analysis. No source code is sent.
API requirements: 1 unit + full-scans:create permission. Report adds 2 units + full-scans:list + security-policy:read.
CI Gate: socket ci
Shorthand for socket scan create --report. Creates a scan and exits with code 0 if the project passes your org's security policy, non-zero otherwise:
socket ciUse in CI pipelines to block merges that introduce security policy violations.
Scan Reports
# View scan report with alert folding
socket scan report <SCAN_ID> --fold=version --json
# Include license policy
socket scan report <SCAN_ID> --license --markdown
# Quick health check (just true/false)
socket scan report <SCAN_ID> --shortFold levels: none (every occurrence) → file → version (recommended) → pkg.
Scan Diffs
Compare two scans to see exactly what changed between upgrades:
socket scan diff <SCAN_ID_BEFORE> <SCAN_ID_AFTER>
# JSON for automation
socket scan diff <ID1> <ID2> --json > scan-delta.json
# Markdown for PR comments
socket scan diff <ID1> <ID2> --markdownShows packages added, removed, and changed — plus any new or resolved alerts.
API requirements: 1 unit + full-scans:list permission.
Automated CVE Fixing: socket fix
Automatically upgrade vulnerable dependencies to secure versions with intelligent upgrade planning.
Basic Usage
# Fix all fixable vulnerabilities
socket fix
# Fix specific CVEs
socket fix --id GHSA-hhq3-ff78-jv3g
socket fix --id CVE-2021-23337
# Multiple IDs
socket fix --id GHSA-xxxx-xxxx-xxxx,GHSA-yyyy-yyyy-yyyy
socket fix --id GHSA-xxxx --id GHSA-yyyy
# Fix in specific project directory
socket fix ./path/to/projectCooldown-Aligned Fixing
Align with your cooldown policy using --minimum-release-age:
# Only fix with packages vetted for at least 7 days (matches recommended cooldown)
socket fix --minimum-release-age 7d
# Conservative: 14 days
socket fix --minimum-release-age 14d
# Aggressive: 3 days
socket fix --minimum-release-age 3dTime formats: 1h (hours), 3d (days), 2w (weeks).
Conservative Options
# Don't suggest major version upgrades (less risk of breakage)
socket fix --no-major-updates
# Preview changes without applying them
socket fix --no-apply-fixes
# Output suggested fixes to file
socket fix --no-apply-fixes --output-file suggested-fixes.json
# Show which direct deps introduce transitive CVEs
socket fix --show-affected-direct-dependencies --output-file fixes.json
# Pin to exact versions instead of preserving ranges
socket fix --range-style pinCI/PR Mode (Autopilot)
Run in GitHub Actions to automatically create fix PRs:
# Create PRs for fixable CVEs (auto-merge if checks pass)
socket fix --autopilot
# Limit number of PRs per run
socket fix --autopilot --pr-limit 5Required environment variables for CI:
SOCKET_CLI_GITHUB_TOKEN(orGITHUB_TOKEN) — for PR creationSOCKET_CLI_GIT_USER_NAME— git commit author nameSOCKET_CLI_GIT_USER_EMAIL— git commit author emailSOCKET_CLI_API_TOKEN— Socket API token
API requirements: 101 units + full-scans:create + packages:list permissions.
Output Formats
socket fix --json
socket fix --markdown > security-fixes.mdDependency Optimization: socket optimize
Apply @socketregistry overrides to patch known issues without changing direct dependency versions:
# Apply overrides
socket optimize
# Pin overrides to exact versions
socket optimize --pin
# Production dependencies only
socket optimize --prod
# For a specific project
socket optimize ./path/to/projectThis adds overrides (npm/pnpm) or resolutions (yarn) to your package.json that redirect vulnerable transitive dependencies to Socket's secure patches.
Safe Install Wrappers
socket npm and socket npx
Run npm/npx through Socket to check packages before installation:
# Install with Socket protection
socket npm install express
socket npm install -g typescript
# Run commands safely
socket npx create-react-app my-appThese wrappers intercept the actual npm/npx resolution, check all resolved packages against Socket's database, and prompt before installing flagged packages.
Beta limitations: Uses default issue set only (not configurable without auth). Windows limited to WSL.
System-Wide Wrapper: socket wrapper
Enable automatic interception of all npm/npx commands on your system:
# Enable (creates shell aliases)
socket wrapper on
# Disable
socket wrapper offAfter enabling, any npm install ... command automatically runs through Socket. Requires restarting your shell or sourcing your RC file (e.g., source ~/.zshrc).
Manual Shell Aliases
# Add to ~/.zshrc or ~/.bashrc
alias npm="socket-npm"
alias npx="socket-npx"
# zsh autocompletions
compdef _npm socket-npm
# bash autocompletions
$(complete -p npm | sed 's/npm$/socket-npm/')Combining with npq
npq (pre-install auditor) can use socket-npm as its package manager:
NPQ_PKG_MGR=socket-npm npq install expressNote: socket npm performs full transitive analysis and integrates into npm's install flow, so it's more thorough than npq's checks. Running both may be redundant.
Project Configuration: socket.json
Store per-project defaults to avoid repeating flags:
# Interactive setup
socket scan setupCreates socket.json in the project root:
{
"repo": "my-project",
"branch": "main",
"defaultBranch": true
}After setup, socket scan create automatically uses these values. Flags still override config.
Commit socket.json to share defaults with your team, or add to .gitignore for personal use.
Alert Categories Quick Reference
Socket detects issues across five categories:
Supply Chain Risk (most critical for upgrades)
- malware — Known malicious package
- didYouMean — Possible typosquat (similar name to popular package)
- gptMalware — AI-detected malware
- troll — Protestware or potentially unwanted behavior
- obfuscatedFile — Obfuscated code detected
- installScripts — Pre/post-install scripts present
- manifestConfusion — Mismatch between package.json and tarball
Vulnerability
- criticalCVE, cve, mediumCVE, mildCVE — Known CVEs by severity
Quality
- deprecated — Package is deprecated
- unmaintained — No recent maintenance activity
- unpopularPackage — Very low download counts
Maintenance
- Part of quality category; signals inactive packages
License
- noLicenseFound — No license file detected
- copyleftLicense — Copyleft license may restrict usage
- nonpermissiveLicense — Non-permissive terms
Proactive Upgrade Workflow with Socket CLI
Integrate Socket into every stage of dependency management:
1. PRE-UPGRADE: socket scan create --report → baseline scan
2. EVALUATE: socket package score npm <pkg>@<ver> → assess target safety
3. SAFE INSTALL: socket npm install <pkg> → block malicious packages
4. POST-UPGRADE: socket scan create --report → verify no regressions
5. DIFF: socket scan diff <before> <after> → see exactly what changed
6. FIX: socket fix --minimum-release-age 7d → auto-fix any new CVEs
7. OPTIMIZE: socket optimize → apply security overridesQuick Reference: Command Cheat Sheet
| Command | Purpose | Auth Required |
|---|---|---|
socket npm install <pkg> | Install with malware check | No (beta) |
socket npx <cmd> | Run with malware check | No (beta) |
socket wrapper on | Auto-protect all npm/npx | No |
socket package shallow npm <pkg> | Quick package score | Yes |
socket package score npm <pkg> | Deep score (with transitives) | Yes |
socket scan create --report | Full project scan | Yes |
socket scan diff <id1> <id2> | Compare two scans | Yes |
socket ci | CI gate (scan + policy check) | Yes |
socket fix | Auto-fix CVEs | Yes |
socket fix --minimum-release-age 7d | Fix with cooldown alignment | Yes |
socket fix --no-major-updates | Fix without major bumps | Yes |
socket fix --no-apply-fixes | Preview fixes without applying | Yes |
socket fix --autopilot | CI auto-fix with PR creation | Yes |
socket optimize | Apply security overrides | Yes |
socket login | Store API token locally | — |
socket scan setup | Create socket.json defaults | — |
Supported Ecosystems
Socket CLI supports:
- JavaScript/TypeScript: npm, pnpm (v6+), Yarn (classic + berry), Bun
- Python: pip, uv (requirements.txt, uv.lock)
- Java: Maven, Gradle (with gradle.lockfile)
- Ruby: RubyGems
- Go: go.sum/go.mod
- Rust: Cargo
- C#: NuGet (packages.lock.json coming soon)
socket npm / socket npx wrappers only work with npm. For other package managers, use socket scan create for analysis and socket fix for remediation.
Staged Upgrade Strategies
Detailed guide for incremental dependency upgrades with codemod automation.
Upgrade Planning
Phase 1: Assessment
# Identify current versions
npm list --depth=0
bun pm ls # Bun
# Check for available updates
npm outdated
bun outdated
# Check for breaking changes
# Read CHANGELOG.md, MIGRATION.md, GitHub releasesPhase 2: Ordering
Upgrade in dependency order — foundations first:
1. TypeScript / build tools
2. Core framework (React, Next.js, etc.)
3. Routing
4. State management
5. UI libraries
6. Testing libraries
7. Dev dependenciesPhase 3: Execution
Upgrade one major version at a time with testing between each:
# Step 1: Create feature branch
git checkout -b upgrade/react-19
# Step 2: Upgrade the package
bun add react@19 react-dom@19
# Step 3: Test immediately
bun test
bunx tsc --noEmit
bun run build
# Step 4: Fix issues, commit
git add -A && git commit -m "chore: upgrade react to 19"
# Step 5: Continue to next packageCodemod Automation
react-codeshift
# Install codemod runner
bunx react-codeshift <transform> <path>
# Example: rename unsafe lifecycles
bunx react-codeshift \
--parser tsx \
--transform react-codeshift/transforms/rename-unsafe-lifecycles.js \
src/
# Example: update context API
bunx react-codeshift \
--transform react-codeshift/transforms/old-context-apis.js \
src/jscodeshift (generic)
# Run any codemod
bunx jscodeshift -t <codemod-url> src/
# Example: upgrade React Router imports
bunx jscodeshift -t https://raw.githubusercontent.com/ReactTraining/react-router/main/packages/react-router/codemods/5.x-6.x.ts src/Next.js Codemods
# Built-in Next.js upgrade codemods
bunx @next/codemod@latest upgrade
# Specific transforms
bunx @next/codemod new-link src/
bunx @next/codemod next-image-to-legacy-image src/Custom Migration Scripts
AST-Based Transformation
// migration-script.mjs
import { readFileSync, writeFileSync } from 'fs';
import { globSync } from 'glob';
import jscodeshift from 'jscodeshift';
const files = globSync('src/**/*.{ts,tsx}');
for (const file of files) {
const source = readFileSync(file, 'utf8');
const j = jscodeshift(source);
// Example: replace old import with new
j.find(jscodeshift.ImportDeclaration, {
source: { value: 'old-package' }
}).forEach(path => {
path.value.source.value = 'new-package';
});
const output = j.toSource();
if (output !== source) {
writeFileSync(file, output);
console.log(`Updated: ${file}`);
}
}Regex-Based Quick Fixes
// quick-fix.mjs
import { readFileSync, writeFileSync } from 'fs';
import { globSync } from 'glob';
const replacements = [
[/from 'old-api'/g, "from 'new-api'"],
[/oldFunction\(/g, 'newFunction('],
[/import \{ OldComponent \}/g, 'import { NewComponent }'],
];
const files = globSync('src/**/*.{ts,tsx}');
let totalChanges = 0;
for (const file of files) {
let content = readFileSync(file, 'utf8');
let changed = false;
for (const [pattern, replacement] of replacements) {
const matchCount = (content.match(pattern) || []).length;
if (matchCount > 0) {
content = content.replace(pattern, replacement);
changed = true;
totalChanges += matchCount;
}
}
if (changed) {
writeFileSync(file, content);
console.log(`Updated: ${file}`);
}
}
console.log(`Total changes: ${totalChanges}`);Peer Dependency Handling
# npm 7+: strict peer dependencies by default
npm install --legacy-peer-deps # Ignore peer dep conflicts
npm install --force # Override conflicts
# Better approach: resolve the actual conflict
npm ls <package-name> # Find why peer dep is wrong
# Bun: handles peer deps automatically
bun install # Resolves peer deps without flagsWorkspace Upgrades
# Update all workspace packages
npm install --workspaces
# Update specific workspace
bun add package@latest --workspace=packages/app
# Update shared dev dependency across workspaces
bun add -D typescript@latest --workspace=*Rollback Strategy
#!/bin/bash
# rollback.sh
# Save current state
git stash
git checkout -b upgrade-branch
# Attempt upgrade
bun add package@latest
# Run tests
if bun test && bun run build; then
echo "Upgrade successful"
git add package.json bun.lock
git commit -m "chore: upgrade package"
else
echo "Upgrade failed, rolling back"
git checkout main
git branch -D upgrade-branch
bun install # Restore from lockfile
fiSupply Chain Security Reference
Comprehensive guide to preventing supply chain attacks during dependency installation and upgrades.
Threat Landscape
Recent supply chain incidents demonstrate why hardening dependency workflows is critical:
| Incident | Year | Attack Vector | Impact |
|---|---|---|---|
| event-stream | 2018 | Malicious maintainer | Stole Bitcoin wallets |
| eslint-scope | 2018 | Stolen credentials | Published malicious versions |
| ua-parser-js | 2021 | Account takeover | Cryptomining + credential theft |
| node-ipc | 2022 | Protestware | Deleted files on Russian IPs |
| colors/faker | 2022 | Maintainer sabotage | Infinite loop DOS |
| Shai-Hulud | 2024 | Postinstall worm | Propagated via lifecycle scripts |
| Nx | 2025 | Compromised postinstall | Weaponized AI coding agents |
Security Principles
1. Trust Nothing by Default
Every package — direct or transitive — is a potential attack vector. Configure package managers to block unsafe behavior and only allow what is explicitly reviewed.
2. Delay Before Installing
Newly published packages may contain malicious code discovered within hours or days. A cooldown period lets the community catch threats before they reach production.
3. Freeze and Validate
Lockfiles are the contract between development and production. Protect them from injection and validate their integrity in CI.
4. Minimize Attack Surface
Fewer dependencies = fewer potential vulnerabilities. Each transitive dependency inherits all risks of its own dependency tree.
5. Audit Before Trusting
Don't rely solely on npmjs.org — the displayed source code can differ from the actual tarball. Use security tools to audit packages before installation.
Disabling Post-Install Scripts
Post-install scripts are the most common supply chain attack vector. They execute arbitrary code during npm install with full system access.
npm
# Global config (recommended — applies to all projects)
npm config set ignore-scripts true
npm config set allow-git none
# Per-command
npm install --ignore-scripts --allow-git=none <package>
# .npmrc file
ignore-scripts=true
allow-git=noneEven with --ignore-scripts, git-based dependencies can ship .npmrc files that re-enable lifecycle scripts. Use --allow-git=none (npm CLI 11.10.0+) alongside --ignore-scripts to fully close this vector.
Bun
Bun disables postinstall scripts by default and maintains an internal allow-list. Allow specific packages via trustedDependencies in package.json:
{
"trustedDependencies": [
"esbuild",
"sharp"
]
}pnpm (10.0+)
pnpm disables postinstall scripts by default since v10.0. Control which packages can run build scripts:
# pnpm-workspace.yaml
# Preferred (pnpm 10.26+): single map of package → true/false
allowBuilds:
esbuild: true
fsevents: true
nx@21.6.4 || 21.6.5: true
core-js: false
# Legacy (still supported):
# onlyBuiltDependencies:
# - esbuild
# - fsevents
# Make unreviewed scripts a hard error (pnpm 10.3+)
strictDepBuilds: trueAllowlist with @lavamoat/allow-scripts
For projects that need some post-install scripts, use @lavamoat/allow-scripts to create an auditable allowlist:
npm install --save-dev @lavamoat/allow-scripts
npx allow-scripts autoThis scans the dependency tree and creates a package.json entry listing which packages are permitted to run scripts, blocking all others.
Lockfile Injection Prevention
The Threat
Malicious actors can submit PRs that modify lockfiles to point to compromised packages or change the resolved URL + integrity hash to their own payload.
Validation with lockfile-lint
npm install --save-dev lockfile-lint
# Validate npm lockfile
npx lockfile-lint \
--path package-lock.json \
--type npm \
--allowed-hosts npm yarn \
--validate-https
# Validate yarn lockfile
npx lockfile-lint \
--path yarn.lock \
--type yarn \
--allowed-hosts npm yarn \
--validate-httpsCI Integration
{
"scripts": {
"lint:lockfile": "lockfile-lint --path package-lock.json --type npm --allowed-hosts npm --validate-https",
"preinstall": "npm run lint:lockfile"
}
}pnpm Specific Hardening
pnpm is inherently more resistant to lockfile injection:
- Doesn't maintain tarball sources that can be maliciously modified
- Won't install packages in the lockfile that aren't in
package.json
Additional protection (pnpm 10.26+):
# pnpm-workspace.yaml
# Block transitive deps from using exotic sources (git repos, tarball URLs)
blockExoticSubdeps: trueTrust Policy (pnpm 10.21+)
Detect when a package's publish-time trust level has decreased — an early signal of account compromise:
# pnpm-workspace.yaml
trustPolicy: no-downgrade
# Allow specific packages to bypass
trustPolicyExclude:
- 'chokidar@4.0.3'
# Ignore check for packages published >30 days ago (pnpm 10.27+)
trustPolicyIgnoreAfter: 43200 # minutes (30 days)Trust levels (strongest → weakest): 1. Trusted Publisher — published via OIDC/GitHub Actions 2. Provenance — published with npm provenance attestation 3. Signatures — registry signature present 4. No evidence — no trust signals
Bun Lockfile Notes
Bun uses bun.lock (text-based, default since v1.2) or bun.lockb (binary). lockfile-lint does not currently support Bun lockfile formats. Monitor the lockfile-lint repo for future support.
Pre-Install Security Auditing
npq — Pre-Install Package Auditor
npq audits packages before installation using multiple security "marshalls":
# Install globally
npm install -g npq
# Use instead of npm
npq install express
# Dry run (audit without installing)
npq install express --dry-run
# Shell alias for seamless integration
alias npm='npq-hero'
echo "alias npm='npq-hero'" >> ~/.zshrc
# Use with other package managers
NPQ_PKG_MGR=pnpm npq install fastify
NPQ_PKG_MGR=bun npq install fastify
# Permanent aliases for other PMs
alias pnpm="NPQ_PKG_MGR=pnpm npq-hero"What npq validates:
- Vulnerability scanning (Snyk CVE database)
- Package age analysis (flags packages < 22 days old)
- Typosquatting detection
- Registry signature verification
- Provenance attestation checks
- Pre/post-install script warnings
- Package health (README, LICENSE, repo URL, downloads)
- Binary introduction warnings
- Deprecation status
- Maintainer domain validation (expired domains)
Socket Firewall (sfw) — Real-Time Package Firewall
sfw intercepts package manager commands and blocks malicious packages:
# Install globally
npm install -g sfw
# Prefix any package manager command
sfw npm install express
sfw pnpm add express
sfw yarn add express
sfw pip install requests
sfw cargo fetchWhat sfw checks:
- Malicious code detection
- Install script risks
- Typosquatting detection
- Dependency confusion attacks
- Known vulnerabilities
- Protestware and env variable access
- Network and filesystem access patterns
Comparison
| Feature | npq | sfw | Socket CLI (socket npm) |
|---|---|---|---|
| Analysis | Pre-install marshalls | Real-time deep analysis | Full transitive scan via npm integration |
| Data sources | Snyk CVE, npm metadata | Socket proprietary intelligence | Socket proprietary intelligence |
| Interactivity | Prompts before install | Blocks and prompts flagged packages | Prompts before installing flagged packages |
| PM support | npm, pnpm, Bun (env vars) | npm, yarn, pnpm, pip, uv, cargo | npm, npx (wrapper mode) |
| Open source | Yes | Client only | Client only (open source on GitHub) |
| Free tier | Yes | No | Yes (beta, default issues only) |
| CI integration | No | No | Yes (socket ci, socket fix --autopilot) |
| Package scoring | No | No | Yes (socket package score) |
| CVE auto-fixing | No | No | Yes (socket fix) |
| Requires auth | No | Yes | No for wrapper, Yes for scans/fix |
See references/socket-cli-guide.md for full Socket CLI documentation.
Publisher Security
Enable 2FA for npm Accounts
# Enable for auth + publishing
npm profile enable-2fa auth-and-writes
# Enable for auth only
npm profile enable-2fa auth-onlyPublish with Provenance Attestations
Provides cryptographic proof of where and how packages were built:
# GitHub Actions
permissions:
id-token: write
steps:
- run: npm publish --provenanceRequires npm CLI 9.5.0+ and GitHub Actions or GitLab CI/CD.
Publish with OIDC (Trusted Publishing)
Eliminates long-lived npm tokens by using short-lived OIDC tokens from CI:
# GitHub Actions
permissions:
id-token: write
steps:
- run: npm publishConfigure trusted publisher on npmjs.com first. Automatically generates provenance attestations (OpenSSF compliant).
Avoiding Blind Upgrades
Anti-Patterns
# DANGEROUS — upgrades everything without review
npm update
npx npm-check-updates -uIncidents like colors/faker and node-ipc demonstrate why blind upgrades are dangerous.
Safe Alternatives
# Interactive — review each upgrade
npx npm-check-updates --interactive
# Use automated tools with security policies
# - Snyk: 21-day cooldown built-in
# - Dependabot: configurable cooldown
# - Renovate: minimumReleaseAge configPackage Health Assessment
Snyk Security Database
Before adopting any package, check security.snyk.io:
https://security.snyk.io/package/npm/<package-name>Provides: security vulnerabilities, popularity trends, maintenance activity, community signals.
Don't Trust npmjs.org Alone
The npmjs.org website:
- Omits git and HTTPS-based dependencies from displayed
package.json - Source code display can drift from the actual installed tarball
Always inspect the actual tarball:
npm pack <package-name> --dry-run
npm pack <package-name>
tar -tzf <package-name>-<version>.tgzDependency Tree Reduction
Replace common dependencies with native JavaScript:
// Instead of lodash
const unique = [...new Set(array)];
// Instead of axios
const response = await fetch(url);
// Instead of utility libraries
const isEmpty = obj => Object.keys(obj).length === 0;
const clone = structuredClone(original);Each dependency adds transitive attack surface. Evaluate necessity, maintenance burden, and bundle size before adding any dependency.
Testing Strategy for Dependency Upgrades
Comprehensive testing approaches to validate dependency upgrades at every level.
Testing Pyramid
E2E Tests
/ \
Integration Tests
/ \
Unit Tests
/ \
Static Analysis (tsc, lint)Run from bottom to top after each upgrade.
Level 1: Static Analysis
# TypeScript type-check (fastest feedback)
bunx tsc --noEmit
# Lint
bun run lint
# Check bundle (size impact)
bun run buildLevel 2: Unit Tests
# Run all unit tests
bun test
# Watch mode during upgrade
bun test --watch
# Specific test file
bun test src/components/Button.test.tsxAfter upgrading, check for:
- Type errors from API changes
- Assertion failures from behavior changes
- Missing exports from package restructuring
Level 3: Integration Tests
describe('Dependency Compatibility', () => {
it('should have matching React versions', () => {
const reactVersion = require('react/package.json').version;
const reactDomVersion = require('react-dom/package.json').version;
expect(reactVersion).toBe(reactDomVersion);
});
it('should render without crashing', () => {
const { container } = render(<App />);
expect(container).toBeTruthy();
});
it('should handle navigation', () => {
render(<App />);
fireEvent.click(screen.getByText('Navigate'));
expect(screen.getByText('New Page')).toBeInTheDocument();
});
});Level 4: Visual Regression Tests
describe('Visual Regression', () => {
it('should match snapshot', () => {
const { container } = render(<Component />);
expect(container.firstChild).toMatchSnapshot();
});
it('should match visual baseline', () => {
render(<Dashboard />);
// Compare screenshot against baseline
cy.compareSnapshot('dashboard');
});
});After UI library upgrades, always check:
- Snapshot diffs
- Color/font changes
- Layout shifts
- Responsive breakpoints
Level 5: E2E Tests
// cypress/e2e/app.cy.js
describe('E2E Smoke Tests', () => {
it('should load the app', () => {
cy.visit('/');
cy.get('[data-testid="app"]').should('exist');
});
it('should complete auth flow', () => {
cy.visit('/login');
cy.get('input[name="email"]').type('user@example.com');
cy.get('button[type="submit"]').click();
cy.url().should('include', '/dashboard');
});
it('should handle API errors gracefully', () => {
cy.intercept('GET', '/api/data', { statusCode: 500 });
cy.visit('/dashboard');
cy.get('[data-testid="error-message"]').should('be.visible');
});
});Bundle Analysis
# Compare bundle sizes before and after upgrade
bun run build
# Analyze bundle composition
bunx bundle-analyzer dist/index.js
# Check for unexpected bundle size increases
# Before upgrade: note the bundle size
# After upgrade: compare and investigate increases > 5%Performance Testing
# Run Lighthouse CI
bunx @lhci/cli autorun
# Check Core Web Vitals
# - LCP: Largest Contentful Paint
# - FID: First Input Delay
# - CLS: Cumulative Layout ShiftUpgrade Test Matrix
| Test Type | When to Run | Failure Indicates |
|---|---|---|
| Type-check | After every package | Breaking API changes |
| Unit tests | After every package | Behavior changes |
| Integration | After framework upgrades | Compatibility issues |
| Visual regression | After UI library upgrades | Visual breaking changes |
| E2E | After major upgrades | User flow breakage |
| Bundle analysis | After any upgrade | Size regression |
| Performance | After major upgrades | Performance regression |
CI Integration
# .github/workflows/upgrade-validation.yml
name: Upgrade Validation
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bunx tsc --noEmit
- run: bun run lint
- run: bun test
- run: bun run build
- run: bun run test:e2e#!/usr/bin/env bash
set -euo pipefail
# Generate hardened SAP dependency security configuration candidates from templates.
# Defaults to dry-run output on stdout. Pass --write to write a selected
# candidate into an output directory after manual review.
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
TEMPLATE_DIR="${ROOT_DIR}/templates"
usage() {
cat <<USAGE
Usage: $(basename "$0") [--write] <target> [output-dir]
Package-manager targets:
npm -> .npmrc
bun -> bunfig.toml
pnpm -> pnpm-workspace.yaml
yarn -> .yarnrc.yml
deno -> deno.json (template-free fallback)
SAP targets:
mcp -> sap-mcp-config.candidate.md
maven -> maven-security-fragment.md
gradle -> gradle-security-fragment.md
python -> python-security.md
container -> container-trivy.yml
btp -> btp-cf-mbt-review.md
abap -> abap-gcts-review.md
Default mode prints the candidate to stdout and does not write files.
Use --write only after reviewing the candidate output.
USAGE
}
write_mode=0
if [[ ${1:-} == "--write" ]]; then
write_mode=1
shift
fi
if [[ ${1:-} == "" || ${1:-} == "-h" || ${1:-} == "--help" ]]; then
usage
exit 0
fi
target_name="${1:-}"
out_dir="${2:-.}"
emit_template() {
local template_file="$1"
local output_file="$2"
local template_path="${TEMPLATE_DIR}/${template_file}"
if [[ ! -f "$template_path" ]]; then
echo "Error: template not found: $template_path" >&2
exit 1
fi
if [[ "$write_mode" -eq 1 ]]; then
mkdir -p "$out_dir"
cp "$template_path" "$out_dir/$output_file"
echo "Generated: $out_dir/$output_file"
echo "Tip: review generated values before committing."
else
echo "# Candidate output: $output_file"
echo "# Source template: $template_file"
echo ""
cat "$template_path"
fi
}
emit_content() {
local output_file="$1"
local content="$2"
if [[ "$write_mode" -eq 1 ]]; then
mkdir -p "$out_dir"
printf "%s\n" "$content" > "$out_dir/$output_file"
echo "Generated: $out_dir/$output_file"
echo "Tip: review generated values before committing."
else
echo "# Candidate output: $output_file"
echo ""
printf "%s\n" "$content"
fi
}
case "$target_name" in
npm|bun|pnpm|yarn)
case "$target_name" in
npm)
template_file="npmrc-security.tmpl"
output_file=".npmrc"
;;
bun)
template_file="bunfig-security.tmpl"
output_file="bunfig.toml"
;;
pnpm)
template_file="pnpm-workspace-security.tmpl"
output_file="pnpm-workspace.yaml"
;;
yarn)
template_file="yarnrc-security.tmpl"
output_file=".yarnrc.yml"
;;
esac
emit_template "$template_file" "$output_file"
;;
deno)
emit_content "deno.json" '{
"nodeModulesDir": "auto",
"vendor": true
}'
;;
mcp)
emit_template "sap-mcp-config.tmpl" "sap-mcp-config.candidate.md"
;;
maven)
emit_template "maven-security.tmpl" "maven-security-fragment.md"
;;
gradle)
emit_template "gradle-security.tmpl" "gradle-security-fragment.md"
;;
python)
emit_template "python-security.tmpl" "python-security.md"
;;
container)
emit_template "container-trivy.tmpl" "container-trivy.yml"
;;
btp)
emit_template "btp-cf-mbt-review.tmpl" "btp-cf-mbt-review.md"
;;
abap)
emit_template "abap-gcts-review.tmpl" "abap-gcts-review.md"
;;
*)
echo "Unsupported target: $target_name" >&2
usage >&2
exit 1
;;
esac
exit 0
# ABAP / gCTS / Transport Dependency Review
Use this checklist when dependency work affects ABAP Cloud, RAP, CDS, software components, abapGit packages, or gCTS imports.
- [ ] Identify dependent software components and required import order
- [ ] Check transport request object list for unrelated generated artifacts
- [ ] Run ATC/security checks before release/import
- [ ] Verify CDS/RAP behavior dependencies in the target system
- [ ] Confirm communication arrangement or destination changes are intentional
- [ ] For gCTS, compare repository commit, branch, and package mapping
- [ ] Record rollback transport, previous tag, or re-import path
- [ ] Coordinate import window for cross-system dependencies
# BTP / Cloud Foundry / MBT Dependency Review
Use this checklist before changing BTP deployment tooling, `mta.yaml`, `xs-security.json`, or pipeline CLI versions.
- [ ] Pin `mbt`, `cf`, `btp`, and plugin versions in CI images or setup steps
- [ ] Run `mbt build` from a clean checkout
- [ ] Inspect the generated MTAR contents before deploy
- [ ] Confirm `cf api`, org, and space target before deployment
- [ ] Review service instance, binding, destination, and role collection changes
- [ ] Confirm XSUAA scopes/authorities did not broaden unexpectedly
- [ ] Keep service keys and deployment credentials out of the repo
- [ ] Document rollback command or previous MTAR artifact
Suggested commands:
```bash
cf target
mbt build
find mta_archives -maxdepth 1 -type f -name '*.mtar' -print
```
# bunfig.toml — Security-Hardened Configuration for Bun
# Copy to project root as bunfig.toml
# Customize values marked with [CONFIGURE]
[install]
# === COOLDOWN PERIOD ===
# Only install package versions published at least 7 days ago (value in seconds)
# 3 days = 259200, 7 days = 604800, 14 days = 1209600, 21 days = 1814400
minimumReleaseAge = 604800
# Packages that bypass the cooldown (typically build tooling that needs fast patches)
# [CONFIGURE] Add packages that need same-day updates
minimumReleaseAgeExcludes = [
"@types/bun",
"typescript",
"esbuild"
]
# === REGISTRY ===
registry = "https://registry.npmjs.org/"
# === PEER DEPENDENCIES ===
# Bun handles peer deps automatically; no configuration needed
# Container / Trivy SAP Security Template
# Pin base images by digest after review:
# FROM node:22-bookworm-slim@sha256:<digest>
name: container-security
on:
pull_request:
push:
branches: ["main"]
jobs:
trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t sap-app:${{ github.sha }} .
- name: Scan image
uses: aquasecurity/trivy-action@v0.36.0
with:
image-ref: sap-app:${{ github.sha }}
format: table
exit-code: "1"
vuln-type: os,library
severity: CRITICAL,HIGH
# Review checklist:
# - [ ] Base image uses a digest pin
# - [ ] Runtime user is non-root
# - [ ] No service keys or `.env` files copied into the image
# - [ ] Kyma/Kubernetes manifests drop unnecessary capabilities
# .github/dependabot.yml — Automated Updates with Cooldown
# Copy to .github/dependabot.yml
# Customize values marked with [CONFIGURE]
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
# [CONFIGURE] How often to check for updates: daily, weekly, biweekly, monthly
interval: "weekly"
day: "monday"
# Wait 7 days after a new version is published before creating a PR
cooldown:
default-days: 7
open-pull-requests-limit: 5
# [CONFIGURE] Add reviewers
# reviewers:
# - "team-leads"
commit-message:
prefix: "chore"
include: "scope"
labels:
- "dependencies"
# [CONFIGURE] Uncomment to automerge minor/patch updates
# ignore:
# - dependency-name: "*"
# update-types: ["version-update:semver-major"]
# [CONFIGURE] Uncomment for GitHub Actions updates
# - package-ecosystem: "github-actions"
# directory: "/"
# schedule:
# interval: "weekly"
# cooldown:
# default-days: 7
{
"name": "Node.js Hardened Dev Container",
"image": "mcr.microsoft.com/devcontainers/javascript-node:20",
"features": {
"ghcr.io/devcontainers/features/1password:1": {}
},
"runArgs": [
"--security-opt=no-new-privileges:true",
"--cap-drop=ALL",
"--cap-add=CHOWN",
"--cap-add=SETUID",
"--cap-add=SETGID"
],
"containerEnv": {
"NODE_OPTIONS": "--disable-proto=delete"
},
"postCreateCommand": "npm ci --ignore-scripts",
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
},
"remoteUser": "node"
}
# Gradle SAP Security Fragment
# settings.gradle
dependencyVerification {
verificationMode = VerificationMode.STRICT
}
# Generate/update verification metadata after manual review:
# ./gradlew --write-verification-metadata sha256 help
# Enable dependency locking:
# gradle.properties
dependencyLocking=true
# build.gradle
dependencyLocking {
lockAllConfigurations()
}
# Recommended CI checks:
# ./gradlew dependencies --write-locks
# ./gradlew dependencyInsight --dependency <name>
# osv-scanner --lockfile=gradle.lockfile
Review checklist:
- [ ] No dynamic versions (`+`, `latest.release`, or open ranges)
- [ ] Wrapper version is committed and reviewed
- [ ] Verification metadata is committed
- [ ] Lockfile diff contains only intended modules
# Maven SAP Security Fragment
# .mvn/maven.config
# Review before copying into a project.
--batch-mode
--no-transfer-progress
--strict-checksums
# Recommended CI checks:
# ./mvnw -C -B dependency:tree
# ./mvnw -C -B org.owasp:dependency-check-maven:check
# osv-scanner --lockfile=pom.xml
# pom.xml plugin fragment:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>enforce</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>[3.9.0,)</version>
</requireMavenVersion>
<requireJavaVersion>
<version>[17,)</version>
</requireJavaVersion>
<banDynamicVersions />
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
# .npmrc — Security-Hardened Configuration
# Copy to project root as .npmrc
# Customize values marked with [CONFIGURE]
# === POST-INSTALL SCRIPTS ===
# Block all lifecycle scripts (postinstall, preinstall, etc.)
ignore-scripts=true
# Block git-based dependencies from re-enabling scripts (npm CLI 11.9.0+)
allow-git=none
# === COOLDOWN PERIOD ===
# Only install package versions published at least 7 days ago
# Adjust value (in days): 3 (aggressive), 7 (recommended), 14 (conservative)
min-release-age=7
# === REGISTRY ===
# Use official npm registry
registry=https://registry.npmjs.org/
# === SECURITY ===
# Require integrity checks on all packages
strict-ssl=true
# === OPTIONAL: SCRIPT ALLOWLIST ===
# To allow specific packages to run scripts, use @lavamoat/allow-scripts
# npx allow-scripts auto
# Then review and approve in package.json
# pnpm-workspace.yaml — Security-Hardened Configuration
# Copy to project root as pnpm-workspace.yaml
# Requires pnpm 10.0+ (most features) / 10.16+ (cooldown) / 10.21+ (trust policy) / 10.26+ (allowBuilds, blockExoticSubdeps)
# Customize values marked with [CONFIGURE]
# === COOLDOWN PERIOD ===
# Only install package versions published at least 7 days ago (value in minutes)
# 3 days = 4320, 7 days = 10080, 14 days = 20160, 21 days = 30240
minimumReleaseAge: 10080
# Packages that bypass the cooldown
# [CONFIGURE] Add packages that need same-day updates
minimumReleaseAgeExclude:
- "@types/react"
- "@types/node"
- typescript
- esbuild
# === POST-INSTALL SCRIPTS ===
# Preferred (pnpm 10.26+): map of package → true/false
# [CONFIGURE] Add packages that genuinely need build scripts
allowBuilds:
esbuild: true
fsevents: true
# sharp: true
# core-js: false
# Make unreviewed build scripts a hard error (pnpm 10.3+)
strictDepBuilds: true
# === TRUST POLICY (pnpm 10.21+) ===
# Fail if a package's trust level has decreased vs a previous version
trustPolicy: no-downgrade
# [CONFIGURE] Exclude specific packages from trust checks
# trustPolicyExclude:
# - "chokidar@4.0.3"
# Ignore trust checks for packages published >30 days ago (pnpm 10.27+)
trustPolicyIgnoreAfter: 43200 # minutes (30 days)
# === EXOTIC DEPENDENCY BLOCKING (pnpm 10.26+) ===
# Prevent transitive deps from using git repos or tarball URLs
blockExoticSubdeps: true
# === WORKSPACES (if using monorepo) ===
# [CONFIGURE] Uncomment and adjust for monorepo
# packages:
# - "apps/*"
# - "packages/*"
# Python SAP Security Template
# Preferred with uv:
# pyproject.toml + uv.lock
uv lock
uv sync --frozen
uv audit
# If your audit tooling requires requirements.txt output from uv:
uv export --format requirements-txt --output-file requirements.txt
pip-audit -r requirements.txt
# requirements.txt with hashes when using pip-tools:
pip-compile --generate-hashes --output-file requirements.txt pyproject.toml
pip install --require-hashes -r requirements.txt
pip-audit -r requirements.txt
Review checklist:
- [ ] `uv.lock` or hashed `requirements.txt` is committed
- [ ] Broad extras such as `[all]` are intentional
- [ ] Deprecated SAP packages are removed, for example `generative-ai-hub-sdk`
- [ ] Provider SDK additions are reviewed for transitive dependency volume
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:base"],
"minimumReleaseAge": "7 days",
"schedule": [
"before 3am on Monday"
],
"timezone": "America/New_York",
"packageRules": [
{
"description": "Automerge minor and patch updates after cooldown",
"matchUpdateTypes": ["minor", "patch"],
"automerge": true,
"minimumReleaseAge": "7 days"
},
{
"description": "Require manual review for major updates, longer cooldown",
"matchUpdateTypes": ["major"],
"automerge": false,
"minimumReleaseAge": "14 days",
"labels": ["major-update", "review-required"]
},
{
"description": "Skip cooldown for build tooling that needs fast patches",
"matchPackageNames": ["typescript", "esbuild"],
"minimumReleaseAge": null
}
],
"lockFileMaintenance": {
"enabled": true,
"schedule": ["before 3am on Monday"]
},
"vulnerabilityAlerts": {
"enabled": true
},
"dependencyDashboard": true,
"dependencyDashboardTitle": "Dependency Dashboard"
}
# SAP MCP Config Candidate
# Use this as a review artifact, not as a blind rewrite target.
# Exact pins must match references/sap-mcp-inventory.json.
{
"example-sap-mcp": {
"command": "npx",
"args": ["-y", "@scope/package@1.2.3"],
"env": {
"EXAMPLE_BASE_URL": "${EXAMPLE_BASE_URL}"
}
}
}
Review checklist:
- [ ] Package appears in `references/sap-mcp-inventory.json`
- [ ] Package uses an exact version, not `@latest` or a range
- [ ] Version satisfies the SAP cooldown or has a recorded exception
- [ ] Credential env vars are least-privilege and not committed elsewhere
- [ ] `npm run validate:mcp-security` passes
# Socket Fix CI Workflow
# Automatically fixes CVEs with Socket and creates PRs
# Runs twice daily. Complements Dependabot/Renovate.
# Requires: SOCKET_CLI_API_TOKEN secret in GitHub repo/org settings
#
# Docs: https://docs.socket.dev/docs/socket-fix
name: socket-fix
on:
schedule:
- cron: '0 0 * * *'
- cron: '0 12 * * *'
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
socket-fix:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
# -- uncomment and adjust for your package manager --
# - name: Setup pnpm
# uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda
# with:
# version: '^10.16.0'
# - name: Setup Node.js
# uses: actions/setup-node@v4
# with:
# node-version: "22"
# cache: 'pnpm'
- name: Install dependencies
run: npm ci
- name: Run Socket Fix
env:
SOCKET_CLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SOCKET_CLI_GIT_USER_EMAIL: socket-fix[bot]@users.noreply.github.com
SOCKET_CLI_GIT_USER_NAME: socket-fix[bot]
SOCKET_CLI_API_TOKEN: ${{ secrets.SOCKET_CLI_API_TOKEN }}
run: npx @socketsecurity/cli fix --autopilot --minimum-release-age 7d
# Socket CI Security Gate
# Blocks PRs that violate your organization's security policy
# Runs on every push and pull request
#
# Requires: SOCKET_SECURITY_API_KEY secret in GitHub repo/org settings
# Docs: https://docs.socket.dev/docs/socket-ci
name: socket-security
on:
push:
branches: ['**']
pull_request:
types: [opened, synchronize, reopened]
concurrency:
group: socket-scan-${{ github.ref }}-${{ github.sha }}
cancel-in-progress: true
jobs:
socket-ci:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Install Socket CLI
run: npm install -g socket
- name: Run Socket CI Gate
env:
SOCKET_SECURITY_API_KEY: ${{ secrets.SOCKET_SECURITY_API_KEY }}
run: socket ci
# .yarnrc.yml — Security-Hardened Configuration for Yarn 4.10+
# Copy to project root as .yarnrc.yml
# Customize values marked with [CONFIGURE]
# === COOLDOWN PERIOD ===
# Only consider npm package versions published at least 7 days ago
# Value is in minutes (10080 = 7 days, 43200 = 30 days)
npmMinimalAgeGate: 10080
# Packages that bypass the age gate (descriptors or glob patterns)
# [CONFIGURE] Add packages that need same-day updates
npmPreapprovedPackages:
- "@types/react"
- "@types/node"
- typescript
- esbuild
# === REGISTRY ===
npmRegistryServer: "https://registry.npmjs.org/"
# === SECURITY ===
# Require integrity checks
unsafeHttpWhitelist: []
# === DETERMINISTIC INSTALLS ===
# In CI, use: yarn install --immutable --immutable-cache