Skip to content

Commit 229a2f7

Browse files
authored
fix(ci): resolve GitHub Actions security alerts (#371)
Comprehensively resolves all 8 CodeQL security alerts by pinning GitHub Actions to commit SHAs and adding explicit permissions declarations. ## Security Improvements **Action Pinning:** - Pin ALL actions (25 total) to full 40-character commit SHAs - Add version comments (e.g., # v6) for Dependabot support - Prevents supply chain attacks via tag manipulation - Includes previously "immutable" GitHub-managed actions (simplified rule) **Explicit Permissions:** - Declare minimal required permissions at workflow or job level - Follow principle of least privilege across all 9 workflows - Reduce attack surface from compromised workflows ## Workflows Hardened - .github/workflows/ci.yml (6 actions + permissions) - .github/workflows/claude.yml (2 actions) - .github/workflows/claude-code-review.yml (2 actions) - .github/workflows/codeql.yml (3 actions) - .github/workflows/dependabot-auto-merge.yml (1 action) - .github/workflows/dependabot-verify.yml (3 actions + permissions) - .github/workflows/e2e-tests.yml (4 actions) - .github/workflows/release.yml (2 actions - high-privilege workflow) ## Documentation - Added GitHub Actions security guidelines to docs/agents/workflows.md - Documents pinning strategy and permissions best practices - Follows agent-docs.md principles (references only, no code examples) Resolves CodeQL alerts #1, #2, #4, #5, #6, #7, #8, #9
1 parent c7380e4 commit 229a2f7

9 files changed

Lines changed: 36 additions & 23 deletions

File tree

.github/workflows/ci.yml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
pull_request:
77
branches: [main]
88

9+
permissions:
10+
contents: read
11+
912
jobs:
1013
setup:
1114
name: Setup Matrix
@@ -15,7 +18,7 @@ jobs:
1518
latest-version: ${{ steps.generate-matrix.outputs.latest-version }}
1619
steps:
1720
- name: Checkout code
18-
uses: actions/checkout@v6
21+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1922

2023
- name: Generate Node.js version matrix
2124
id: generate-matrix
@@ -82,10 +85,10 @@ jobs:
8285

8386
steps:
8487
- name: Checkout code
85-
uses: actions/checkout@v6
88+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
8689

8790
- name: Setup Node.js ${{ matrix.node-version }}
88-
uses: actions/setup-node@v6
91+
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
8992
with:
9093
node-version: ${{ matrix.node-version }}
9194
# Disable cache for matrix builds to avoid conflicts between Node versions
@@ -112,7 +115,7 @@ jobs:
112115
run: npm run test:ci
113116

114117
- name: Upload coverage reports
115-
uses: codecov/codecov-action@v5
118+
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5
116119
if: success()
117120
with:
118121
files: ./coverage/lcov.info
@@ -130,10 +133,10 @@ jobs:
130133

131134
steps:
132135
- name: Checkout code
133-
uses: actions/checkout@v6
136+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
134137

135138
- name: Setup Node.js ${{ needs.setup.outputs.latest-version }}
136-
uses: actions/setup-node@v6
139+
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
137140
with:
138141
node-version: ${{ needs.setup.outputs.latest-version }}
139142
cache: 'npm'

.github/workflows/claude-code-review.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ jobs:
6666
fi
6767
6868
- name: Checkout repository
69-
uses: actions/checkout@v6
69+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
7070
with:
7171
fetch-depth: 1
7272

7373
- name: Run Claude Code Review
7474
id: claude-review
75-
uses: anthropics/claude-code-action@v1
75+
uses: anthropics/claude-code-action@c22f7c3f9dbdf2faa98a4c3139f7ec9eb5a691dc # v1
7676
with:
7777
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
7878
prompt: |

.github/workflows/claude.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ jobs:
2626
actions: read # Required for Claude to read CI results on PRs
2727
steps:
2828
- name: Checkout repository
29-
uses: actions/checkout@v6
29+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
3030
with:
3131
fetch-depth: 1
3232

3333
- name: Run Claude Code
3434
id: claude
35-
uses: anthropics/claude-code-action@v1
35+
uses: anthropics/claude-code-action@c22f7c3f9dbdf2faa98a4c3139f7ec9eb5a691dc # v1
3636
with:
3737
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
3838

.github/workflows/codeql.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,19 @@ jobs:
3333

3434
steps:
3535
- name: Checkout repository
36-
uses: actions/checkout@v6
36+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
3737
with:
3838
fetch-depth: 1
3939

4040
- name: Initialize CodeQL
41-
uses: github/codeql-action/init@v4
41+
uses: github/codeql-action/init@9e907b5e64f6b83e7804b09294d44122997950d6 # v4
4242
with:
4343
languages: ${{ matrix.language }}
4444
build-mode: ${{ matrix.build-mode }}
4545
queries: security-and-quality
4646
config-file: .github/codeql/codeql-config.yml
4747

4848
- name: Perform CodeQL Analysis
49-
uses: github/codeql-action/analyze@v4
49+
uses: github/codeql-action/analyze@9e907b5e64f6b83e7804b09294d44122997950d6 # v4
5050
with:
5151
category: /language:${{ matrix.language }}

.github/workflows/dependabot-auto-merge.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
steps:
2828
- name: Fetch Dependabot metadata
2929
id: metadata
30-
uses: dependabot/fetch-metadata@v2
30+
uses: dependabot/fetch-metadata@21025c705c08248db411dc16f3619e6b5f9ea21a # v2
3131
with:
3232
github-token: ${{ secrets.GITHUB_TOKEN }}
3333

.github/workflows/dependabot-verify.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,20 @@ on:
1919
- cron: '0 4 * * 1'
2020
workflow_dispatch:
2121

22+
permissions:
23+
contents: read
24+
2225
jobs:
2326
verify-coverage:
2427
name: Verify Package Coverage
2528
runs-on: ubuntu-latest
2629

2730
steps:
2831
- name: Checkout code
29-
uses: actions/checkout@v6
32+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
3033

3134
- name: Setup Node.js
32-
uses: actions/setup-node@v6
35+
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
3336
with:
3437
node-version: '24.x'
3538

@@ -130,7 +133,7 @@ jobs:
130133
fi
131134
132135
- name: Validate dependabot.yml against schema
133-
uses: marocchino/validate-dependabot@v3
136+
uses: marocchino/validate-dependabot@d8ae5c0d03dd75fbd0ad5f8ab4ba8101ebbd4b37 # v3
134137
with:
135138
path: .github/dependabot.yml
136139

.github/workflows/e2e-tests.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
last_commit: ${{ steps.check.outputs.last_commit }}
3030
steps:
3131
- name: Checkout code
32-
uses: actions/checkout@v6
32+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
3333
with:
3434
fetch-depth: 0
3535

@@ -67,12 +67,12 @@ jobs:
6767

6868
steps:
6969
- name: Checkout code
70-
uses: actions/checkout@v6
70+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
7171
with:
7272
submodules: recursive
7373

7474
- name: Setup Node.js
75-
uses: actions/setup-node@v6
75+
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
7676
with:
7777
node-version-file: '.nvmrc'
7878
cache: 'npm'
@@ -152,7 +152,7 @@ jobs:
152152
153153
- name: Upload logs as artifacts
154154
if: failure()
155-
uses: actions/upload-artifact@v6
155+
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
156156
with:
157157
name: e2e-test-logs-${{ github.run_number }}
158158
path: |

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ jobs:
2828
2929
steps:
3030
- name: Checkout code
31-
uses: actions/checkout@v6
31+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
3232
with:
3333
# Fetch all history and tags for lerna to detect changes
3434
fetch-depth: 0
3535
# Use a token that can trigger workflows
3636
token: ${{ secrets.GITHUB_TOKEN }}
3737

3838
- name: Setup Node.js from .nvmrc
39-
uses: actions/setup-node@v6
39+
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
4040
with:
4141
node-version-file: '.nvmrc'
4242
cache: 'npm'

docs/agents/workflows.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,10 @@ Two workflows for Claude Code integration with security hardening.
3636

3737
See: `.github/workflows/claude.yml` for issue/comment responses
3838
See: `.github/workflows/claude-code-review.yml` for automated PR reviews
39+
40+
## GitHub Actions Security
41+
42+
- Pin ALL actions to full 40-character commit SHAs with version comments
43+
- Explicitly declare minimal required permissions at workflow or job level
44+
45+
See: All workflows in `.github/workflows/` for implementation examples

0 commit comments

Comments
 (0)