npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rexymayderio/sentinel

v0.2.0

Published

Universal Security Verification Framework for AI Agent Installations

Downloads

1,083

Readme

Sentinel

Universal Security Verification Framework for AI Agent Installations

Sentinel sits between an AI agent (or a human) and any installer. Nothing installs until the target has been acquired (download-only, never executed), analyzed, risk-scored, policy-checked, and explicitly approved.

Playground · GitHub repository

flowchart TD
    A[AI / User] --> B[Sentinel]
    B --> C[Acquire]
    C --> D[Analyze]
    D --> E[Score]
    E --> F[Policy]
    F --> G[Approve]
    G --> H[Install]

The installer never runs directly. Acquirers only download and read files; install scripts are never executed during analysis.


Installation

npm install
npm run build

Or install globally / run via npx after publishing:

npm install -g @rexymayderio/sentinel
sentinel verify npm express

# MCP server (use -p so npx runs the sentinel-mcp bin, not the CLI)
npx -y -p @rexymayderio/sentinel sentinel-mcp

Requires Node.js >= 20.


Usage

CLI

# Verify only (never installs) - the manual verification path
sentinel verify npm express
sentinel verify github owner/repo
sentinel verify skill ./my-skill
sentinel verify local ./some-directory
sentinel verify mcp @modelcontextprotocol/server-filesystem
sentinel verify vscode publisher.extension
sentinel verify cursor-rules ./.cursor/rules
sentinel verify zip ./download.zip

# Verify, then install behind the approval gate
sentinel install npm express
sentinel install mcp @modelcontextprotocol/server-filesystem
sentinel install skill ./my-skill --yes      # auto-approve (still cannot override a hard BLOCK)

# Output formats
sentinel verify npm express --json
sentinel verify npm express --markdown
sentinel verify npm express --sarif

# Custom policy file
sentinel verify npm express --policy ./policy.json

# Scan test/fixture files with the full ruleset (default: secrets + malware only)
sentinel verify local ./my-project --score-tests

# CLI help
sentinel help
sentinel verify --help

During local development you can run without building:

npm run dev -- verify skill ./my-skill

MCP server

npm run mcp

Example MCP client config:

{
  "mcpServers": {
    "sentinel": {
      "command": "npx",
      "args": ["-y", "-p", "@rexymayderio/sentinel", "sentinel-mcp"]
    }
  }
}

The -p @rexymayderio/sentinel (package) flag is required: it tells npx to run the sentinel-mcp binary from the package. Without -p, npx @rexymayderio/sentinel sentinel-mcp would run the CLI with sentinel-mcp as an (invalid) argument.

CLI vs MCP

Both ship in the same @rexymayderio/sentinel package - installing it provides two binaries:

| Binary | Purpose | Run | |--------|---------|-----| | sentinel | Command-line verifier/installer | npx -y -p @rexymayderio/sentinel sentinel verify npm express | | sentinel-mcp | MCP server over stdio for AI agents | npx -y -p @rexymayderio/sentinel sentinel-mcp |

There is no separate "CLI-only" or "MCP-only" download - the two binaries are lightweight symlinks over a shared engine, so one install covers both. Use whichever entry point you need.

MCP tools: verify_package, verify_repository, verify_skill, verify_mcp, verify_extension, verify_cursor_rules, verify_docker, calculate_risk, generate_report, scan_directory, scan_archive, approve_install, install.

MCP policy can be configured with SENTINEL_POLICY_JSON and full test scoring with SENTINEL_SCORE_TESTS=true. Restrict local reads and install destinations with the platform-delimited SENTINEL_ALLOWED_ROOTS environment variable. Docker verification returns an explicit supported: false response and never masquerades as a completed scan.

Agent Skill

Install the Sentinel agent skill so your AI assistant intercepts install requests, verifies via the MCP above, explains risks, and only installs after approval.

Copy or symlink skills/sentinel/SKILL.md into your agent's skills directory (e.g. ~/.cursor/skills/sentinel/SKILL.md for Cursor).

The skill never performs analysis itself — it routes to the Sentinel MCP tools and interprets the JSON report. Manual /verify-* commands and automatic install interception are documented in the skill file.


Supported targets

| Target | Status | Notes | |--------|--------|-------| | npm | Implemented | Registry metadata + tarball extraction | | github | Implemented | Repo metadata + tarball download | | skill | Implemented | Local AI skill folder / SKILL.md | | local | Implemented | Any local directory | | mcp | Implemented | npm-backed MCP package + immutable npm identity | | vscode | Implemented | Marketplace VSIX download + bounded ZIP extraction | | cursor-rules | Implemented | Local Cursor rule directory, including .mdc files | | zip | Implemented | Local ZIP / VSIX with traversal, symlink, count, and size guards | | pip, uv, cargo, go, docker, git | Not yet implemented | Acquisition fails -> REQUIRE_APPROVAL (manual review) |


How risk is scored

