chore(security): サプライチェーン対策の土台整備 + ロックファイル修復 - #41
Conversation
Establish supply-chain hardening foundation and unbreak `npm ci`: - Add .npmrc (root + functions) with ignore-scripts, save-exact, audit-level=high to mitigate npm ecosystem poisoning via install scripts. - Add .github/dependabot.yml for weekly npm (root, functions) and github-actions updates, grouping minor/patch to reduce PR noise. - Pin GitHub Actions to full commit SHAs (actions/checkout v6.0.3, actions/setup-node v6.4.0) for tamper resistance; Dependabot tracks updates. - Add `npm audit --audit-level=high` step to CI (non-blocking for now via `|| true`; to be enforced once vulnerabilities are resolved). - Re-sync root package-lock.json (semver 7.6.0 -> 7.8.2) which was out of sync with package.json and caused `npm ci` to fail under npm 11. Validated: `npm ci` and builds (CRA + functions tsc) succeed with ignore-scripts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe PR hardens the repository's supply chain security by introducing npm configuration for strict dependency installation policies, automating dependency updates through Dependabot, and enforcing security checks in CI/CD workflows via pinned GitHub Actions versions and runtime npm audit validation. ChangesSupply Chain Security & Dependency Hardening
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR (PR1/4 in the maintenance series) lays groundwork for supply-chain hardening and restores a consistent root lockfile so npm ci can succeed reliably (notably under newer npm versions).
Changes:
- Add
.npmrc(root +functions/) to harden installs (ignore-scripts,save-exact,audit-level). - Introduce weekly Dependabot updates for npm (root/functions) and GitHub Actions.
- Pin GitHub Actions to commit SHAs and add
npm audit --audit-level=high(non-blocking) to CI; resyncpackage-lock.jsonincludingsemverupdate.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
package-lock.json |
Resyncs lockfile; updates semver and related metadata to fix npm ci inconsistencies. |
functions/.npmrc |
Enables hardened npm defaults for Cloud Functions installs. |
.npmrc |
Enables hardened npm defaults for root installs. |
.github/workflows/ci-react.yml |
Pins actions to SHAs and adds a high-severity audit step in React CI. |
.github/workflows/ci-functions.yml |
Pins actions to SHAs and adds a high-severity audit step in Functions CI. |
.github/workflows/cd-firebase-testnet.yml |
Pins actions to SHAs for testnet CD workflow. |
.github/workflows/cd-firebase-mainnet.yml |
Pins actions to SHAs for mainnet CD workflow. |
.github/dependabot.yml |
Adds Dependabot configuration (npm + GitHub Actions) with weekly grouped updates. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | ||
| - name: Use Node.js ${{ matrix.node-version }} |
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | ||
| - name: Use Node.js ${{ matrix.node-version }} |
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | ||
| - name: Use Node.js ${{ matrix.node-version }} |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (2)
.github/workflows/cd-firebase-testnet.yml (1)
21-21: ⚡ Quick winConsider setting
persist-credentials: falsefor defense in depth.The
actions/checkoutstep persists GitHub credentials by default. Since this workflow runs on every push to main and executes npm scripts, addingpersist-credentials: falseprovides an additional security layer against credential exfiltration.🔒 Recommended security hardening
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/cd-firebase-testnet.yml at line 21, Update the GitHub Actions checkout step (the actions/checkout@... usage) to set persist-credentials: false so the runner does not retain repository credentials by default; locate the checkout step in the workflow and add the persist-credentials: false property under that step to harden credential exposure during npm/script execution.Source: Linters/SAST tools
.github/workflows/cd-firebase-mainnet.yml (1)
18-18: ⚡ Quick winConsider setting
persist-credentials: falsefor defense in depth.The
actions/checkoutstep persists GitHub credentials by default, which could be exfiltrated if malicious code executes in the workflow. While the.npmrcignore-scripts=truesetting mitigates script-based attacks, addingpersist-credentials: falseprovides an additional security layer.🔒 Recommended security hardening
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/cd-firebase-mainnet.yml at line 18, The checkout step using "actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10" currently persists GitHub credentials by default; update that step to set persist-credentials: false to avoid leaving tokens available to later workflow steps or third‑party code, e.g., add the persist-credentials: false input to the actions/checkout step so credentials are not automatically retained.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/cd-firebase-mainnet.yml:
- Around line 19-22: The step name is using the wrong matrix variable
"matrix.node-version" which is undefined; update the step name string "Use
Node.js ${{ matrix.node-version }}" to reference the actual matrix key
"matrix.node" so the step displays the selected Node version (the
actions/setup-node usage block and its with: node-version: ${{ matrix.node }}
stay unchanged).
- Around line 18-20: The pinned SHA for actions/checkout does not match the
v6.0.3 tag; update the uses entry for actions/checkout to either the correct tag
reference (actions/checkout@v6.0.3) or replace the current SHA with the actual
v6.0.3 commit SHA (9f698171ed81b15d1823a05fc7211befd50c8ae0) so the pinned
version and tag align; keep actions/setup-node as-is since its pinned SHA
already matches v6.4.0.
In @.github/workflows/cd-firebase-testnet.yml:
- Around line 22-25: The step name uses the wrong matrix variable
"matrix.node-version" causing an empty display; update the step name string "Use
Node.js ${{ matrix.node-version }}" to reference the defined matrix variable
"matrix.node" (i.e., "Use Node.js ${{ matrix.node }}") so the job name shows the
Node version correctly while leaving the actions/setup-node usage with with:
node-version unchanged.
In @.github/workflows/ci-functions.yml:
- Line 16: Update the actions/checkout usage to set persist-credentials: false
so the checkout step does not expose the GITHUB_TOKEN to untrusted PR workflows;
locate the actions/checkout@... step in the workflow (the line with "uses:
actions/checkout") and add the persist-credentials: false input under that step
to disable credential persistence for pull request runs.
In @.github/workflows/ci-react.yml:
- Around line 17-20: The step name currently uses the incorrect matrix variable
"matrix.node-version" (seen in the line 'name: Use Node.js ${{
matrix.node-version }}'); update that to use the actual matrix key "matrix.node"
so the step name reads 'Use Node.js ${{ matrix.node }}', leaving the rest of the
step (uses: actions/setup-node and with: node-version: ${{ matrix.node }})
unchanged.
- Line 16: Update the checkout step that uses "uses:
actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10" to include the
security option persist-credentials: false (i.e., add the persist-credentials:
false key under that checkout step) so PR workflows do not retain the
GITHUB_TOKEN and cannot exfiltrate credentials.
---
Nitpick comments:
In @.github/workflows/cd-firebase-mainnet.yml:
- Line 18: The checkout step using
"actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10" currently persists
GitHub credentials by default; update that step to set persist-credentials:
false to avoid leaving tokens available to later workflow steps or third‑party
code, e.g., add the persist-credentials: false input to the actions/checkout
step so credentials are not automatically retained.
In @.github/workflows/cd-firebase-testnet.yml:
- Line 21: Update the GitHub Actions checkout step (the actions/checkout@...
usage) to set persist-credentials: false so the runner does not retain
repository credentials by default; locate the checkout step in the workflow and
add the persist-credentials: false property under that step to harden credential
exposure during npm/script execution.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0dc4bb2f-dc01-4bdf-9d48-f1da1dbc170d
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (7)
.github/dependabot.yml.github/workflows/cd-firebase-mainnet.yml.github/workflows/cd-firebase-testnet.yml.github/workflows/ci-functions.yml.github/workflows/ci-react.yml.npmrcfunctions/.npmrc
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | ||
| - name: Use Node.js ${{ matrix.node-version }} | ||
| uses: actions/setup-node@v3 | ||
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify that the pinned SHAs correspond to the stated action versions
echo "Checking actions/checkout SHA..."
gh api repos/actions/checkout/commits/df4cb1c069e1874edd31b4311f1884172cec0e10 --jq '.commit.message' 2>&1 | head -5
echo -e "\nChecking if v6.0.3 tag exists and its SHA..."
gh api repos/actions/checkout/git/ref/tags/v6.0.3 --jq '.object.sha' 2>&1
echo -e "\nChecking actions/setup-node SHA..."
gh api repos/actions/setup-node/commits/48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e --jq '.commit.message' 2>&1 | head -5
echo -e "\nChecking if v6.4.0 tag exists and its SHA..."
gh api repos/actions/setup-node/git/ref/tags/v6.4.0 --jq '.object.sha' 2>&1Repository: nemtus/hackathon
Length of output: 480
Fix pinned action version mismatch in .github/workflows/cd-firebase-mainnet.yml (lines 18-20)
actions/checkout: pinneddf4cb1c069e1874edd31b4311f1884172cec0e10does not match thev6.0.3tag SHA (9f698171ed81b15d1823a05fc7211befd50c8ae0); update the pinned SHA or the referenced version.actions/setup-node: pinned48b55a011bda9f5d6aeb4c2d9c7362e8dae4041ematches thev6.4.0tag SHA.
🧰 Tools
🪛 actionlint (1.7.12)
[error] 19-19: property "node-version" is not defined in object type {node: string}
(expression)
🪛 zizmor (1.25.2)
[warning] 18-18: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/cd-firebase-mainnet.yml around lines 18 - 20, The pinned
SHA for actions/checkout does not match the v6.0.3 tag; update the uses entry
for actions/checkout to either the correct tag reference
(actions/checkout@v6.0.3) or replace the current SHA with the actual v6.0.3
commit SHA (9f698171ed81b15d1823a05fc7211befd50c8ae0) so the pinned version and
tag align; keep actions/setup-node as-is since its pinned SHA already matches
v6.4.0.
| - name: Use Node.js ${{ matrix.node-version }} | ||
| uses: actions/setup-node@v3 | ||
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | ||
| with: | ||
| node-version: ${{ matrix.node }} |
There was a problem hiding this comment.
Fix matrix variable reference in step name.
Line 19 references matrix.node-version, but the matrix only defines node (line 14). While this won't break the workflow since line 22 correctly uses matrix.node, the step name will display incorrectly as "Use Node.js " (empty string).
🔧 Proposed fix
- - name: Use Node.js ${{ matrix.node-version }}
+ - name: Use Node.js ${{ matrix.node }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Use Node.js ${{ matrix.node-version }} | |
| uses: actions/setup-node@v3 | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| - name: Use Node.js ${{ matrix.node }} | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: ${{ matrix.node }} |
🧰 Tools
🪛 actionlint (1.7.12)
[error] 19-19: property "node-version" is not defined in object type {node: string}
(expression)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/cd-firebase-mainnet.yml around lines 19 - 22, The step
name is using the wrong matrix variable "matrix.node-version" which is
undefined; update the step name string "Use Node.js ${{ matrix.node-version }}"
to reference the actual matrix key "matrix.node" so the step displays the
selected Node version (the actions/setup-node usage block and its with:
node-version: ${{ matrix.node }} stay unchanged).
Source: Linters/SAST tools
| - name: Use Node.js ${{ matrix.node-version }} | ||
| uses: actions/setup-node@v3 | ||
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | ||
| with: | ||
| node-version: ${{ matrix.node }} |
There was a problem hiding this comment.
Fix matrix variable reference in step name.
Line 22 references matrix.node-version, but the matrix only defines node (line 17). The step name will display incorrectly as "Use Node.js " (empty), though the workflow will function correctly since line 25 uses the correct variable.
🔧 Proposed fix
- - name: Use Node.js ${{ matrix.node-version }}
+ - name: Use Node.js ${{ matrix.node }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0🧰 Tools
🪛 actionlint (1.7.12)
[error] 22-22: property "node-version" is not defined in object type {node: string}
(expression)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/cd-firebase-testnet.yml around lines 22 - 25, The step
name uses the wrong matrix variable "matrix.node-version" causing an empty
display; update the step name string "Use Node.js ${{ matrix.node-version }}" to
reference the defined matrix variable "matrix.node" (i.e., "Use Node.js ${{
matrix.node }}") so the job name shows the Node version correctly while leaving
the actions/setup-node usage with with: node-version unchanged.
Source: Linters/SAST tools
| name: Node ${{ matrix.node }} CI Functions | ||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Set persist-credentials: false to protect against malicious PRs.
This workflow runs on pull requests from potentially untrusted contributors. Setting persist-credentials: false prevents malicious PRs from exfiltrating the GitHub token through modified workflow files or scripts.
🔒 Essential security fix for PR workflows
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 16-16: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ci-functions.yml at line 16, Update the actions/checkout
usage to set persist-credentials: false so the checkout step does not expose the
GITHUB_TOKEN to untrusted PR workflows; locate the actions/checkout@... step in
the workflow (the line with "uses: actions/checkout") and add the
persist-credentials: false input under that step to disable credential
persistence for pull request runs.
Source: Linters/SAST tools
| name: Node ${{ matrix.node }} CI React | ||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Set persist-credentials: false to protect against malicious PRs.
This workflow runs on pull requests from potentially untrusted contributors. Without persist-credentials: false, malicious PRs could exfiltrate the GitHub token through modified workflow files or scripts.
🔒 Essential security fix for PR workflows
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| with: | |
| persist-credentials: false |
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 16-16: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ci-react.yml at line 16, Update the checkout step that
uses "uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10" to
include the security option persist-credentials: false (i.e., add the
persist-credentials: false key under that checkout step) so PR workflows do not
retain the GITHUB_TOKEN and cannot exfiltrate credentials.
Source: Linters/SAST tools
| - name: Use Node.js ${{ matrix.node-version }} | ||
| uses: actions/setup-node@v3 | ||
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | ||
| with: | ||
| node-version: ${{ matrix.node }} |
There was a problem hiding this comment.
Fix matrix variable reference in step name.
Line 17 references matrix.node-version, but the matrix only defines node (line 12). While the workflow will function correctly since line 20 uses the correct variable, the step name will display as "Use Node.js " (empty).
🔧 Proposed fix
- - name: Use Node.js ${{ matrix.node-version }}
+ - name: Use Node.js ${{ matrix.node }}
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Use Node.js ${{ matrix.node-version }} | |
| uses: actions/setup-node@v3 | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| - name: Use Node.js ${{ matrix.node }} | |
| uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: ${{ matrix.node }} |
🧰 Tools
🪛 actionlint (1.7.12)
[error] 17-17: property "node-version" is not defined in object type {node: string}
(expression)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ci-react.yml around lines 17 - 20, The step name currently
uses the incorrect matrix variable "matrix.node-version" (seen in the line
'name: Use Node.js ${{ matrix.node-version }}'); update that to use the actual
matrix key "matrix.node" so the step name reads 'Use Node.js ${{ matrix.node
}}', leaving the rest of the step (uses: actions/setup-node and with:
node-version: ${{ matrix.node }}) unchanged.
Source: Linters/SAST tools
概要
メンテナンス再生作業の PR1/4。サプライチェーン対策の土台を整え、デプロイ不能の一因だった
npm ci失敗を解消します。変更内容
.npmrc(root + functions):ignore-scripts=true(インストールスクリプト経由のエコシステム汚染対策)/save-exact=true/audit-level=high.github/dependabot.yml: npm(root・functions)と github-actions を週次更新。minor/patch をグループ化actions/checkoutv6.0.3 /actions/setup-nodev6.4.0(改ざん耐性向上、以後は Dependabot が追従)npm audit --audit-level=highステップ追加(当面|| trueで可視化のみ。脆弱性解消後の PR4 で厳格化)package-lock.jsonの再同期(semver7.6.0→7.8.2)。package.json と不整合で npm 11 のnpm ciが失敗していたのを修復検証
npm ci(root / functions)が成功tsc(functions)を ignore-scripts 下で確認後続 PR
🤖 Generated with Claude Code
Summary by CodeRabbit