npm introduced metadata for packages whose legitimate security capabilities can resemble malicious behavior. Examples may include penetration-testing utilities, credential auditing, traffic inspection, exploit research, remote administration, or code that deliberately manipulates another process. Automated malware analysis can flag these capabilities without understanding the maintainer’s purpose.

Maintainers declaring dual-use content must add a contentPolicy field to package.json and a text-only DISCLOSURE file at the package root. The declaration helps review; it does not guarantee publication.

Quick answer

Declare the package honestly, explain the sensitive capability and intended legitimate use in DISCLOSURE, inspect the packed tarball, and publish through a 2FA-enforced method such as trusted publishing. Once declared, future versions cannot remove the metadata.

{
  "name": "@example/security-audit",
  "version": "1.4.0",
  "contentPolicy": {
    "dualUse": true
  },
  "files": [
    "dist",
    "README.md",
    "DISCLOSURE"
  ]
}

Check npm’s current documentation for the exact accepted schema before publishing; enforcement and field details can evolve.

Write a useful DISCLOSURE file

The file should describe what the package can do, why legitimate users need it, and which safeguards or operating assumptions apply. Avoid marketing language and vague claims such as “for education only.”

A useful disclosure answers:

  • Which behavior may look malicious to an automated scanner?
  • What legitimate workflow uses it?
  • Does it access credentials, networks, processes, or files?
  • Does it download or execute additional code?
  • Which permissions are required?
  • What should users never do with it?

Keep the file text-only and include it in the published tarball. Do not hide the explanation only in a website that can change independently.

Inspect exactly what npm receives

Run:

npm pack --dry-run
npm pack
tar -tf example-security-audit-1.4.0.tgz

Confirm that DISCLOSURE is present and that private test fixtures, credentials, captures, generated binaries, and large research datasets are absent. Review install scripts and network behavior.

Generate a software bill of materials or at least record direct production dependencies. A security tool that silently pulls an unexpected package deserves the same scrutiny as any other release.

Use a publishing method that enforces 2FA

npm says dual-use packages must use a 2FA-enforced publishing path. Trusted publishing with OIDC, an interactive session protected by 2FA, or staged publishing can satisfy the requirement. Direct publication with a token that bypasses 2FA is not permitted for declared dual-use packages.

permissions:
  contents: read
  id-token: write

steps:
  - uses: actions/checkout@<full-commit-sha>
  - run: npm ci
  - run: npm test
  - run: npm publish --provenance --access public

Pin actions and protect the release environment. OIDC removes a long-lived npm token, but a compromised workflow can still publish malicious code under your identity.

Plan for review and permanence

Publish-time scanning may release the package normally, hold it for manual review, or block it. Preserve the source commit, packed tarball, test results, provenance, and release logs so an appeal can explain the package precisely.

Once a version is published with dual-use metadata, subsequent versions must keep the contentPolicy field and DISCLOSURE file. Treat this as a lasting package contract. Review forks or renamed packages carefully rather than using them to escape the declaration.

Review the declaration like release security data

Place ownership of contentPolicy beside package publishing, not in an unrelated documentation queue. A maintainer who understands the package should confirm that declared behavior matches the tarball being released. Review changes to the field in pull requests and block a release when executable behavior expands without a corresponding declaration.

Test from the packed artifact:

npm pack --dry-run
npm publish --dry-run

Inspect included binaries, scripts, examples, generated files, and disclosure text together. Repository files excluded from the tarball do not describe what users install, while generated files included only at publish time can create behavior reviewers never saw in source.

If npm holds a release, preserve the package version, tarball hash, publishing logs, and policy metadata before making changes. Repeatedly republishing slightly different artifacts makes the incident harder to explain and can consume version numbers without resolving the underlying classification.

Primary references

Dual-use metadata is not an accusation. It is a way to give automated and human reviewers the context that sensitive software requires. A clear declaration, reproducible package, minimal permissions, and strong publishing identity make that context credible.