Skip to content

Commit ec459ea

Browse files
committed
Harden GitHub Actions pins and permissions
1 parent bdc6699 commit ec459ea

5 files changed

Lines changed: 62 additions & 22 deletions

File tree

.github/dependabot.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,7 @@ updates:
3030
- "ci"
3131
commit-message:
3232
prefix: "ci"
33+
groups:
34+
github-actions:
35+
patterns:
36+
- "*"

.github/workflows/auto-tag.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ jobs:
1010
tag:
1111
runs-on: ubuntu-latest
1212
permissions:
13-
contents: write
13+
contents: read
1414
steps:
15-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
15+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
1616
with:
1717
fetch-depth: 2
1818
persist-credentials: false

.github/workflows/ci.yml

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,23 @@ jobs:
1818
name: Check
1919
runs-on: ubuntu-latest
2020
steps:
21-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
22-
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # stable
21+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
22+
with:
23+
persist-credentials: false
24+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
2325
with:
2426
toolchain: stable
25-
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
27+
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
2628
- run: cargo check --all-targets
2729

2830
fmt:
2931
name: Format
3032
runs-on: ubuntu-latest
3133
steps:
32-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
33-
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # stable
34+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
35+
with:
36+
persist-credentials: false
37+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
3438
with:
3539
toolchain: stable
3640
components: rustfmt
@@ -40,12 +44,14 @@ jobs:
4044
name: Clippy
4145
runs-on: ubuntu-latest
4246
steps:
43-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
44-
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # stable
47+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
48+
with:
49+
persist-credentials: false
50+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
4551
with:
4652
toolchain: stable
4753
components: clippy
48-
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
54+
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
4955
- run: cargo clippy --all-targets -- -D warnings
5056

5157
test:
@@ -55,9 +61,11 @@ jobs:
5561
matrix:
5662
os: [ubuntu-latest, macos-latest, windows-latest]
5763
steps:
58-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
59-
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # stable
64+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
65+
with:
66+
persist-credentials: false
67+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
6068
with:
6169
toolchain: stable
62-
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
70+
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
6371
- run: cargo test --all-targets

.github/workflows/release.yml

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ env:
88
CARGO_TERM_COLOR: always
99

1010
permissions:
11-
contents: write
11+
contents: read
1212

1313
jobs:
1414
build:
@@ -34,14 +34,16 @@ jobs:
3434
runner: windows-latest
3535
archive: zip
3636
steps:
37-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
37+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
38+
with:
39+
persist-credentials: false
3840

39-
- uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # stable
41+
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
4042
with:
4143
toolchain: stable
4244
targets: ${{ matrix.target }}
4345

44-
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
46+
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
4547
with:
4648
key: ${{ matrix.target }}
4749

@@ -93,7 +95,7 @@ jobs:
9395
Compress-Archive -Path "dist/$package" -DestinationPath "$package.zip"
9496
9597
- name: Upload artifact
96-
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
98+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
9799
with:
98100
name: teams-${{ matrix.target }}
99101
path: teams-${{ github.ref_name }}-${{ matrix.target }}.*
@@ -102,11 +104,15 @@ jobs:
102104
name: Create Release
103105
needs: build
104106
runs-on: ubuntu-latest
107+
permissions:
108+
contents: write
105109
steps:
106-
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
110+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
111+
with:
112+
persist-credentials: false
107113

108114
- name: Download all artifacts
109-
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
115+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
110116
with:
111117
path: artifacts
112118
merge-multiple: true
@@ -118,7 +124,7 @@ jobs:
118124
cat checksums-sha256.txt
119125
120126
- name: Create GitHub Release
121-
uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2
127+
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
122128
with:
123129
generate_release_notes: true
124130
files: |
@@ -129,9 +135,10 @@ jobs:
129135
name: Update Homebrew Tap
130136
needs: release
131137
runs-on: ubuntu-latest
138+
permissions: {}
132139
steps:
133140
- name: Update homebrew formula
134-
uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3
141+
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1
135142
with:
136143
token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
137144
repository: osodevops/homebrew-tap

docs/release-readiness.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,27 @@ Known CI maintenance item as of 2026-06-04:
9494
- Update pinned actions used by CI/release before GitHub's June 16, 2026 Node 24 default switch.
9595
- Watch especially `actions/checkout`, `actions/upload-artifact`, `actions/download-artifact`, and `softprops/action-gh-release`.
9696

97+
## GitHub Actions supply-chain checklist
98+
99+
For every GitHub Actions dependency update:
100+
101+
1. Verify the owner and repository are unchanged.
102+
2. Verify the target tag exists in the official action repository.
103+
3. Resolve the tag to the underlying commit.
104+
4. Pin the workflow to the full 40-character commit SHA, not the tag.
105+
5. Keep the trailing version comment accurate, for example `# v7.0.1`.
106+
6. Check `action.yml` for the runtime. Prefer Node 24 compatible action versions.
107+
7. Read the release notes for behavior changes, new inputs, permission changes, or token handling changes.
108+
8. Keep workflow `permissions` at least privilege. Do not give write permissions to build/test jobs.
109+
9. Set `persist-credentials: false` on `actions/checkout` unless a later step explicitly needs checkout's persisted git credentials.
110+
10. Do not merge a Dependabot Actions PR if it changes the action owner/repository, points to a fork, removes SHA pinning, or leaves comments inconsistent with the reviewed version.
111+
112+
Preferred repository setting:
113+
114+
- Require actions and reusable workflows to be pinned to a full-length commit SHA at the repository or organization level.
115+
116+
Dependabot is configured to group GitHub Actions updates into one PR so the complete workflow supply-chain diff can be reviewed together.
117+
97118
## Commercial release blockers
98119

99120
These must be resolved before marketing this as production-ready for external customers:

0 commit comments

Comments
 (0)