Built for the post-postmark-mcp era

Stop trusting your
dependencies. Start gating them.

ModuleWarden is the policy layer between your developers and npm. Every version, every install, audited in an isolated sandbox before it lands in your codebase.

Free for OSS. No credit card. Self-host or cloud.

~/your-repo · npm install · routed through modulewarden
$ npm install postmark-mcp@1.0.16
> fetching v1.0.15 baseline (last allowed)...
> fetching v1.0.16 candidate...
> running bounded diff audit (sandboxed)...
⚠ new postinstall script
⚠ outbound network call added: post to api.attacker.tld/exfil
⚠ environment variable read: SMTP_USER, SMTP_PASS
✗ BLOCKED risk=0.94 policy=team-defaults ref=incident-2511
> posted to #security · runbook attached · audit log: aud_7f3e2
> use mw approve aud_7f3e2 to override (requires approver)
$ _

Real incident, real package. postmark-mcp v1.0.16, Sep 2025 · ~1,500 weekly downloads at time of compromise.

847K

malicious npm packages

Sonatype, Q2 2025

+156%

YoY growth in attacks

Sonatype Open-Source Malware Index

~15min

median dwell time

Compromise to first install

0

audit logs by default

npm install gives you nothing

The problem

Your scanners run after the damage is done.

SCA tools flag known CVEs. Endpoint scanners look at what is already installed. By the time either fires, the malicious tarball is in your node_modules/, your environment variables are in someone else's S3 bucket, and your incident response clock is ticking.

CVE scanners are reactive

A CVE gets assigned after the attack is public. You get blocked from a malicious version that already shipped to production.

Endpoint tools are post-install

Bumblebee, EDR, runtime scanners. All useful. All look at packages after they are on disk, after the postinstall script ran.

Approval is the only sound gate

The right time to block a malicious package is before it executes. ModuleWarden enforces that gate without slowing down legitimate work.

How it works

A policy gate. Not another scanner.

ModuleWarden runs between your package manager and the registry. Every npm install routes through the gate. The gate runs a bounded audit. The audit produces a decision. Your CI either gets the package or gets a clear reason it was blocked.

1

Bounded diff, not the whole world

Each audit reviews version N to N+1 of one package. Not the 3M-package npm ecosystem. The signal-to-noise actually works in our favor.

2

Private prompts, private rubric

Attackers cannot game what they cannot see. Your review criteria live in your org. We never publish them. Each customer's rubric drifts independently as new attack patterns emerge.

3

Sandboxed audit harness

The audit runs in a one-shot Docker container with no network, no host mounts, no secrets. Even if the package is actively malicious, the blast radius is zero. The container terminates, the verdict ships, the harness disappears.

4

Three outcomes, every one logged

Allow, quarantine, or block. Every decision streams to your SIEM with the reasoning, the diff, and the policy that fired. Your auditors will have actual answers.

Request flow
  developer / CI runner
       │
       │  npm install foo@2.1.0
       ▼
  ┌──────────────────────────┐
  │  ModuleWarden Gate       │
  │  (Verdaccio + policy)    │
  └────────────┬─────────────┘
               │
               ├─ fetch v2.0.4 (last allowed)
               ├─ fetch v2.1.0 (proposed)
               │
               ▼
  ┌──────────────────────────┐
  │  Audit Container          │
  │  Docker · no net · 1-shot │
  │  Bounded diff + rubric    │
  └────────────┬─────────────┘
               │
               ▼
  ┌──────────────────────────┐
  │  Policy Decision          │
  │  + audit log > SIEM       │
  └────────────┬─────────────┘
               │
       ┌───────┼────────┐
       ▼       ▼        ▼
    allow  quarantine  block
       │       │
       │       └─> Slack approval (one click)
       ▼
   tarball > cache > developer

Drops into your stack

Works with what you already run.

npm
drop-in registry proxy
pnpm
.npmrc one-liner
yarn
v1, berry, both
bun
bunfig.toml
🐝

Pairs with Bumblebee

Perplexity's open-source endpoint scanner feeds ModuleWarden your installed-package inventory from every developer laptop and CI runner. Baseline risk score, org-wide, in one shot. The two tools are built for each other.

📊

Streams to your SIEM

Splunk, Datadog, Sumo, Elastic, raw webhooks. Every decision, every approval, every override. Compliance auditors get a real trail. Security ops get real signal.

Install in 30 seconds
# self-host the gate
$ docker run -p 4873:4873 -v mw-data:/data ghcr.io/modulewarden/gate:latest

# point npm at it
$ npm config set registry http://localhost:4873/

# or cloud (early access)
$ npm config set registry https://gate.modulewarden.com/your-org/

Pricing

Pay for protection, not seats.

Free for open source. Flat per-developer pricing for teams. No per-audit metering, no surprise bills after an incident.

Open Source
$0
forever, for public projects
  • Self-host the gate
  • 1,000 audits / month
  • Community rule pack (OSSF-backed)
  • CLI + REST API
  • GitHub-issue support
Start on GitHub
Recommended
Team
$12 / dev / mo
10 developer minimum · billed annually
  • Everything in Open Source
  • Unlimited audits
  • Private rule packs + custom rubric
  • Slack + PagerDuty + webhook alerts
  • SIEM export (Splunk, Datadog, Sumo)
  • SSO (SAML, OIDC, Google Workspace)
  • Email + chat support
Get early access
Enterprise
Let's talk
100+ developers, regulated industries
  • Everything in Team
  • Air-gapped deployment
  • Bring-your-own LLM endpoint
  • Custom rule pack engineering
  • 24/7 incident response
  • SOC 2 Type II, DPA, BAA
  • Dedicated success manager
Contact sales

FAQ

Honest answers.

Is this just another SCA tool?

No. SCA tools tell you which already-installed packages have known CVEs. ModuleWarden gates each install request before it executes. Different position in the stack, different problem solved. Use both.

Doesn't this break our CI?

Allowed versions are cached. Repeated installs hit the cache, sub-100ms. New-version installs add ~3-8 seconds for the audit. Quarantine is async, the install resolves with a clear "pending approval" message, and your CI gets a one-click resume from Slack.

What if the audit LLM is wrong?

False positives are reviewed by your approver in one click. False negatives are caught by the rule layer (static analysis runs in parallel with the model audit, and either can fail the policy). The model is one input. Your policy is the source of truth.

Do you send our package contents anywhere?

Self-host: nothing leaves your network. Cloud: only public-registry packages are audited against our hosted LLM. Private packages stay in your perimeter via the bring-your-own-endpoint option on Enterprise. Your rubric and your decisions are encrypted at rest with a customer-held KMS key.

Why not just block everything by default?

Your developers would mutiny. The gate is calibrated for low false-positive rates by design. The point is to keep developers fast while raising the floor on what gets through.

Will this work with PyPI / RubyGems / cargo?

npm first. The architecture is registry-agnostic; PyPI is on the immediate roadmap, RubyGems and cargo follow customer demand. Email us about your ecosystem and we will prioritize accordingly.

Get early access

We are rolling out to design partners now. Tell us about your stack and we will be in touch within 24 hours.

No credit card. No spam. We respond within one business day.