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

@pugi/plugin-sandbox

v0.1.0-alpha.4

Published

Pugi sandbox plugin - throws on policy violations in tool.execute.before; wraps shell calls in Seatbelt (macOS), bubblewrap (Linux), or Docker (opt-in cross-platform).

Readme

@pugi/plugin-sandbox

OS-level isolation for Pugi tool calls. Wraps bash invocations in Seatbelt (macOS) or bubblewrap (Linux), enforces a binary allowlist, blocks classes of dangerous syntax (rm -rf /, eval, subshell substitution, system redirects), and persists every decision to a JSONL audit log.

Part of the Pugi 1.0 soft fork sprint (see ADR-0081).

Status

Day 49 ships Docker as an opt-in third wrap strategy alongside Seatbelt (macOS default) and bubblewrap (Linux default). 51 node:test specs cover parser, path guard, profile generators, audit log, hook surface, and the new Docker argv builder + strategy chooser. Audit mode remains the default; flip to enforce once your team has reviewed the audit log and tuned the allowlist.

Install

pnpm add @pugi/plugin-sandbox

Usage

// pugi.config.ts
export default {
  plugin: [
    [
      '@pugi/plugin-sandbox',
      {
        mode: 'audit',                // 'audit' | 'enforce' | 'permissive'
        profile: 'workspace',         // 'minimal' | 'workspace' | 'network-allow' | 'custom'
        workspaceRoot: process.cwd(), // defaults to the Pugi worktree
        allowedDomains: ['anvil.pugi.io', 'api.pugi.io', 'github.com'],
        allowedBinaries: ['node', 'npm', 'pnpm', 'git', 'bun'],
        enableNetworkEgress: true,    // flip to false for offline runs
      },
    ],
  ],
};

Modes

| Mode | Behaviour | When to use | |---|---|---| | audit (default) | Logs violations to .pugi/sandbox-audit.jsonl. Never throws (except for rm -rf outside workspace, which is always blocked). | Onboarding new repos. Lets you tune the allowlist before flipping to enforce. | | enforce | Throws SandboxViolation on any violation. Wraps every bash call in the OS sandbox. | Production / customer-facing runs. | | permissive | Skips violation throws but still wraps commands. | Break-glass debugging only. |

Docker wrap strategy (Day 49, opt-in)

Set preferDocker: true to route every wrapped bash call through a docker run invocation instead of the OS-native sandbox. Useful for:

  • Cross-platform parity (the same image runs the same on macOS, Linux, and Windows).
  • Workloads that need stronger filesystem isolation than Seatbelt can provide on macOS.
  • Windows hosts, which previously fell through to audit-only mode.

Existing Linux and macOS customers see no behaviour change when preferDocker is unset; bubblewrap and Seatbelt remain the defaults.

export default {
  plugin: [
    [
      '@pugi/plugin-sandbox',
      {
        mode: 'enforce',
        preferDocker: true,                 // opt-in
        dockerImage: 'ghcr.io/pugi-io/sandbox:default',
        dockerMemoryLimit: '512m',
        dockerCpuQuota: '1.0',
        dockerWorkspaceWritable: false,     // mount /workspace ro by default
        dockerAllowNetwork: false,          // --network none unless opted in
        dockerEnvAllowlist: ['HOME', 'PATH', 'LANG', 'LC_ALL'],
      },
    ],
  ],
};

Per-run security posture applied to every Docker invocation:

| Flag | Value | Purpose | |---|---|---| | --rm | always | Ephemeral container; nothing persists. | | --read-only | always | Root filesystem is read-only. | | --tmpfs /tmp:size=64m | always | Small writable scratch only. | | --security-opt no-new-privileges | always | Blocks setuid escalation. | | --cap-drop ALL | always | Drops every Linux capability. | | --pids-limit 64 | always | Prevents fork-bomb. | | --ulimit nofile=128:128 | always | Caps file descriptors. | | --network none | unless dockerAllowNetwork | Default offline. | | -v ws:/workspace:ro | unless dockerWorkspaceWritable | Read-only mount. | | --memory <limit> | from dockerMemoryLimit | cgroup memory cap. | | --cpus <quota> | from dockerCpuQuota | cgroup cpu cap. | | --env <name>=<value> | per dockerEnvAllowlist | Only listed env vars cross. |

