claudeers.

🔓 unclaimed — this page was auto-generated from GitHub. Are you the creator?

Claim this page →
// Claude Skills

safer-dependencies

safer-dependencies is a security layer for Claude Code that audits packages before they’re added to your project. It detects and fixes risky dependencies, in…

// install
git clone https://github.com/robert-auger/safer-dependencies

Safer Dependencies for Claude Code

Automatically checks dependencies that Claude adds through its Write, Edit, and Bash tools, and auto-corrects vulnerable versions in place. Runs provenance, version age, vulnerability, and hash-integrity checks across npm, PyPI, RubyGems, Maven, Go, Rust, and PHP (Composer). Coverage is scoped to writes that go through Claude's tools (Intercept Mode corrects a vulnerable pin after the file lands, within the same tool cycle — not before); see CAPABILITIES.md for exactly what is and isn't covered.

New here? GETTING-STARTED.md takes you from zero to a working install in about five minutes.

Security & privacy: see SECURITY.md (vulnerability disclosure), PRIVACY.md (data egress, no telemetry), and CAPABILITIES.md (what the tool defends against and what it doesn't).

License (source-available — NOT OSI "open source"): Free to use and modify for your own purposes, including for-profit/company internal use and building products you sell. A separate paid license is required only to monetize the software itself — selling it, shipping it inside a product or service that is sold, or offering its functionality to third parties for a fee (including hosted/SaaS/API). Redistribution and derivatives must keep the license and credit this project. See LICENSE (Section 4 for the commercial restriction); commercial-license requests via github.com/robert-auger.

Contents

What it does

When AI coding assistants like Claude add packages to your project, they often pick whatever version sounds right — without checking whether it has known security vulnerabilities, whether the package is still actively maintained, or whether the name is a typo away from a malicious lookalike. safer-dependencies fixes that by sitting between Claude and your manifest files and running security checks automatically, before any unsafe version lands in your code.

When Claude is about to add a package to your project, this skill intercepts and runs 5 checks:

  1. Provenance -- official registry, typosquat detection (npm/PyPI/RubyGems/Maven/crates.io), package age
  2. Version age -- picks the newest stable version published 7+ days ago (cooldown window)
  3. Vulnerability scan -- OSV API, with ecosystem-native tools (npm audit, pip-audit, bundle audit) when available
  4. Hash-pin integrity -- for PyPI requirements.txt lines with --hash=sha256:... pins, the declared hash is validated against PyPI's published hashes; mismatch emits a WARNING
  5. Abandoned & stale packages -- known-abandoned packages (e.g. paperclip, request, pycrypto, github.com/dgrijalva/jwt-go) are hard-blocked immediately with a suggested replacement; packages with no stable release in 2+ years get an advisory STALE: warning. Hard-blocked packages are removed from the manifest and Claude will ask how to proceed; stale-only packages are left in place.

If issues are found, Claude emits warnings and may step back to a safer version. All checks are logged to ~/.claude/safer-dependencies-audit-YYYY-MM.log (one file per calendar month).

How it works

The skill operates in five modes (summarized below; the deepest design rationale lives in skills/safer-dependencies.md):

Normal Mode (Manual)

When Claude is about to write an import, add a package to a manifest, or update a lock file, the skill runs inline in your session:

  1. Queries the package registry for stable versions
  2. Auto-selects the newest version published 7+ days ago (deterministic -- no LLM judgment)
  3. Checks for known vulnerabilities via ecosystem tools and the OSV API
  4. Verifies package signatures where available
  5. Emits warnings if issues are found, pins the exact version
  6. Logs the result to the audit trail

The version selection is handled by standalone Python scripts bundled with the skill, not by the LLM interpreting rules. The command outputs SELECTED: <version> and Claude uses that version exactly.

Intercept Mode (Automatic)

Configure .claude/settings.json with a PostToolUse hook to enable automatic, transparent package verification:

  1. Claude writes a manifest file (e.g. package.json) with the originally-requested version — the file lands on disk
  2. The PostToolUse hook fires immediately after the write completes and invokes safer-dependencies-shim.sh
  3. The shim reads the file, parses declared packages, and runs all security checks (typosquat, abandoned, CVE, staleness, hash-pin)
  4. If corrections are needed, the shim rewrites the manifest in place with safe versions (or removes entries that have no safe version)
  5. The shim emits signals (UPDATED:, BLOCKED:, WARNING:, STALE:, MAJOR-UPDATE-CONFIRM:, REFACTOR-REQUIRED:, REGRESSION:, TYPOSQUAT-CONFIRM:, VERIFY:, CLEAN:) via hookSpecificOutput.additionalContext on stdout. REGRESSION: precedes a MAJOR-UPDATE-CONFIRM: when the audit log shows the same (file, package) was previously corrected to the same safe target — that is, a subagent or stale plan has re-introduced a known-vulnerable version, and the orchestrator should restore the previously-approved version rather than re-deciding the major bump.
  6. Claude receives those signals as a system-reminder and performs follow-up work (find affected imports, run tests, refactor for breaking changes)

Design note — Shape C (post-write corrective): the hook does NOT block writes. Each vulnerable version lands on disk first and is then auto-corrected within the same tool-use cycle. This is a deliberate choice over a PreToolUse blocking design — see FAQ.md for the tradeoffs.

Example signal:

UPDATED: aiohttp 3.8.5 → 3.9.0 (HIGH: 33 CVEs fixed)

The parent agent uses these signals to identify affected code and refactor as needed.

Pre-Install Mode (Bash Hook)

Configure .claude/settings.json with a PreToolUse:Bash hook to enable pre-flight auditing of package-manager install commands. This complements (does not replace) Intercept Mode — together they form a layered defense.

  1. Claude attempts a Bash tool call (e.g. npm install [email protected])
  2. The PreToolUse hook fires before the call runs and invokes safer-dependencies-pretooluse-bash.sh
  3. A pure-bash early filter short-circuits non-PM commands in ~115 ms (no Python invocation), so git status / ls / npm test pay negligible cost on the hot path
  4. For recognized package-manager installs (npm/pnpm/yarn install/i/add), the helper tokenizes via shlex, extracts each pkg@version argument, and POSTs to OSV
  5. Any vulnerable concrete pin → the hook returns permissionDecision: "deny" with a per-finding GHSA-id + CVSS + summary, plus a hint to invoke the safer-dependencies skill
  6. The install never runs — no network fetch, no postinstall scripts

Why this exists in addition to Intercept Mode: the post-write shim is blind to Bash. npm install [email protected] runs to completion (and postinstall scripts execute) before any audit fires; npm install -g typosquat-pkg writes no project manifest at all. Pre-Install Mode closes those gaps structurally.

Pre-Install Mode only sees what the user typed (pkg@version args on the command line). It can't see the transitive tree the resolver will actually install. Post-Install Mode (below) audits the lockfile once the install completes — the two modes are complementary, not redundant.

Scope: the package-manager CLIs covered here span five ecosystems (npm/pnpm/yarn/bun/npx/deno, pip/pip3/pipx/pipenv/uv/uvx/poetry, gem/bundle, go, cargo), plus Maven via Intercept Mode (Maven dependencies are typically declared in pom.xml/build.gradle, not added via a CLI verb).

Known gap: the Maven CLI does support direct downloads via mvn dependency:get -Dartifact=group:art:version and mvn dependency:copy. This hook does not yet recognize those invocations. If you use them regularly, the existing post-write shim still catches whatever lands in your manifest, but the pre-fetch protection only applies to the ecosystems listed above. Tracked as a follow-up.

Per-ecosystem syntax recognized:

PMVerbsConcrete-pin syntax
npm, pnpm, yarn, buninstall, i, add (plus yarn/pnpm dlx, bun x, yarn create)[email protected], @scope/[email protected]
npx(verbless — package is first positional)[email protected]
denoadd, installnpm:[email protected] (npm-prefixed specs)
pip, pip3, pipx, pipenv, uv, uvx, poetryinstall (pip/pip3/pipx/pipenv) / add (uv/poetry) / verbless (uvx)pkg==1.2.3 (extras pkg[extra]==X also handled)
gem, bundleinstall (gem) / add-v 1.2.3, --version 1.2.3, --version=1.2.3 (separate flag)
goget, install[email protected] (must include v prefix per Go modules)
cargoadd, install[email protected]

Range pins (npm ^4.17, pip >=, poetry ^/~, Go @latest) and unspecified versions pass through to Intercept Mode after install — the post-write shim audits whatever the resolver picks. Auto-rewrite to a safe version is queued as a follow-up.

Failure mode: fail-open. Any error (Python missing, network blip, malformed input) exits 0 with no output, allowing bash to proceed. Intercept Mode still runs after install, so a failed pre-flight degrades gracefully to existing protection.

Example deny:

safer-dependencies pre-flight audit blocked this install.
Vulnerable pinned version(s) detected:
  - [email protected] → GHSA-35jh-r3h4-6jhm (CVSS:7.4): Command Injection in lodash
Re-run with a patched version, or invoke the safer-dependencies skill
for a recommended pin.

Post-Install Mode (Bash Hook)

Configure .claude/settings.json with a PostToolUse:Bash hook to enable post-flight auditing after Bash commands. It runs three independent scans against the command's cwd, each closing a gap the other hooks can't address:

  • Scan A — lockfiles. After a successful install verb (npm install, bundle install, poetry install, uv sync, go mod tidy, etc.), audits freshly-modified lockfiles (package-lock.json, Gemfile.lock, poetry.lock, uv.lock, go.sum, yarn.lock, pnpm-lock.yaml, Pipfile.lock). This closes the transitive-CVE gap Pre-Install can't see: the user typed pkg@version, but the resolver may have pulled in dozens of transitives no one named.
  • Scan B — manifests. After any Bash command not on a read-only denylist (ls, cat, git status, …), audits freshly-modified manifests. This is the only fallback for manifest edits made via sed -i, jq, or a script — those bypass the Write/Edit tool that Intercept Mode hooks on.
  • Scan C — resolved environment. Plain pip install / pip install -r requirements.txt writes no lockfile, so Scan A never sees the resolved tree. After a pip-shaped install, Scan C re-invokes the same pip with a read-only list --format=json and OSV-checks the full resolved environment (direct + transitive).

How a scan runs:

  1. Claude runs a Bash tool call
  2. The PostToolUse hook fires after the command completes and invokes safer-dependencies-posttooluse-bash.sh
  3. A pure-bash early filter short-circuits commands that match no scan gate in ~115 ms (same fast-path convention as Pre-Install), so ls / git / cat pay negligible cost
  4. Each scan walks cwd with find -maxdepth 5 (covers monorepo layouts; excludes node_modules, .git, .venv, venv) for files modified within the last 60 s — override via SAFE_DEP_POSTINSTALL_MTIME_WINDOW
  5. For each freshly-modified file (Scan A/B), the hook forges a synthetic PostToolUse:Write payload and pipes it to the existing shim — the shim's lockfile and manifest auditors run unchanged, no duplicated logic
  6. Per-file signals are concatenated and emitted as one hookSpecificOutput JSON to the parent agent

What it catches that Pre-Install doesn't: transitive vulnerabilities. A clean-looking bundle install can pull [email protected] (CVE-2025-27610) as a transitive of sinatra — the user never typed rack, so Pre-Install can't see it, but Post-Install reads the resolved Gemfile.lock and reports the CVE.

Scope: Scan A does not rewrite resolved versions — the auto-correct contract only applies to manifests Claude wrote directly. For transitive CVEs, the fix is typically "update the direct dep that owns the transitive," which needs human judgment. Scan B does auto-correct, because it audits manifests through the same shim path as Intercept Mode. Scan A skips when the transitive check tier is set to off (config set checks.transitive off).

Failure mode: fail-open, same as other hooks. Any error (missing shim, malformed payload, Python unavailable) exits 0 silently.

Example WARNING:

WARNING: [email protected] in lock file has GHSA-29mw-wpgm-hmr9, GHSA-35jh-r3h4-6jhm

Post-Agent Mode (Agent Hook Pair)

The four modes above only fire for root-session tool calls. When the root session dispatches a subagent (via the Agent tool — many skills and slash commands do this internally), the subagent's Write/Edit/Bash calls bypass all of them. Post-Agent Mode is the reactive safety net for that gap.

  1. A PreToolUse:Agent hook (safer-dependencies-pretooluse-agent.sh) runs immediately before each Agent dispatch and touches a sentinel file at /tmp/.safer-deps-agent-<PPID>-<session_id>.sentinel (falling back to a PPID-only name when no session id is available)
  2. The subagent runs and may write manifests or lockfiles
  3. A PostToolUse:Agent hook (safer-dependencies-posttooluse-agent.sh) runs after the Agent call returns, finds every manifest and lockfile newer than the sentinel, and audits each via the same shim path
  4. Findings surface as additionalContext to the root session's next turn; the sentinel is removed

Nested subagents are covered automatically — the root's PostToolUse:Agent fires only after all of the outer agent's work (including anything it dispatched) is on disk. The one gap is a global install that writes no manifest or lockfile (npm install -g …): there is nothing to scan. Like the other hooks, it fails open — any error (missing sentinel, missing shim, unreadable payload) exits 0 silently. Full design rationale lives in skills/safer-dependencies.md.

What triggers it

The skill fires automatically when Claude:

Manifest / install operations

  • Adds or updates a package in package.json, requirements.txt, Gemfile, pom.xml, build.gradle, Cargo.toml, go.mod, or any other supported manifest
  • Writes an import, require, or use for a package not already declared in the manifest
  • Generates or updates a lock file (checks only new/changed entries)
  • Runs a package-manager install via Bash (npm install, bundle install, poetry install, uv sync, go mod tidy, etc.) — Pre-Install audits the command args, Post-Install audits the resulting lockfile
  • Writes a Dockerfile or CI workflow (.github/workflows/*.yml, etc.) that embeds pinned package-manager install steps

Selection & recommendation questions

  • Library/framework comparisons: "should I use axios or node-fetch?", "moment vs dayjs?", "which is better X or Y?"
  • Recommendation requests: "what's a good HTTP client for Python?", "recommend a logging library for Go", "what package handles CSV in Node?"
  • Version selection: "what version of Django should I use?", "latest stable Flask?"

Intent-to-use expressions (pre-add)

  • "I want to use FastAPI for this", "I'm thinking of adding Celery", "we're looking at Prisma as the ORM", "let's use Tailwind"

Package health and trust questions

  • "Is moment.js still maintained?", "is this gem still active?", "is X abandoned?", "is X EOL?", "can I trust this package?", "when was faker last updated?"

Scaffolding commands

  • npx create-react-app, npm create vite@latest, django-admin startproject, rails new, cargo new + cargo add, "bootstrap a new FastAPI project"

Implicit package adds (feature requests that imply a new dependency)

  • "Add Redis caching to the app", "connect to Postgres", "add JWT auth", "write code to send emails" — fires when no package for that capability is already in the manifest

Migration and porting

  • "Migrate from requests to httpx", "move from CRA to Vite", "port from moment to date-fns" — audits the incoming package

It does not fire for:

  • Standard library imports (os, fs, java.util.*, etc.)
  • Already-declared dependencies that aren't being changed
  • Academic discussion of how a package works internally ("explain React's reconciler", "how does webpack's module resolution work?") — comparison and selection questions do still fire
  • Installing OS-level apps, runtimes, or IDE extensions (Python itself, Docker, Homebrew, VS Code extensions)

What's in this repo

This is a skill + hook bundle, not a single skill file. A complete install deploys these pieces:

FileRole
skills/safer-dependencies.mdThe skill (SKILL.md once installed). Describes audit procedures and includes management mode for installation/stats.
skills/safer-dependencies-shim.shPostToolUse:Write/Edit hook — audits manifest + lockfile writes and auto-corrects vulnerable versions in place (Intercept Mode).
skills/safer-dependencies-pretooluse-bash.shPreToolUse:Bash hook — pre-flight OSV audit of package-manager install commands; denies vulnerable concrete pins before the install runs (Pre-Install Mode).
skills/safer-dependencies-posttooluse-bash.shPostToolUse:Bash hook — post-flight audit after Bash commands; catches transitive CVEs in freshly-written lockfiles, manifests edited via sed/jq/scripts, and the resolved environment of plain pip install (Post-Install Mode).
skills/safer-dependencies-pretooluse-agent.sh + skills/safer-dependencies-posttooluse-agent.shPreToolUse:Agent + PostToolUse:Agent hook pair — closes the subagent coverage gap. Modes 2–4 only fire for root-session tool calls, so any manifest a subagent writes bypasses them. Post-Agent audits whatever the subagent wrote after each Agent tool-call returns (Post-Agent Mode).
skills/scripts/Shared Python library (safedep/) and standalone resolver scripts used by all hooks.
skills/scripts/safer_dependencies_manager.pyManagement module for interactive installation, usage stats, and setup validation.

The skill file alone is not enough — without hooks, automatic invocation depends on Claude deciding to reach for the skill. Install all five pieces for full coverage; many skills and slash commands dispatch subagents internally, so the Post-Agent pair matters even if you never explicitly spawn one. (See FAQ.md for why a skill on its own can't guarantee coverage.)

Supported ecosystems

EcosystemManifestLock file
npmpackage.jsonpackage-lock.json, yarn.lock, pnpm-lock.yaml
PyPIrequirements.txt, pyproject.toml, Pipfile, setup.py, setup.cfgPipfile.lock, poetry.lock, uv.lock
RubyGemsGemfile, *.gemspecGemfile.lock
Mavenpom.xml, build.gradle, libs.versions.toml--
Gogo.modgo.sum
RustCargo.tomlCargo.lock
PHP (Composer)composer.jsoncomposer.lock

Install

New to the project? Start with GETTING-STARTED.md. The short version:

git clone https://github.com/robert-auger/safer-dependencies /tmp/safer-dependencies
python3 /tmp/safer-dependencies/skills/scripts/safer_dependencies_manager.py interactive_install

The installer prompts for scope (global vs project) and which hooks to enable, then writes settings.json for you — both the hook entries and the permissions allowlist that lets the skill's check commands run without an approval prompt on every audit.

Everything else install-related lives in INSTALLATION.md, the single reference for install mechanics: manual file-by-file installs (global and project-level), Windows specifics, Post-Agent hooks, the permissions allowlist, verifying the setup, updating, pinning to a release tag, and uninstalling.

After install, day-to-day management works via natural language to Claude — install safer-dependencies (re-run / change hooks), show safer-dependencies stats, check safer-dependencies setup — or the /safer-dependencies menu. Updating is in-session too: /safer-dependencies update applies the latest release (update --check for a dry-run, update --rollback to undo); see INSTALLATION.md for the trust model.

Platform note: macOS, Linux, and Windows are supported. Windows needs Git for Windows (provides bash) and Python 3 on PATH — no WSL required.

Configuration

Two things are configurable after install:

  • Permissions allowlist — pre-approves the skill's read-only check commands (curl, npm view, pip-audit, …) so audits run without an approval prompt each time. The interactive installer writes the core entries for you; manual installs add the full block by hand. Full block and rationale: INSTALLATION.md → Permissions allowlist.
  • Security policy — the release-age cooldown window/mode and a per-check off/warn/block tier for every check type, edited with /safer-dependencies config and stored in ~/.config/safer-dependencies/config.toml. Schema and tier semantics: skills/references/configuration.md.

Warning levels

LevelMeaningExample
CRITICALStop and ask userTyposquat detected, tampered signature
HIGHWarn and proceedKnown CVE, package < 30 days old
MEDIUMWarn and proceedVersion < 7 days old, missing signature
LOWWarn and proceedUnsigned Ruby gem (expected)

Audit log

Every check is logged to ~/.claude/safer-dependencies-audit-YYYY-MM.log (one file per calendar month, where YYYY-MM is the UTC year-month) as a single JSON line. Override the full path with the SAFE_DEP_AUDIT_LOG environment variable (when set, the date suffix is not appended). Files are also size-rotated when they exceed SAFE_DEP_LOG_MAX_BYTES (default 10 MiB; set to 0 to disable). Set SAFE_DEP_MODEL to override the model value written to source.model in each entry — useful for A/B comparisons between model versions.

All five modes append to the same file. Each entry carries a source block (schema 2.2) identifying which component wrote it:

source.componentWritten byTrigger
shim.posttooluseshim.shManifest or lockfile write (Intercept Mode, Post-Install dispatch)
shim.install_errorshim.shShim preflight install failure
bash.pretoolusepretooluse-bash.shBash install command (Pre-Install Mode)
bash.posttooluseposttooluse-bash.shPost-Install Bash hook itself, when it fail-opens before reaching the shim
agent.pretoolusepretooluse-agent.shReserved for Pre-Agent fail-open events (the hook itself is currently silent on success)
agent.posttooluseposttooluse-agent.shPost-Agent hook fail-open events (e.g. shim missing, python_missing)
manual.skillClaude running Normal ModeManual audit invoked inline

source.model records the Claude Code model active in the session (e.g. "claude-sonnet-4-6"). Present in schema 2.1+; entries written by older installs omit the field. The stats command degrades gracefully to "unknown" when it is absent.

Filter by source.component with jq:

jq -r '.source.component' audit.log | sort | uniq -c | sort -rn
jq -c 'select(.source.component == "bash.pretooluse")' audit.log

# Surface every silent fail-open across all hooks:
jq -c 'select(.source.mode == "fail_open") | {component: .source.component, reason: .fail_open.reason, ts}' audit.log

For easier analysis, ask Claude for usage statistics instead of parsing logs manually:

"Show safer-dependencies stats for the last month"

This provides human-readable summaries of activity, security impact, and performance metrics extracted from these audit logs.

Entry shapes (schema 2.2). Three distinct shapes share the same ts / schema / source header:

ShapeWhen it's writtenDistinguishing fields
Audit entryManifest / lockfile / bash-install auditfile, ecosystem, checked, findings, abandoned, stale, typosquat, unknown, signatures, notes, clean
Install-error entryShim preflight install-error (component shim.install_error)install_error, shim_dir, scripts_dir
Fail-open entryAny hook entry-point exits early because of helper_missing / shim_missing / python_missing. source.mode is "fail_open"fail_open: { reason, detail? }

Audit entries: Intercept Mode runs the full pipeline (provenance, version age, OSV, abandoned/stale, typosquat, signatures), so all arrays can populate. Pre-Install Mode runs OSV only today, so abandoned / stale / typosquat / signatures are always empty. Post-Install dispatch (lockfile audit) writes under shim.posttooluse with findings populated by WARNING: strings from the lockfile auditors. The notes array carries informational NOTE: signals (e.g. manifest-skipped-because-unpinned).

Schema 2.2 added — additively — four fields to lockfile audit entries: lockfile, manifest_ref, relation_summary (a direct/transitive/unknown classification of each flagged package against the sibling manifest), and a policy block recording the transitive tier in force. The bump is backward-compatible: readers of 2.1 entries tolerate the new fields, and the source.model field remains present from 2.1 onward.

{
  "ts": "2026-04-19T12:34:56Z",
  "schema": "2.2",
  "source": {
    "component": "shim.posttooluse",
    "script": "shim.sh",
    "hook": "PostToolUse:Write",
    "tool": "Write",
    "mode": "intercept",
    "model": "claude-sonnet-4-6"
  },
  "file": "/path/to/project/package.json",
  "ecosystem": "npm",
  "checked": ["[email protected]", "[email protected]"],
  "findings": ["UPDATED: express 4.18.2 → 4.22.1 (HIGH: 1 CVE fixed)"],
  "abandoned": [],
  "stale": [],
  "typosquat": [],
  "unknown": [],
  "signatures": [],
  "notes": [],
  "clean": ["[email protected]"]
}

Pre-Install Mode example (Bash hook, vulnerable pin denied):

{
  "ts": "2026-04-23T06:56:21Z",
  "schema": "2.2",
  "source": {
    "component": "bash.pretooluse",
    "script": "pretooluse-bash.sh",
    "hook": "PreToolUse:Bash",
    "tool": "Bash",
    "mode": "intercept",
    "model": "claude-sonnet-4-6"
  },
  "file": "bash:npm install [email protected] [email protected]",
  "ecosystem": "npm",
  "checked": ["[email protected]", "[email protected]"],
  "findings": [
    "BLOCKED: [email protected] GHSA-35jh-r3h4-6jhm (CVSS:3.1/...): Command Injection in lodash"
  ],
  "abandoned": [],
  "stale": [],
  "typosquat": [],
  "unknown": [],
  "signatures": [],
  "notes": [],
  "clean": ["[email protected]"]
}

Fail-open Mode example (Post-Install Bash hook called with no shim adjacent — broken install):

{
  "ts": "2026-05-03T07:14:11Z",
  "schema": "2.2",
  "source": {
    "component": "bash.posttooluse",
    "script": "safer-dependencies-posttooluse-bash.sh",
    "hook": "PostToolUse",
    "tool": "Bash",
    "mode": "fail_open",
    "model": "claude-sonnet-4-6"
  },
  "fail_open": {
    "reason": "shim_missing",
    "detail": "/home/alice/.claude/skills/safer-dependencies"
  }
}

A fail-open entry says: "this hook fired but exited early without auditing because something prerequisite was missing." Use the jq filter above (select(.source.mode == "fail_open")) to surface every silent loss-of-protection event in your log.

When the shim runs in dry-run mode (SAFE_DEP_DRY_RUN=1), entries also include "mode": "dry_run" so post-hoc analysis can filter audit-only invocations.

Requirements

  • Python 3.9+ (the hooks probe for this and fail-open on older interpreters)
  • curl (for registry API calls and OSV vulnerability checks)
  • Ecosystem tools (optional, skill falls back to OSV API if missing):
    • npm for npm packages
    • pip-audit for Python packages
    • bundle for Ruby packages
    • dependency-check for Java packages

FAQ

Design-decision rationale (why PostToolUse instead of PreToolUse, why signatures aren't verified, why scripts and shim are duplicated, skill-loading gotchas, etc.) is documented in FAQ.md.

// compatibility

Platformscli, api, web, mobile
Operating systems
AI compatibilityclaude
LicenseNOASSERTION
Pricingopen-source
LanguagePython

// faq

What is safer-dependencies?

safer-dependencies is a security layer for Claude Code that audits packages before they’re added to your project. It detects and fixes risky dependencies, including CVEs, typosquats, abandoned packages, version-age issues, and adds package-cooldown violations across npm, PyPI, RubyGems, Maven, Go, and Rust.. It is open-source on GitHub.

Is safer-dependencies free to use?

safer-dependencies is open-source under the NOASSERTION license, so it is free to use.

What category does safer-dependencies belong to?

safer-dependencies is listed under skills in the Claudeers registry of Claude-compatible tools.

2 views
11 stars
unclaimed
updated 4 days ago

// embed badge

safer-dependencies on Claudeers
[![Claudeers](https://claudeers.com/api/badge/safer-dependencies.svg)](https://claudeers.com/safer-dependencies)

// retro hit counter

safer-dependencies hit counter
[![Hits](https://claudeers.com/api/counter/safer-dependencies.svg)](https://claudeers.com/safer-dependencies)

// reviews

// guestbook

0/500

// related in Claude Skills

🔓

An agentic skills framework & software development methodology that works.

// skillsobra/Shell249,840MIT[ claude ]
🔓

Public repository for Agent Skills

// skillsanthropics/Python159,495[ claude ]
🔓

💫 Toolkit to help you get started with Spec-Driven Development

// skillsgithub/Python117,790MIT[ claude ]
🔓

AI coding assistant skill (Claude Code, Codex, OpenCode, Cursor, Gemini CLI, and more). Turn any folder of code, SQL schemas, R scripts, shell scripts, docs,…

// skillsGraphify-Labs/Python77,228MIT[ claude ]
→ see how safer-dependencies connects across the ecosystem