PackAttest

See it. Select it. Ship it.

Early prototype · v0.1.0 · MIT licensed · Feedback welcome

PackAttest is a small command-line tool for the npm ecosystem that prevents accidental file leaks in published packages. It treats the final tarball as the source of truth and requires explicit human approval of every file before release.

Install globally and run pa review from any package directory:

npm install -g packattest
pa review

View on GitHub

The problem

In npm, what gets published is typically defined by .npmignore or the files field in package.json. These are configured before the final artifact exists.

Build tools evolve. Defaults change. Outputs drift. New files appear. And nothing in most workflows requires a human to review the actual artifact before it is published. The result is a recurring class of incident: source maps exposing internal logic, .env files bundled by accident, debug artifacts and test data shipping to production.

npm pack --dry-run can show you the contents, but it is optional, has no memory of the previous release, and leaves no record that a review happened. Hope is not a security property.

The model

  1. Artifact is truth. Decisions are based on the final packaged tarball — not the source tree, not configuration files. If it is in the tarball, it ships.
  2. Explicit human approval. Before publishing, every file in the artifact must be consciously selected. No implicit inclusion, no silent defaults.
  3. Attestation. Approval is recorded as a verifiable file — artifact hash, selected files, reviewer identity, source commit — and committed alongside the code.
  4. CI enforcement. The pipeline rebuilds the artifact and compares it to the attestation. If anything has changed since review, publishing fails hard.

How it works

PackAttest exposes three commands:

pa review — pack the artifact, diff it against the version currently tagged latest on the registry, and present the exact file list. Nothing is preselected; every file must be toggled and confirmed.

Animated demo: running pa review shows all files; the user leaves the source map and .env file unchecked and confirms publishing only three safe files.

After review, an attestation file is written to the repository:

{
  "version": 1,
  "package_name": "your-package",
  "package_version": "1.4.0",
  "artifact_hash": "sha256:6ecd7fb...",
  "selected_files": [
    "package/dist/index.js",
    "package/package.json",
    "package/README.md"
  ],
  "reviewed_at": "2026-04-04T16:01:27.907Z",
  "reviewer": "git:your-name",
  "source_commit": "595b0df...",
  "tool_version": "0.1.0"
}

pa publish — verify the current artifact against the attestation and publish locally.

pa verify — the same verification flow for CI, with structured log output. Rebuilds the artifact, checks the hash, and publishes only if everything matches. If the artifact has drifted since pa review, the pipeline fails.

What it doesn't solve

PackAttest is intentionally narrow. It helps prevent accidental file inclusion, unexpected build artifacts, and scope expansion between releases.

It does not:

Those are different problem spaces, requiring different tools. PackAttest addresses one specific, common, and repeatedly demonstrated failure mode: not realizing a file was in the package.

Get started

Install from npm:

npm install -g packattest

Or install from source:

git clone https://github.com/divohna/PackAttest.git
cd PackAttest && npm install && npm install -g .

Then, from any package directory:

pa review

GitHub Repository

Feedback, critiques, and contributions welcome.

← Back to Home