From d63dd9523056857a7086017fd9907c4e22f113fe Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 24 Aug 2026 23:47:24 +0000 Subject: [PATCH 1/3] mono - chore: defense - record npm stage-only and 2FA manuals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maintainer confirmed § 5 trusted publisher / Drydock / 2FA and § 7 account 2FA plus offline recovery codes are done. Co-authored-by: Jared Wray --- DEFENSE_IN_DEPTH.md | 12 ++++++------ SECURITY.md | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/DEFENSE_IN_DEPTH.md b/DEFENSE_IN_DEPTH.md index f1808e4c..02ac32df 100644 --- a/DEFENSE_IN_DEPTH.md +++ b/DEFENSE_IN_DEPTH.md @@ -34,11 +34,11 @@ Profile: npm library · public - [x] No npm tokens (or other registry credentials) in Actions secrets — verified 2026-08-24 ## 5. npm publishing — npm libraries only -- [ ] OIDC trusted publishing configured **stage-only** on npmjs.com for the publish workflow — it can stage, never publish live (manual) +- [x] OIDC trusted publishing configured **stage-only** on npmjs.com for the publish workflow — it can stage, never publish live — recorded 2026-08-24 - [x] `.github/workflows/release.yaml` packs then stages with `pnpm stage publish ./packed/*.tgz --no-git-checks` — PR #1702 -- [ ] Maintainer promotes staged versions with 2FA (manual) -- [ ] Drydock connected — staged releases reviewed before promotion (manual) -- [ ] No direct publish rights: package requires 2FA and disallows tokens (manual) +- [x] Maintainer promotes staged versions with 2FA — recorded 2026-08-24 +- [x] Drydock connected — staged releases reviewed before promotion — recorded 2026-08-24 +- [x] No direct publish rights: package requires 2FA and disallows tokens — recorded 2026-08-24 - [x] `package.json` `repository.url` accurate so provenance maps to this repo — verified 2026-08-24 ## 6. Security tooling @@ -47,6 +47,6 @@ Profile: npm library · public - [x] Socket reviews every PR that changes dependencies — verified 2026-08-24 ## 7. Repository lockdown -- [ ] Phishing-resistant 2FA (passkeys / hardware keys) on the GitHub and npm accounts (manual) -- [ ] Recovery codes stored offline in a password manager (manual) +- [x] Phishing-resistant 2FA (passkeys / hardware keys) on the GitHub and npm accounts — recorded 2026-08-24 +- [x] Recovery codes stored offline in a password manager — recorded 2026-08-24 - [x] `lockdown-repo.sh` applied by a repo admin (never committed to this repo); `--check` with `--required-checks` and `--allowed-actions` passes (PRs required on the default branch, merges blocked unless required status checks pass, tag ruleset, immutable releases, fork-PR approval (public repos), read-only workflow tokens, Actions allowlist, secret scanning, Dependabot disabled, private vulnerability reporting (public repos)) — PR #1705 diff --git a/SECURITY.md b/SECURITY.md index 79ac219b..98405dd5 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -27,7 +27,8 @@ hardening checklist; progress is tracked in [DEFENSE_IN_DEPTH.md](./DEFENSE_IN_D - Tags can only be created by repository admins; published GitHub Releases are immutable (assets and tags cannot be changed after publish). - Workflow runs from outside collaborators always require maintainer approval, and only allowlisted GitHub Actions can run. - CI workflows default to read-only `contents: read` permissions; generated output is never committed back from CI; every action is pinned to a full commit SHA; Socket Firewall (`sfw`) wraps `pnpm install`; workflows are security-linted with zizmor on every PR. -- npm publishing authenticates with OIDC trusted publishing; there are no npm tokens in Actions secrets. CI packs tarballs and stages them with `pnpm stage publish`; a maintainer promotes the staged version. The release job `needs` a passing Aikido `scan-release`. +- npm publishing authenticates with OIDC trusted publishing configured **stage-only** on each published package (GitHub Actions → `jaredwray/cacheable` → workflow `release.yml`). There are no npm tokens in Actions secrets, and packages disallow tokens. CI packs tarballs and stages them with `pnpm stage publish`; Drydock reviews staged releases; a maintainer promotes with 2FA. The release job `needs` a passing Aikido `scan-release`. +- GitHub and npm maintainer accounts use phishing-resistant 2FA (passkeys / hardware keys). - pnpm is pinned via `packageManager` (`pnpm@11.5.1`), and the lockfile is committed. - Dependencies install through pnpm with a 7-day cooldown on new versions, lifecycle scripts blocked by default, and `trustPolicy: no-downgrade`. - There is no `.github/dependabot.yml`. From ecf4ae8660b8ebae93fbfe1df1b9641c953d6a63 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 24 Aug 2026 23:47:41 +0000 Subject: [PATCH 2/3] mono - chore: defense - cite PR #1706 on recorded manuals Co-authored-by: Jared Wray --- DEFENSE_IN_DEPTH.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/DEFENSE_IN_DEPTH.md b/DEFENSE_IN_DEPTH.md index 02ac32df..261f83b1 100644 --- a/DEFENSE_IN_DEPTH.md +++ b/DEFENSE_IN_DEPTH.md @@ -34,11 +34,11 @@ Profile: npm library · public - [x] No npm tokens (or other registry credentials) in Actions secrets — verified 2026-08-24 ## 5. npm publishing — npm libraries only -- [x] OIDC trusted publishing configured **stage-only** on npmjs.com for the publish workflow — it can stage, never publish live — recorded 2026-08-24 +- [x] OIDC trusted publishing configured **stage-only** on npmjs.com for the publish workflow — it can stage, never publish live — PR #1706 - [x] `.github/workflows/release.yaml` packs then stages with `pnpm stage publish ./packed/*.tgz --no-git-checks` — PR #1702 -- [x] Maintainer promotes staged versions with 2FA — recorded 2026-08-24 -- [x] Drydock connected — staged releases reviewed before promotion — recorded 2026-08-24 -- [x] No direct publish rights: package requires 2FA and disallows tokens — recorded 2026-08-24 +- [x] Maintainer promotes staged versions with 2FA — PR #1706 +- [x] Drydock connected — staged releases reviewed before promotion — PR #1706 +- [x] No direct publish rights: package requires 2FA and disallows tokens — PR #1706 - [x] `package.json` `repository.url` accurate so provenance maps to this repo — verified 2026-08-24 ## 6. Security tooling @@ -47,6 +47,6 @@ Profile: npm library · public - [x] Socket reviews every PR that changes dependencies — verified 2026-08-24 ## 7. Repository lockdown -- [x] Phishing-resistant 2FA (passkeys / hardware keys) on the GitHub and npm accounts — recorded 2026-08-24 -- [x] Recovery codes stored offline in a password manager — recorded 2026-08-24 +- [x] Phishing-resistant 2FA (passkeys / hardware keys) on the GitHub and npm accounts — PR #1706 +- [x] Recovery codes stored offline in a password manager — PR #1706 - [x] `lockdown-repo.sh` applied by a repo admin (never committed to this repo); `--check` with `--required-checks` and `--allowed-actions` passes (PRs required on the default branch, merges blocked unless required status checks pass, tag ruleset, immutable releases, fork-PR approval (public repos), read-only workflow tokens, Actions allowlist, secret scanning, Dependabot disabled, private vulnerability reporting (public repos)) — PR #1705 From 360ba064bc944edc6fa8cc8cd148ac7065d21e27 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 25 Aug 2026 18:39:56 +0000 Subject: [PATCH 3/3] mono - chore: defense - use space-free matrix test check names GitHub matrix jobs were reporting "test (22)" which the ruleset cannot require. Name each leg test-22/24/26 and keep a test gate so the existing required check still reports. Co-authored-by: Jared Wray --- .github/workflows/codecov.yml | 11 +++-------- .github/workflows/tests.yml | 20 +++++++++++++++++++- DEFENSE_IN_DEPTH.md | 2 +- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 4d8aeb22..6962dd62 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -11,13 +11,8 @@ permissions: contents: read jobs: - test: + codecov: runs-on: ubuntu-latest - - strategy: - matrix: - node-version: ['26'] - steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -33,10 +28,10 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 - - name: Use Node.js ${{ matrix.node-version }} + - name: Use Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: ${{ matrix.node-version }} + node-version: '26' cache: pnpm - name: Enable Corepack diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 85d398b6..498f5e78 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,7 +11,10 @@ permissions: contents: read jobs: - test: + # Matrix check names must be kebab-case. GitHub otherwise reports + # "test (22)", which rulesets cannot require (spaces are rejected). + test-node: + name: test-${{ matrix.node-version }} runs-on: ubuntu-latest strategy: @@ -56,3 +59,18 @@ jobs: - name: Test run: pnpm test:ci + + # Space-free required check (`test`) so the branch ruleset can match. + test: + needs: test-node + if: ${{ always() && !cancelled() }} + runs-on: ubuntu-latest + steps: + - name: Install Socket Firewall + uses: SocketDev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2 + with: + mode: firewall-free + firewall-version: "1.15.0" + + - name: Require matrix success + run: test "${{ needs.test-node.result }}" = "success" diff --git a/DEFENSE_IN_DEPTH.md b/DEFENSE_IN_DEPTH.md index 261f83b1..594f7a92 100644 --- a/DEFENSE_IN_DEPTH.md +++ b/DEFENSE_IN_DEPTH.md @@ -27,7 +27,7 @@ Profile: npm library · public - [x] Every action pinned to a full commit SHA (`npx actions-up`) — PR #1701 - [x] Every job installs Socket Firewall (`SocketDev/action` SHA-pinned, `firewall-version` pinned); `pnpm install` / `npm install` run as `sfw pnpm install` / `sfw npm install` — PR #1701 - [x] `.github/workflows/check-workflows.yaml` lints workflows with zizmor on every PR — PR #1701 -- [x] Workflow `name:` and job `name:` contain no spaces (kebab-case) so they can be set as required status checks — PR #1701 +- [x] Workflow `name:` and job `name:` contain no spaces (kebab-case) so they can be set as required status checks; matrix checks are `test-22` / `test-24` / `test-26` plus a `test` gate — PR #1701, PR #1706 - [x] `persist-credentials: false` on checkouts that don't push — PR #1701 - [x] No `pull_request_target` on workflows that run untrusted PR code — verified 2026-08-24 - [x] Artifact-publishing workflows disable `actions/setup-node` default caching (`package-manager-cache: false`) to prevent cache poisoning — PR #1701