In short

Decide intake from evidence about the role the package will play, not from a score. Check that the exact version you will ship links to a reviewed source commit, ideally through verified provenance; who can publish it; how the project handles security reports; and the Scorecard checks that matter for your use, such as Code-Review, Maintained, Dangerous-Workflow and Signed-Releases. Pin the approved version, contain the remaining risk, name an update owner and set reopening triggers.

  • A Scorecard total is a risk-weighted average of unrelated checks; read the individual checks, the scan date and every -1 (inconclusive) result.
  • Scorecard rates Dangerous-Workflow and Webhooks as Critical risks and Code-Review, Maintained, Signed-Releases and Token-Permissions as High.
  • A package's repository link is often unverified metadata; only provenance, such as npm's SLSA attestation, binds a version to a commit.
  • Whoever can publish controls what you install: the 2025 Shai-Hulud worm republished packages with stolen maintainer tokens.
  • Turn residual risk into enforceable conditions: a pinned version and digest, an isolated worker, size limits and a named update owner.

Verify it

  1. Run ./intake-evidence.sh <package> <version> and copy the provenance, repository link type and Scorecard scan date into the intake record.
  2. Confirm that the version you will pin has provenance with verified: true, or record the missing link as a blocking or accepted gap.
  3. List publishers with npm view <package> maintainers and reopen the intake when that list changes.
  4. Re-run the evidence script for every new major version and after any maintainer or repository change.
  5. Test the pilot limits: a 101,000,000-byte expansion must stop at the 100,000,000-byte cap and clean up, while a 99,000,000-byte archive completes.
Applies to

Dependency intake and continuity decisions. Popularity or a score cannot replace fit-for-use and update planning.

Learning goals and prerequisitesAbout 28 minutes: 6 to read and 22 for the exercise

What you will learn

  • Interpret project-health findings in a concrete execution context.
  • Apply hard intake gates separately from aggregate scores.
  • Convert residual risk into testable pilot conditions and ownership.

Before you start

Engineers and reviewers who approve new open source dependencies and own their updates

  • Read dependency metadata and distinguish adoption, maintenance activity and security response evidence.

Refresh first: Generate an SBOM for the software you actually release

Go to the guided practice

Assess the dependency in the role it will have

Project health becomes a security decision only when joined to how you use the dependency. A parser for anonymous uploads, a development formatter and a privileged deployment agent have different exposure and replacement costs. Start with required functionality, execution context, data handled, update mechanism, available alternatives and the team's ability to maintain a fork. Popularity or a high aggregate score cannot answer those product-specific questions.

The fictional team needs an archive parser for untrusted customer uploads. Candidate A has a higher total security score but a single active maintainer and an unexplained release workflow gap. Candidate B has a lower score because its badge and packaging checks are incomplete, yet its recent fixes have clear review and release records. The task is not to pick the prettier dashboard. It is to decide which evidence addresses the consequence of parsing attacker-controlled bytes and whether the remaining uncertainty can be bounded operationally.

Read checks and observations behind the aggregate

OpenSSF Scorecard runs about 20 automated checks against a source repository and rates each from 0 to 10, or -1 when it could not reach a result. Each check carries a risk level: Dangerous-Workflow and Webhooks are Critical; Binary-Artifacts, Branch-Protection, Code-Review, Dependency-Update-Tool, Maintained, Signed-Releases, Token-Permissions and Vulnerabilities are High. A failed check can signal a real weakness, unsupported tooling or an observation limitation, and a passed check can cover a narrow behavior rather than the entire project. Inspect raw findings, the scan date and the repository identity. Do not assume that a repository's settings describe every package published under its name, or that its score is a probability of compromise.

For archive parsing, relevant evidence includes response to input-validation defects, release provenance, reviewed changes, test cases for malformed input and a way to report vulnerabilities. A quiet repository may be stable or abandoned; commit frequency alone does not distinguish those states. A recently added maintainer can improve continuity or introduce takeover risk; examine the release authorization path. Where an automated finding conflicts with a supplied release record, preserve both and investigate the specific claim rather than averaging away the disagreement.

Read checks and observations behind the aggregate
Scorecard checkRiskWhat it measuresWhy it matters for an upload parser
Dangerous-WorkflowCriticalWorkflow patterns such as untrusted checkouts in privileged triggersA compromised CI can publish malicious releases.
Code-ReviewHighWhether recent changes were reviewed before mergeUnreviewed parser changes reach releases directly.
MaintainedHighCommit and issue activity in the last 90 daysParser fixes need a responsive maintainer.
Signed-ReleasesHighSignatures or provenance on release assetsLinks what you download to what was built.
VulnerabilitiesHighOpen OSV advisories against the projectKnown unfixed issues before you adopt it.
FuzzingMediumIntegration with OSS-Fuzz or other fuzzersMalformed archives are the main input risk.