Each finding has a severity. The Risk Calculator sums severity weights, subtracts positive-signal credit, and clamps the result to 0-100.

| Severity | Weight | |----------|--------| | CRITICAL | +50 | | HIGH | +20 | | MEDIUM | +10 | | LOW | +2 | | INFO | 0 |

Positive signals (verified publisher, long history, etc.) each subtract 5 from LOW/MEDIUM signal weight, capped at -30; they never offset HIGH or CRITICAL findings.

Test/fixture code is detected by path (test/, tests/, __tests__/, fixtures/, *.test.*, *.spec.*, etc.) and scanned with a narrower ruleset than production code. Everyday dev patterns (child_process, spawn, eval, dynamic imports, rm -rf, ...) are expected in tests and are not flagged there. Instead, test files are checked only for the things that genuinely matter in tests — the places malware likes to hide:

  • Leaked secrets (AWS/GCP/OpenAI keys, private keys, tokens, ...)
  • Malware signatures: remote payload delivery (curl … | sh, wget … | sh), crypto miners, UPX-packed blobs
  • Exfiltration / C2 channels: Discord/Telegram webhooks, Pastebin, ngrok, Cloudflare tunnels, .onion, dynamic DNS
  • Prompt-injection attacks hidden in fixtures

Findings that survive this filter are real, so they are reported (tagged [test-file] in terminal output, isTest: true in JSON) and counted at full weight in the risk score and policy. Use --score-tests (or set scoreTestCodeFully: true in policy) to scan test files with the full production ruleset instead.

The final score maps to a risk level:

| Score | Risk level | |-------|------------| | 0-19 | LOW | | 20-49 | MEDIUM | | 50-79 | HIGH | | 80-100 | CRITICAL |

Confidence reflects how much evidence was actually gathered, not how many problems were found. A clean, fully-described package is high confidence even with zero findings. It is computed from:

  • package metadata present (+35)
  • at least one file scanned (+25), plus +2 per file up to +20
  • +2 per finding signal up to +20

clamped to 0-100. When acquisition fails entirely, confidence is 0. Confidence (and whether any files/metadata were gathered) feeds the data-sufficiency check that can escalate a target to REQUIRE_APPROVAL.


Policy decisions

The Policy Engine (src/engine/policy-engine.ts) reduces the risk score, findings, permissions, and data assessment into exactly one of the five POLICY_DECISIONS. They are evaluated in a fixed priority order and the first matching rule wins.

Evaluation order:

  1. Corporate blacklist -> BLOCK
  2. Risk score >= block threshold -> BLOCK
  3. Insufficient data -> REQUIRE_APPROVAL
  4. Any HIGH / CRITICAL finding -> REQUIRE_APPROVAL
  5. Corporate whitelist -> AUTO_APPROVE
  6. Verified / trusted publisher -> AUTO_APPROVE
  7. Install script / shell / network / filesystem-write / warn-threshold checks -> WARN or REQUIRE_APPROVAL
  8. Nothing flagged -> APPROVE

AUTO_APPROVE

  • Meaning: Sentinel is confident the target is safe; no human interaction needed.
  • Triggered when: hard blocks, data checks, and severe-finding checks pass, then the package matches corporateWhitelist; or autoApproveTrusted is enabled and a trusted signal matches.
  • Risk shown: actual level (typically LOW).
  • Recommended action: SAFE TO INSTALL.
  • Install behavior: proceeds without prompting (CLI and MCP).

APPROVE

  • Meaning: No policy violations detected, but not explicitly trusted either. Safe default.
  • Triggered when: the target passes all checks - below warn threshold, no install scripts, no shell access, no gated network or filesystem-write access, sufficient data.
  • Risk shown: actual level.
  • Recommended action: SAFE TO INSTALL.
  • Install behavior: CLI prompts for confirmation unless --yes is passed; MCP install proceeds when confirm: true.

WARN

  • Meaning: Installable, but something deserves attention.
  • Triggered when: warnOnInstallScript is on and an npm/MCP package defines consumer lifecycle scripts (preinstall/install/postinstall), OR warnOnShellAccess is on and shell access was detected (and not already escalated), OR the risk score is at/above warnThreshold (default 50).
  • Risk shown: actual level.
  • Recommended action: PROCEED WITH CAUTION.
  • Install behavior: CLI prompts (the --yes flag asserts human approval). MCP requires both confirm: true and humanApproved: true.

REQUIRE_APPROVAL

  • Meaning: A human must explicitly approve - either because a sensitive capability was detected, or because Sentinel could not gather enough data to judge the target on its own.
  • Triggered when: any of:
    • warnOnShellAccess detects shell access (escalated from the default);
    • requireApprovalForNetwork is on and a network permission / non-LOW network finding is present;
    • requireApprovalForFilesystemWrite is on and runtime code can modify the filesystem;
    • the data assessment (src/engine/data-assessment.ts) is insufficient - acquisition failed (network error, package not found, unsupported ecosystem), no files could be scanned, a remote target returned no usable metadata, or analysis confidence is below minConfidence (default 40%). In this case the report's dataAssessment lists the specific reasons.
  • Risk shown: actual level (may be LOW with low confidence when data is thin).
  • Recommended action: REVIEW AND APPROVE BEFORE INSTALLING.
  • Install behavior: CLI prompts for explicit y/N; --yes asserts human approval. MCP requires humanApproved: true in addition to installation intent.

