Skip to content

Commit 63888fc

Browse files
committed
docs(ci): enforce immutable SHA pinning for actions
Replace mutable version tags with commit SHA + comment pattern to prevent supply chain attacks via tag redirection. Signed-off-by: umatare5 <umatare5@gmail.com> AI-assisted-by: GitHub Copilot Coding Agent
1 parent f06cf0a commit 63888fc

1 file changed

Lines changed: 17 additions & 17 deletions

File tree

.github/instructions/github-actions-ci-cd-best-practices.instructions.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ jobs:
4747
artifact_path: ${{ steps.package_app.outputs.path }}
4848
steps:
4949
- name: Checkout code
50-
uses: actions/checkout@v4
50+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
5151
- name: Setup Node.js
52-
uses: actions/setup-node@v3
52+
uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 # v3.9.1
5353
with:
5454
node-version: 18
5555
- name: Install dependencies and build
@@ -62,7 +62,7 @@ jobs:
6262
zip -r dist.zip dist
6363
echo "path=dist.zip" >> "$GITHUB_OUTPUT"
6464
- name: Upload build artifact
65-
uses: actions/upload-artifact@v3
65+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
6666
with:
6767
name: my-app-build
6868
path: dist.zip
@@ -74,7 +74,7 @@ jobs:
7474
environment: staging
7575
steps:
7676
- name: Download build artifact
77-
uses: actions/download-artifact@v3
77+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
7878
with:
7979
name: my-app-build
8080
- name: Deploy to Staging
@@ -87,17 +87,17 @@ jobs:
8787
### **3. Steps and Actions**
8888
- **Principle:** Steps should be atomic, well-defined, and actions should be versioned for stability and security.
8989
- **Deeper Dive:**
90-
- **`uses`:** Referencing marketplace actions (e.g., `actions/checkout@v4`, `actions/setup-node@v3`) or custom actions. Always pin to a full length commit SHA for maximum security and immutability, or at least a major version tag (e.g., `@v4`). Avoid pinning to `main` or `latest`.
90+
- **`uses`:** Referencing marketplace actions (e.g., `actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2`) or custom actions. Always pin to a full-length commit SHA for maximum security and immutability. Tags and branches are mutable references — a malicious actor who gains write access to an action's repository can silently move a tag (e.g., `@v4`) to a compromised commit, executing arbitrary code in your workflow (a supply chain attack). A commit SHA is immutable and cannot be redirected. Add the version as a comment (e.g., `# v4.3.1`) for human readability. Avoid mutable references like `@main`, `@latest`, or major version tags (e.g., `@v4`).
9191
- **`name`:** Essential for clear logging and debugging. Make step names descriptive.
9292
- **`run`:** For executing shell commands. Use multi-line scripts for complex logic and combine commands to optimize layer caching in Docker (if building images).
9393
- **`env`:** Define environment variables at the step or job level. Do not hardcode sensitive data here.
9494
- **`with`:** Provide inputs to actions. Ensure all required inputs are present.
9595
- **Guidance for Copilot:**
96-
- Use `uses` to reference marketplace or custom actions, always specifying a secure version (tag or SHA).
96+
- Use `uses` to reference marketplace or custom actions, always pinning to an immutable commit SHA with a human-readable version comment (e.g., `uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2`). This is especially critical for third-party actions where you have no control over whether a tag gets moved.
9797
- Use `name` for each step for readability in logs and easier debugging.
9898
- Use `run` for shell commands, combining commands with `&&` for efficiency and using `|` for multi-line scripts.
9999
- Provide `with` inputs for actions explicitly, and use expressions (`${{ }}`) for dynamic values.
100-
- **Security Note:** Audit marketplace actions before use. Prefer actions from trusted sources (e.g., `actions/` organization) and review their source code if possible. Use `dependabot` for action version updates.
100+
- **Security Note:** Audit marketplace actions before use. Prefer actions from trusted sources (e.g., `actions/` organization) and review their source code if possible. Use `dependabot` for action version updates. **Never use mutable tag or branch references** (`@v4`, `@main`, `@latest`) — these are vulnerable to supply chain attacks where a compromised tag can execute malicious code in your CI/CD pipeline.
101101

102102
## Security Best Practices in GitHub Actions
103103

@@ -136,7 +136,7 @@ jobs:
136136
- **Federated Identity:** This is a key pattern for modern, secure cloud deployments.
137137
- **Guidance for Copilot:**
138138
- Strongly recommend OIDC for authenticating with AWS, Azure, GCP, and other cloud providers instead of storing long-lived access keys as secrets.
139-
- Provide examples of how to configure the OIDC action for common cloud providers (e.g., `aws-actions/configure-aws-credentials@v4`).
139+
- Provide examples of how to configure the OIDC action for common cloud providers (e.g., `aws-actions/configure-aws-credentials@<SHA> # v4.x.x`). Always pin to a full commit SHA.
140140
- Explain the concept of trust policies and how they relate to OIDC setup.
141141
- **Pro Tip:** OIDC is a fundamental shift towards more secure cloud deployments and should be prioritized whenever possible.
142142

