Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
20 changes: 19 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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"
14 changes: 7 additions & 7 deletions DEFENSE_IN_DEPTH.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,18 @@ 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
- [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 — PR #1706
- [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 — 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
Expand All @@ -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 — 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
3 changes: 2 additions & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down