From bd8cd2e57704d1e0549ba0453810ce417059825d Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 18 Aug 2026 17:02:25 +0000 Subject: [PATCH 1/2] chore: defense - lint GitHub Actions workflows with zizmor Add check-workflows.yaml and clear the findings it would fail on: persist-credentials: false on checkouts that do not push, and package-manager-cache: false on publish/deploy setup-node steps. Co-authored-by: Jared Wray --- .github/workflows/check-workflows.yaml | 28 ++++++++++++++++++++++++++ .github/workflows/code-coverage.yaml | 6 ++++++ .github/workflows/codeql.yaml | 2 ++ .github/workflows/deploy-site.yaml | 1 + .github/workflows/release.yaml | 9 +++++++++ .github/workflows/tests.yaml | 2 ++ DEFENSE_IN_DEPTH.md | 10 ++++----- SECURITY.md | 1 + 8 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/check-workflows.yaml diff --git a/.github/workflows/check-workflows.yaml b/.github/workflows/check-workflows.yaml new file mode 100644 index 0000000..3bf60b3 --- /dev/null +++ b/.github/workflows/check-workflows.yaml @@ -0,0 +1,28 @@ +name: Check Workflows + +on: + push: + branches: [main] + pull_request: + +permissions: {} + +jobs: + zizmor: + runs-on: ubuntu-latest + permissions: + contents: read + actions: read + security-events: write # SARIF upload to code scanning + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Install Socket Firewall + uses: SocketDev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2 + with: + mode: firewall-free + firewall-version: "1.15.0" + - name: Run zizmor + uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2 diff --git a/.github/workflows/code-coverage.yaml b/.github/workflows/code-coverage.yaml index b160034..2c139fb 100644 --- a/.github/workflows/code-coverage.yaml +++ b/.github/workflows/code-coverage.yaml @@ -15,6 +15,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Install Socket Firewall uses: SocketDev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2 with: @@ -36,6 +38,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Install Socket Firewall uses: SocketDev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2 with: @@ -61,6 +65,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Install Socket Firewall uses: SocketDev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2 with: diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index bdd172f..cc9d4fa 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -40,6 +40,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Install Socket Firewall uses: SocketDev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2 diff --git a/.github/workflows/deploy-site.yaml b/.github/workflows/deploy-site.yaml index f66a088..f5b115d 100644 --- a/.github/workflows/deploy-site.yaml +++ b/.github/workflows/deploy-site.yaml @@ -26,6 +26,7 @@ jobs: uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 + package-manager-cache: false - name: Install Dependencies run: sfw pnpm install --frozen-lockfile diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 1102969..1d7c541 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -13,6 +13,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Install Socket Firewall uses: SocketDev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2 with: @@ -23,6 +25,7 @@ jobs: uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 + package-manager-cache: false - name: Install Dependencies run: sfw pnpm install --frozen-lockfile - name: Build @@ -33,6 +36,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Install Socket Firewall uses: SocketDev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2 with: @@ -43,6 +48,7 @@ jobs: uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 + package-manager-cache: false - name: Install Dependencies run: sfw pnpm install --frozen-lockfile - name: Test Services @@ -60,6 +66,8 @@ jobs: id-token: write steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Install Socket Firewall uses: SocketDev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2 with: @@ -70,6 +78,7 @@ jobs: uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 + package-manager-cache: false - name: Install Dependencies run: sfw pnpm install --frozen-lockfile - name: Build diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 7d980d9..23ced9b 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -18,6 +18,8 @@ jobs: node-version: ['22', '24', '26'] steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Install Socket Firewall uses: SocketDev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2 with: diff --git a/DEFENSE_IN_DEPTH.md b/DEFENSE_IN_DEPTH.md index 742192e..2ca7ea0 100644 --- a/DEFENSE_IN_DEPTH.md +++ b/DEFENSE_IN_DEPTH.md @@ -27,13 +27,13 @@ Profile: npm library · public ## 4. GitHub Actions - [x] `permissions: contents: read` (or `{}` + per-job grants) on every workflow — verified 2026-08-17 -- [ ] Every action pinned to a full commit SHA (`npx actions-up`) (PR #113 pending) +- [x] Every action pinned to a full commit SHA (`npx actions-up`) — PR #113 - [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 #111 -- [ ] `.github/workflows/check-workflows.yaml` lints workflows with zizmor on every PR -- [ ] `persist-credentials: false` on checkouts that don't push +- [ ] `.github/workflows/check-workflows.yaml` lints workflows with zizmor on every PR (PR pending) +- [ ] `persist-credentials: false` on checkouts that don't push (PR pending) - [x] No `pull_request_target` on workflows that run untrusted PR code — verified 2026-08-17 -- [ ] Artifact-publishing workflows disable `actions/setup-node` default caching (`package-manager-cache: false`) to prevent cache poisoning -- [ ] No npm tokens (or other registry credentials) in Actions secrets +- [ ] Artifact-publishing workflows disable `actions/setup-node` default caching (`package-manager-cache: false`) to prevent cache poisoning (PR pending) +- [x] No npm tokens (or other registry credentials) in Actions secrets — verified 2026-08-18 (OIDC `id-token` on publish; no `NPM_TOKEN` in workflows) ## 5. npm publishing — npm libraries only diff --git a/SECURITY.md b/SECURITY.md index 1d4703f..9f221b9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -23,4 +23,5 @@ We will acknowledge receipt, work with you on a coordinated disclosure timeline, This repository follows the [defense-in-depth](https://github.com/jaredwray/agentic/blob/main/skills/security/defense-in-depth-nodejs/SKILL.md) hardening checklist; progress is tracked in [DEFENSE_IN_DEPTH.md](./DEFENSE_IN_DEPTH.md). Measures currently in place: - Codespaces and Cursor Cloud Agents install through Aikido Safe Chain; package-manager shims must not be bypassed. +- CI runs with read-only permissions; every action is pinned to a full commit SHA; Socket Firewall (`sfw`) wraps `pnpm install` / `npm install`; workflows are security-linted with zizmor on every PR. - Dependencies install through pnpm with a 7-day cooldown on new versions, and lifecycle scripts are blocked by default. Socket reviews every dependency change; Aikido scans every build. From 52cd5f661a31097a1c54cb4ed70d51969df00cf8 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 18 Aug 2026 17:03:02 +0000 Subject: [PATCH 2/2] chore: defense - record PR #116 on zizmor checklist Co-authored-by: Jared Wray --- DEFENSE_IN_DEPTH.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DEFENSE_IN_DEPTH.md b/DEFENSE_IN_DEPTH.md index 2ca7ea0..161af17 100644 --- a/DEFENSE_IN_DEPTH.md +++ b/DEFENSE_IN_DEPTH.md @@ -29,10 +29,10 @@ Profile: npm library · public - [x] `permissions: contents: read` (or `{}` + per-job grants) on every workflow — verified 2026-08-17 - [x] Every action pinned to a full commit SHA (`npx actions-up`) — PR #113 - [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 #111 -- [ ] `.github/workflows/check-workflows.yaml` lints workflows with zizmor on every PR (PR pending) -- [ ] `persist-credentials: false` on checkouts that don't push (PR pending) +- [ ] `.github/workflows/check-workflows.yaml` lints workflows with zizmor on every PR (PR #116 pending) +- [ ] `persist-credentials: false` on checkouts that don't push (PR #116 pending) - [x] No `pull_request_target` on workflows that run untrusted PR code — verified 2026-08-17 -- [ ] Artifact-publishing workflows disable `actions/setup-node` default caching (`package-manager-cache: false`) to prevent cache poisoning (PR pending) +- [ ] Artifact-publishing workflows disable `actions/setup-node` default caching (`package-manager-cache: false`) to prevent cache poisoning (PR #116 pending) - [x] No npm tokens (or other registry credentials) in Actions secrets — verified 2026-08-18 (OIDC `id-token` on publish; no `NPM_TOKEN` in workflows) ## 5. npm publishing — npm libraries only