@@ -162,7 +162,7 @@ jobs:
162162
permissions:
163163
contents: read # This job only needs to read code, override workflow default
164164
steps:
165-
- uses: actions/checkout@v4
165+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
166166
- run: npm run lint
167167
```
168168

@@ -219,13 +219,13 @@ jobs:
219219
- **Restore Keys:** Use `restore-keys` for fallbacks to older, compatible caches.
220220
- **Cache Scope:** Understand that caches are scoped to the repository and branch.
221221
- **Guidance for Copilot:**
222-
- Use `actions/cache@v3` for caching common package manager dependencies (Node.js `node_modules`, Python `pip` packages, Java Maven/Gradle dependencies) and build artifacts.
222+
- Use `actions/cache` (pinned to a full commit SHA) for caching common package manager dependencies (Node.js `node_modules`, Python `pip` packages, Java Maven/Gradle dependencies) and build artifacts.
223223
- Design highly effective cache keys using `hashFiles` to ensure optimal cache hit rates.
224224
- Advise on using `restore-keys` to gracefully fall back to previous caches.
225225
- **Example (Advanced Caching for Monorepo):**
226226
```yaml
227227
- name: Cache Node.js modules
228-
uses: actions/cache@v3
228+
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
229229
with:
230230
path: |
231231
~/.npm
@@ -259,8 +259,8 @@ jobs:
259259
node-version: [16.x, 18.x, 20.x]
260260
browser: [chromium, firefox]
261261
steps:
262-
- uses: actions/checkout@v4
263-
- uses: actions/setup-node@v3
262+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
263+
- uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 # v3.9.1
264264
with:
265265
node-version: ${{ matrix.node-version }}
266266
- name: Install Playwright browsers
@@ -289,7 +289,7 @@ jobs:
289289
- **`lfs`:** Manage Git LFS (Large File Storage) files efficiently. If not needed, set `lfs: false`.
290290
- **Partial Clones:** Consider using Git's partial clone feature (`--filter=blob:none` or `--filter=tree:0`) for extremely large repositories, though this is often handled by specialized actions or Git client configurations.
291291
- **Guidance for Copilot:**
292-
- Use `actions/checkout@v4` with `fetch-depth: 1` as the default for most build and test jobs to significantly save time and bandwidth.
292+
- Use `actions/checkout` (pinned to a full commit SHA, e.g., `actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1`) with `fetch-depth: 1` as the default for most build and test jobs to significantly save time and bandwidth.
293293
- Only use `fetch-depth: 0` if the workflow explicitly requires full Git history (e.g., for release tagging, deep commit analysis, or `git blame` operations).
294294
- Advise against checking out submodules (`submodules: false`) if not strictly necessary for the workflow's purpose.
295295
- Suggest optimizing LFS usage if large binary files are present in the repository.
@@ -303,7 +303,7 @@ jobs:
303303
- **Use Cases:** Build outputs (executables, compiled code, Docker images), test reports (JUnit XML, HTML reports), code coverage reports, security scan results, generated documentation, static website builds.
304304
- **Limitations:** Artifacts are immutable once uploaded. Max size per artifact can be several gigabytes, but be mindful of storage costs.
305305
- **Guidance for Copilot:**
306-
- Use `actions/upload-artifact@v3` and `actions/download-artifact@v3` to reliably pass large files between jobs within the same workflow or across different workflows, promoting modularity and efficiency.
306+
- Use `actions/upload-artifact` and `actions/download-artifact` (both pinned to full commit SHAs) to reliably pass large files between jobs within the same workflow or across different workflows, promoting modularity and efficiency.
307307
- Set appropriate `retention-days` for artifacts to manage storage costs and ensure old artifacts are pruned.
308308
- Advise on uploading test reports, coverage reports, and security scan results as artifacts for easy access, historical analysis, and integration with external reporting tools.
309309
- Suggest using artifacts to pass compiled binaries or packaged applications from a build job to a deployment job, ensuring the exact same artifact is deployed that was built and tested.
@@ -452,7 +452,7 @@ This checklist provides a granular set of criteria for reviewing GitHub Actions
452452
- Are `needs` dependencies correctly defined between jobs to ensure proper execution order?
453453
- Are `outputs` used efficiently for inter-job and inter-workflow communication?
454454
- Are `if` conditions used effectively for conditional job/step execution (e.g., environment-specific deployments, branch-specific actions)?
455-
- Are all `uses` actions securely versioned (pinned to a full commit SHA or specific major version tag like `@v4`)? Avoid `main` or `latest` tags.
455+
- Are all `uses` actions pinned to a full commit SHA with a human-readable version comment (e.g., `actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1`)? Tags (e.g., `@v4`) and branches (e.g., `@main`) are mutable and can be silently redirected to malicious commits — always use immutable SHA references, especially for third-party actions.
456456
- Are `run` commands efficient and clean (combined with `&&`, temporary files removed, multi-line scripts clearly formatted)?
457457
- Are environment variables (`env`) defined at the appropriate scope (workflow, job, step) and never hardcoded sensitive data?
458458
- Is `timeout-minutes` set for long-running jobs to prevent hung workflows?
@@ -604,4 +604,4 @@ GitHub Actions is a powerful and flexible platform for automating your software
604604

605605
---
606606

607-
<!-- End of GitHub Actions CI/CD Best Practices Instructions -->
607+
<!-- End of GitHub Actions CI/CD Best Practices Instructions -->

0 commit comments

Comments
 (0)