Skip to content

fix(security): install from the lockfile on the documented setup path - #704

Open
hivecommons-hive[bot] wants to merge 1 commit into
mainfrom
sec/fix-documented-npm-ci
Open

hivecommons-hive[bot] wants to merge 1 commit into
mainfrom
sec/fix-documented-npm-ci

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Security Fix

Every CI workflow installs dependencies with npm ci — ci.yml:26/:82,
deploy-gh-pages.yml:37, import-architectures.yml:27,
refresh-community-people.yml:26, refresh-radar-reports.yml:26,
pr-queue-hygiene.yml:30. Every contributor-facing entry point told a human
to run npm install instead: README.md:37, CONTRIBUTING.md:11,
AGENTS.md:43, and .devcontainer/devcontainer.json's postCreateCommand.

npm install does not read package-lock.json as an instruction. It re-resolves
the semver ranges in package.json against the registry, takes whatever is
newest and matching, runs its lifecycle scripts, and rewrites the lockfile. Ten
direct dependencies use caret ranges (react ^19.3.0, @docusaurus/faster ^3.10.2, prettier ^3.9.8, cspell ^10.3.3, npm-check-updates ^23.1.0,
…), so those ranges are open in practice.

The documented setup path therefore installed and executed dependency code that
nobody here reviewed or pinned, across a graph of 1569 packages with install
scripts present in it; skipped the integrity hashes npm ci fails closed on;
and let a dependency upgrade drift silently into an unrelated PR, to be
installed faithfully by CI's npm ci on every later run. The devcontainer made
it automatic — postCreateCommand runs without anyone typing it.

The suite already assumed the opposite: the comment at
tests/dev-environment.test.mjs:312-313 calls npm ci "the first documented
setup step". Nothing actually said that, and nothing failed when a doc said
otherwise.

What this changes

  • README.md, CONTRIBUTING.md, AGENTS.md — the install step becomes
    npm ci, each with one sentence on why, and on using
    npm install <package> deliberately when adding or upgrading a dependency.
  • .devcontainer/devcontainer.json — postCreateCommand becomes npm ci.
  • tests/dev-environment.test.mjs — new test
    no developer doc or devcontainer command prescribes a bare npm install,
    which scans the three docs and all six devcontainer lifecycle hooks. It
    matches only the bare form (\bnpm install\s*(?=$|[\n'"&|;])), so npm install — still the correct way to add a dependency — passes. It reuses the file's existingstripJsonComments/devcontainerRawhelpers and the lifecycle-key list already used byevery npm script invoked by devcontainer lifecycle commands exists`.

No lockfile change: npm ci already succeeds on main as-is, so this only
changes which command people are told to run.

Files and functions claimed by this PR

  • README.md (install step), CONTRIBUTING.md (development setup),
    AGENTS.md (Build & Test install bullet)
  • .devcontainer/devcontainer.json (postCreateCommand)
  • tests/dev-environment.test.mjs (new test + BARE_NPM_INSTALL)

Disjoint from every open hold-gated PR: #676 (scripts/lib/mdx-active-content.mjs),
#684 (scripts/validate-projects-born.mjs, package.json), #691
(scripts/validate-architecture-assets.mjs), #674 (package.json), and the
test PRs #678/#680/#686/#688/#693/#702, which touch
tests/{import-architectures-fallbacks,svg-active-content,fetch-community-people,validate-*,collect-*,coverage-report-collect}.test.mjs.
None touches these five files, and this PR does not touch package.json.

Verification

  • npm test (runs npm run check then the unit suite) → 1181 pass, 0 fail
  • npm run test:unit:coverage:check → exit 0 (src files 100.00% lines /
    97.95% regions, unchanged — this PR adds no source file)
  • Non-vacuous: reverting postCreateCommand to npm install fails the new test
    with actual: [ 'devcontainer.postCreateCommand' ]; the doc arm caught a bare
    npm install code span during development and was confirmed the same way.

Closes #703


Filed by sec-check agent (ACMM L4/L5 — hold-gated mode). Hold-gated: human review required.

— hive: agent=sec-check backend=copilot model=claude-opus-5 copilot=1.0.88

Every CI workflow installs with `npm ci`, but README.md, CONTRIBUTING.md,
AGENTS.md and the devcontainer's postCreateCommand all told a human to run
`npm install`. That command does not read package-lock.json as an
instruction: it re-resolves the caret ranges in package.json against the
registry, runs the lifecycle scripts of whatever it resolved, and rewrites the
lockfile in the contributor's tree.

So the documented path installed and executed dependency code that was never
reviewed or pinned, skipped the lockfile's integrity hashes, and let a
dependency upgrade drift into an unrelated PR.

Point all four at `npm ci` and add a regression test to tests/dev-environment.test.mjs
that rejects a bare `npm install` in a developer doc or a devcontainer
lifecycle command. `npm install <package>` is still the way to add a
dependency, so only the bare form is rejected.

Closes #703

Signed-off-by: hivecommons-hive[bot] <hivecommons-hive@hive.kubestellar.io>
@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

Important

Held for human review by the hive's ACMM level gate.

This PR was opened by the "sec-check" agent while Hive policy required a human checkpoint for that agent. Non-outreach agents are held at ACMM L3–L5; the outreach agent is always held because it publishes project-facing communication.

Hive will automatically remove the hold label once current policy no longer requires a level hold for "sec-check". If this is an outreach PR, a human must review it and remove the label.

@hivecommons-hive hivecommons-hive Bot added security Approved by a Hive merger/owner for auto-merge on green CI agent/security Approved by a Hive merger/owner for auto-merge on green CI hive/hosted-available-lke648397-260827-5n31 Approved by a Hive merger/owner for auto-merge on green CI labels Sep 26, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent/security Approved by a Hive merger/owner for auto-merge on green CI hive/hosted-available-lke648397-260827-5n31 Approved by a Hive merger/owner for auto-merge on green CI hold security Approved by a Hive merger/owner for auto-merge on green CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[sec-check] Documented setup installs with npm install, bypassing the reviewed package-lock.json that CI's npm ci enforces

0 participants