BLOCK

  • Meaning: Installation is forbidden. Cannot be overridden by --yes or by the MCP confirm flag.
  • Triggered when: the package name matches the corporateBlacklist, OR the risk score is at/above blockThreshold (default 80, i.e. CRITICAL).
  • Risk shown: actual level (typically CRITICAL).
  • Recommended action: DO NOT INSTALL.
  • Install behavior: refused everywhere. CLI exits with code 2.

Decision summary

| Decision | Trigger | Risk shown | Recommended action | Auto-installable | |----------|---------|------------|--------------------|------------------| | AUTO_APPROVE | Whitelist / verified / trusted publisher | actual | SAFE TO INSTALL | Yes | | APPROVE | No violations | actual | SAFE TO INSTALL | With confirm/--yes | | WARN | Install script or warn-threshold | actual | PROCEED WITH CAUTION | With human approval | | REQUIRE_APPROVAL | Shell/network/filesystem-write access, severe findings, or insufficient data | actual | REVIEW AND APPROVE BEFORE INSTALLING | With human approval | | BLOCK | Blacklist or score >= block threshold | actual | DO NOT INSTALL | No |


Policy configuration

Pass a JSON file via --policy <file> to override defaults (src/engine/default-policy.ts).

| Field | Type | Default | Effect | |-------|------|---------|--------| | blockThreshold | number | 80 | Score at/above this -> BLOCK. | | warnThreshold | number | 50 | Score at/above this -> at least WARN. | | minConfidence | number | 40 | Confidence below this -> data treated as insufficient -> REQUIRE_APPROVAL. | | trustedPublishers | string[] | [] | Exact names or explicit scoped prefixes ending in / or /*. | | corporateWhitelist | string[] | [] | Exact names/scoped prefixes auto-approved only after hard blocks and data checks. | | corporateBlacklist | string[] | [] | Exact names/scoped prefixes forced to BLOCK. | | autoApproveTrusted | boolean | false | Opt in to verified/trusted-publisher auto-approval. | | requireApprovalForNetwork | boolean | true | Network access -> REQUIRE_APPROVAL. | | requireApprovalForFilesystemWrite | boolean | true | Filesystem mutation capability -> REQUIRE_APPROVAL. | | warnOnInstallScript | boolean | true | Install scripts -> WARN. | | warnOnShellAccess | boolean | true | Shell access -> REQUIRE_APPROVAL. | | allowOverrides | boolean | true | Allow human overrides of non-BLOCK decisions. | | scoreTestCodeFully | boolean | false | When false, test/fixture files are scanned only for leaked secrets and malware signatures. When true, they are scanned with the full production ruleset. |

Example policy.json:

{
  "blockThreshold": 70,
  "minConfidence": 50,
  "trustedPublishers": ["@myorg/"],
  "corporateBlacklist": ["leftpad-evil"]
}

Analyzers

| Analyzer | Looks for | |----------|-----------| | Metadata | name, license, repo, first publish date, recent version update, downloads, verified publisher | | Source | HTTPS, suspicious TLDs, npm typosquatting | | Static code | eval, exec, spawn, child_process, subprocess, dynamic imports, base64/hex blobs, entropy, minified files | | Runtime capability | Node.js filesystem read/write and network module access | | Install script | consumer postinstall/preinstall/install, curl\|bash, wget\|bash, sudo, rm -rf, npx | | AI prompt | prompt injection, zero-width / invisible Unicode, jailbreaks, hidden goals, memory poisoning, tool escalation | | Secret | AWS / GCP / OpenAI / Anthropic / GitHub keys, JWT, private keys | | Dependency | dependency count, insecure sources, local file deps, optional native packages, OSV lookups | | Network | hardcoded IPs, Discord/Telegram webhooks, pastebin, ngrok, crypto miners, Tor | | Binary | opaque native executables and WebAssembly that require manual inspection |

Reports include evidence for code-based findings: the matching source line (file, line number, and a snippet up to 120 characters). Terminal output shows this under each finding; JSON includes file, line, and evidence fields.


Development

npm run build      # compile TypeScript to dist/
npm test           # run behavioral tests (vitest)
npm run check      # type-check source/tests and run the suite
npm run test:watch # watch mode
npm run validate:real -- all --summary # live 40-target precision/capability matrix

Architecture follows ports-and-adapters: analyzers, the risk calculator, and the policy engine are pure and unit-testable, while I/O boundaries (registry, repo API, process runner, approval prompt) are mocked in tests.


License

MIT