Collect the evidence with deps.dev, Scorecard and npm

The script below gathers intake evidence for one exact npm version from public APIs, without a token: deps.dev reports licenses, advisories, verified provenance and how it linked the version to a repository; the Scorecard API returns the latest published result for that repository, usually from OpenSSF's weekly scan; and npm lists who can publish. For sigstore 5.0.0, deps.dev showed SLSA provenance with verified: true naming the source commit, and a repository link backed by SLSA_ATTESTATION. For the widely used tar 7.5.22 it showed no provenance and only an UNVERIFIED_METADATA repository link, taken from package.json, with one publisher; Scorecard's 2026-10-05 scan of that repository scored 5.6, with Code-Review 0 and Signed-Releases and Branch-Protection inconclusive. That says nothing about the quality of the code. It means the claim that the registry tarball came from the reviewed repository rests on trust in the publisher, which an intake gate like the one in this guide must record.

intake-evidence.shShell
#!/usr/bin/env bash
set -euo pipefail
PKG="$1" VER="$2"   # an npm package and exact version; URL-encode scoped names (%40scope%2Fname)
DEPS="https://api.deps.dev/v3/systems/npm/packages/$PKG/versions/$VER"

# 1. License, advisories, provenance and how deps.dev linked the version to a repository
curl -s "$DEPS" | jq '{publishedAt, licenses, advisoryKeys,
  provenance: [.slsaProvenances[] | {sourceRepository, commit, verified}],
  repository: [.relatedProjects[] | select(.relationType == "SOURCE_REPO")
    | {id: .projectKey.id, relationProvenance}]}'

# 2. OpenSSF Scorecard checks for that repository (latest published result; -1 means inconclusive)
REPO=$(curl -s "$DEPS" | jq -r '[.relatedProjects[] | select(.relationType == "SOURCE_REPO")][0].projectKey.id')
curl -s "https://api.scorecard.dev/projects/$REPO" \
  | jq '{date, score, checks: [.checks[] | {name, score}]}'

# 3. Who can publish this package, and whether npm holds provenance for this version
npm view "$PKG@$VER" maintainers dist.attestations.provenance --json

Record conditions that can actually be enforced

A dependency intake record needs the exact package/repository relationship, required capability, criticality, exposure, assessed evidence, unresolved questions, chosen version/digest, approving role and maintenance plan. Conditions should be measurable: pin an approved archive digest, keep parsing in a restricted worker, cap input/output size, and retain regression tests. A vague promise to monitor the project leaves no event that changes the decision. Record the license as part of intake; /domains/supply-chain/dependencies/open-source-license-compliance/ covers the check.

The fixture's local rule forbids production intake for this parser unless the distributed package can be linked to an authorized release and the team has an owned update path. Candidate A lacks that link despite its higher score, so it remains pending. B has the needed release evidence and a documented response route, but its single active release owner creates continuity risk. A conditional pilot can limit exposure and establish fallback support; it is not proof that B is safer in every dimension. Stronger isolation also increases latency and operational work, which the decision should acknowledge.

Use change events and expiry instead of a permanent badge

A health assessment expires when relevant facts change: maintainer ownership, release signing identity, registry namespace, security response, major architecture, support status or your own use of the package. Reassess high-consequence dependencies on a scheduled cadence as well as on those events. An old intake approval should not authorize a new major version that introduces native code or network access without review. Watch the publishing path too: in September 2025 the Shai-Hulud worm stole npm tokens from developer machines and CI runners and used them to publish malicious versions of other packages those tokens could publish. A new version that loses provenance its predecessors had, adds an install script or comes from a new publisher deserves review before it is installed; pnpm trustPolicy: no-downgrade fails an install when a package's trust evidence is weaker than in earlier releases. Ownership changes were the signal that mattered in /domains/supply-chain/dependencies/case-study-event-stream/ and /domains/supply-chain/dependencies/case-study-polyfill-io/: the handover of an npm package and the sale of a CDN domain.