Operator prerequisites

  1. Docker Engine reachable from the Pugi process (Docker Desktop on macOS / Windows, native docker on Linux).
  2. The default image ghcr.io/pugi-io/sandbox:default available on the host. Customers can warm it via pugi doctor --warm-sandbox on first install, or pre-pull it during provisioning.
  3. To rebuild the default image from source:
    docker build -t ghcr.io/pugi-io/sandbox:default \
      -f packages/pugi-plugins/sandbox/docker/Dockerfile.default .
    docker push ghcr.io/pugi-io/sandbox:default

Performance impact

A cold docker run on the default image adds roughly 200-500 ms of container start overhead per bash call. For interactive workloads this is unnoticeable; for tight loops consider keeping preferDocker: false and relying on the OS-native wrapper.

Timeout

Per-call wallclock cap is enforced by the outer Pugi bash tool, not by the sandbox plugin. Tune it via the existing tool-level timeout in pugi.jsonc rather than expecting a Docker-specific knob here - duplicating the timeout inside the sandbox would race the outer cap and only Linux ships timeout(1) out of the box.

Profile matrix

| Profile | File access | Network | Binaries | Notes | |---|---|---|---|---| | minimal | Read system, no workspace write | Off | Allowed list only | Use for read-only analysis runs. | | workspace (default) | Read system + workspace; write workspace + /tmp | Egress to allowed domains | Allowed list only | The CEO-blessed default for Pugi. | | network-allow | Workspace read/write | Egress unrestricted | Allowed list only | Use when an LLM needs to fetch arbitrary packages. | | custom | Whatever your .sb / bwrap-args.json says | Per profile | Per profile | For advanced teams. Requires customProfile. |

Threat model

In scope

  • Accidental dangerous commands from the LLM (rm -rf /, eval, network exfil to unknown hosts).
  • Path traversal to sensitive files (~/.ssh, ~/.aws, ~/.env).
  • Command injection via subshell substitution ($(...), backticks) or piping to a fresh shell (| sh, | bash).
  • Workspace data exfiltration via curl / wget to unauthorized domains (best-effort on macOS due to Seatbelt limitations; properly enforced on Linux when network egress is disabled).
  • Writing to system paths even when the user accidentally allowlists a shell command that contains a > redirect.

Out of scope (document explicitly so users do not get a false sense of security)

  • Kernel exploits. sandbox-exec and bubblewrap depend on the host kernel's security model. A kernel CVE that lets unprivileged code escape the sandbox is not something this plugin can defend against.
  • Side-channel attacks. Timing, cache, and Spectre-class attacks are outside the scope of any user-space sandbox.
  • Network MITM. Use TLS verification and certificate pinning at the HTTP-client layer; the sandbox does not inspect TLS traffic.
  • Supply chain. npm install of a malicious dependency executes the install scripts inside the sandbox, but the sandbox still allows network egress to registry.npmjs.org by default. Use the personas signing flow in @pugi/plugin-personas for supply-chain defence.
  • macOS Seatbelt does NOT do reliable host-level network filtering. allowedDomains is advisory only on darwin; use network-allow: off for true offline runs on macOS, or move to Linux/Docker for real egress gating.

Defence in depth

The plugin layers protections so a bypass in one layer does not silently become an exploit:

  1. Command parser rejects rm -rf, eval, subshell substitution, pipe-to-shell, and system-path redirects regardless of OS.
  2. Binary allowlist restricts which executables can run.
  3. Path guard blocks .. segments, absolute paths outside the workspace, and symlinks pointing outside the workspace.
  4. OS sandbox wraps the resulting command in sandbox-exec (macOS) or bwrap (Linux) so even if a bypass slips through, the kernel contains it.
  5. Audit log records every decision for post-mortem.

Threat actor model

We assume the LLM is the only adversary inside the sandbox. The user is trusted (they can always run bash outside Pugi). External network attackers are out of scope; that is the firewall and reverse-proxy team's problem.

Audit log format

.pugi/sandbox-audit.jsonl:

{
  "ts": "2026-06-06T12:34:56.789Z",
  "mode": "enforce",
  "violation": "binary_not_allowed",
  "tool": "bash",
  "command": "docker run hello-world",
  "binary": "docker",
  "sessionId": "abc123",
  "decision": "blocked"
}

Successful tool calls in audit mode go to .pugi/sandbox-success.jsonl so the violation log stays focused.

Hook surface

  • tool.execute.before - inspect, audit, wrap.
  • tool.execute.after - lightweight success audit in audit mode.

License

MIT. See LICENSE.