NIST supply-chain risk guidance and SSDF provide broader risk and lifecycle context, but the concrete policy here is fictional. For an organization-wide program, the OpenSSF S2C2F puts intake checks like these into a maturity model (/domains/supply-chain/dependencies/s2c2f-adoption/), and a maintainer's dated OSPS Baseline claim (/domains/supply-chain/ci-cd/osps-baseline-for-maintainers/) is one more piece of evidence to read, not a score. Its purpose is to show how evidence becomes an engineering condition. Preserve the rejected or deferred option and why; otherwise the next team may repeat the same superficial score comparison. The exercise includes all relevant observations and decision thresholds. It deliberately leaves code quality unproven so the reader cannot turn project-health evidence into an unsupported statement that the parser is vulnerability-free.

Guided practice

Select a bounded pilot candidate for an archive parser used on anonymous uploads. The local intake gate requires authorized-release linkage and an owned update path.

Supplied scenario material
Plain text
Candidate A: pkg:generic/zipfast@8.0; Scorecard total 8.8/10; package digest HA; release tag exists but no evidence connects registry archive HA to reviewed commit; one active maintainer; last security response 200 days ago, resolution unknown.
Candidate B: pkg:generic/archivecore@3.2; total 6.4/10; package digest HB; E1 authenticated provenance links HB to reviewed C32; E2 security contact responded in 2 days in supplied incident; release owner is a single person; missing badge/fuzzing check evidence.
Product: anonymous uploads, maximum compressed size 10 MB; expanding archives can exhaust disk. Worker isolation is available at cost of 30 ms/job.
Local policy: unknown release origin blocks; assign internal update owner; pilot must enforce 10 MB input and 100 MB expanded-output caps, no network, scratch-only writes; reassess in 30 days.
Fictional internal owner Jo can maintain B updates; no owner assigned for A.
  1. 1. Choose relevant evidence

    Explain why total score alone cannot satisfy the intake gate.

    Expected result and reasoning

    A scores higher but its shipped HA lacks authorized-release linkage and an internal update owner. Those are mandatory local conditions. B supplies the release link and Jo can own updates, despite lower automated totals.

  2. 2. Make the scoped decision

    Decide A and B without claiming comprehensive safety.

    Expected result and reasoning

    Defer A pending release-origin evidence and ownership. Permit a conditional B pilot at HB/C32 only, subject to required isolation and size controls. B is not declared vulnerability-free or universally superior.

  3. 3. Translate a condition into a test

    Specify exact output-cap behavior for 99 MB and 101 MB expansion.

    Expected result and reasoning

    With the exercise cap defined in decimal MB, 99,000,000 expanded bytes may complete; an attempted 101,000,000 bytes must abort before exceeding 100,000,000 and clean scratch output. Compressed input under 10 MB does not waive expansion limits.

  4. 4. Record residual risk

    Name two uncertainties and the operational cost.

    Expected result and reasoning

    Single-person release continuity and absent fuzzing evidence remain open. Isolation adds 30 ms/job and maintenance burden. Jo owns updates; product owner accepts only the limited pilot, not indefinite unrestricted use.

  5. 5. Set reopening triggers

    Write a 30-day review and two immediate triggers.

    Expected result and reasoning

    Review pilot and supplier evidence after 30 days. Immediately reopen on maintainer/release-identity change or use outside the isolated capped worker. A new version needs its own digest/release-link verification.

Your deliverable: A dependency intake decision with hard gates, pilot conditions, residual risks and exact re-evaluation events.

Scores, packages and incidents are fictional. The guide models risk reasoning, not a recommendation to use a real dependency.

Save a draft on this device to resume later. Automatic saving begins after you choose Save. Drafts are never sent by this application; use synthetic data.

No draft saved on this device yet.

Sources & further reading

The standards, specifications and documentation behind the guidance above. Each is the evidence for a claim on this page; consult it for detail beyond the defaults and versions listed here.

  1. OpenSSF Scorecard project and checks
  2. NIST SP 800-161 Rev. 1, updated: supply-chain risk management. May 2022, updated 1 November 2024.
  3. NIST SP 800-218: SSDF 1.1, final (1.2 initial public draft published 2025-12-17). Version 1.1 (February 2022).
  4. OpenSSF Scorecard: checks and risk levels
  5. OpenSSF Scorecard API
  6. deps.dev API v3
  7. OpenSSF: Concise Guide for Evaluating Open Source Software
  8. CISA: widespread supply chain compromise impacting the npm ecosystem (2025-09-23)
  9. pnpm settings: dependency resolution (trustPolicy)

Reference information

ASVS 5.0.0 requirements
v5.0.0-15.1.2 · v5.0.0-15.1.4

Download this guide as Markdown