Skip to content

Commit c1cfd45

Browse files
authored
chore: enforce security hardening for GitHub Actions workflows (#10038)
* chore: set explicit workflow permissions defaults * chore: disable persisted checkout credentials * chore: centralize secure authenticated git push * chore: pin workflow actions to immutable SHAs * chore: group dependabot updates
1 parent fe768c9 commit c1cfd45

26 files changed

+179
-95
lines changed

.github/dependabot.yml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,21 @@ updates:
66
schedule:
77
interval: 'daily'
88
open-pull-requests-limit: 10
9+
groups:
10+
composer-dependencies:
11+
patterns:
12+
- '*'
913

1014
- package-ecosystem: 'github-actions'
11-
directory: '/'
15+
directories:
16+
- '/'
17+
- '/admin/framework'
18+
- '/admin/starter'
19+
- '/admin/userguide'
1220
schedule:
1321
interval: 'daily'
14-
ignore:
15-
- dependency-name: '*'
16-
update-types:
17-
- 'version-update:semver-minor'
18-
- 'version-update:semver-patch'
22+
groups:
23+
github-actions:
24+
patterns:
25+
- '*'
26+
group-by: dependency-name

.github/scripts/deploy-appstarter

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ cp -Rf ${SOURCE}/admin/starter/. ./
3232
# Commit the changes
3333
git add .
3434
git commit -m "Release ${RELEASE}"
35-
git push
35+
bash ${SOURCE}/.github/scripts/secure-git-push https://github.com/codeigniter4/appstarter.git HEAD:master

.github/scripts/deploy-framework

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ cp -Rf ${SOURCE}/admin/starter/tests/. ./tests/
3434
# Commit the changes
3535
git add .
3636
git commit -m "Release ${RELEASE}"
37-
git push
37+
bash ${SOURCE}/.github/scripts/secure-git-push https://github.com/codeigniter4/framework.git HEAD:master

.github/scripts/deploy-userguide

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,4 @@ touch ${TARGET}/docs/.nojekyll
5858
# Commit the changes
5959
git add .
6060
git commit -m "Release ${RELEASE}"
61-
git push
61+
bash ${SOURCE}/.github/scripts/secure-git-push https://github.com/codeigniter4/userguide.git HEAD:master

.github/scripts/secure-git-push

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
if [[ $# -ne 2 ]]; then
6+
echo "Usage: secure-git-push <remote-url> <refspec>" >&2
7+
exit 1
8+
fi
9+
10+
if [[ -z "${PUSH_TOKEN:-}" ]]; then
11+
echo "PUSH_TOKEN is required" >&2
12+
exit 1
13+
fi
14+
15+
REMOTE_URL="$1"
16+
REFSPEC="$2"
17+
AUTH_HEADER="$(printf 'x-access-token:%s' "${PUSH_TOKEN}" | base64 | tr -d '\n')"
18+
19+
echo "::add-mask::${AUTH_HEADER}"
20+
git -c http.https://github.com/.extraheader="AUTHORIZATION: basic ${AUTH_HEADER}" push "${REMOTE_URL}" "${REFSPEC}"
21+
22+
unset AUTH_HEADER PUSH_TOKEN

.github/workflows/deploy-apidocs.yml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,21 @@ jobs:
2929
git config --global user.name "${GITHUB_ACTOR}"
3030
3131
- name: Checkout source
32-
uses: actions/checkout@v6
32+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3333
with:
3434
path: source
35+
persist-credentials: false
3536

3637
- name: Checkout target
37-
uses: actions/checkout@v6
38+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3839
with:
3940
repository: codeigniter4/api
4041
token: ${{ secrets.ACCESS_TOKEN }}
4142
path: api
43+
persist-credentials: false
4244

4345
- name: Setup PHP
44-
uses: shivammathur/setup-php@v2
46+
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
4547
with:
4648
php-version: '8.2'
4749
tools: phive
@@ -66,9 +68,11 @@ jobs:
6668
6769
- name: Deploy to API repo
6870
working-directory: api
71+
env:
72+
PUSH_TOKEN: ${{ secrets.ACCESS_TOKEN }}
6973
run: |
7074
git add .
7175
if ! git diff-index --quiet HEAD; then
7276
git commit -m "Updated API for commit ${GITHUB_SHA}"
73-
git push origin master
77+
bash ${GITHUB_WORKSPACE}/.github/scripts/secure-git-push https://github.com/codeigniter4/api.git HEAD:master
7478
fi

.github/workflows/deploy-distributables.yml

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ jobs:
1616

1717
steps:
1818
- name: Checkout
19-
uses: actions/checkout@v6
19+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2020
with:
2121
fetch-depth: 0 # fetch all tags
22+
persist-credentials: false
2223

2324
- name: Get latest version
2425
id: version
@@ -49,25 +50,29 @@ jobs:
4950
git config --global user.name "${GITHUB_ACTOR}"
5051
5152
- name: Checkout source
52-
uses: actions/checkout@v6
53+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
5354
with:
5455
path: source
56+
persist-credentials: false
5557

5658
- name: Checkout target
57-
uses: actions/checkout@v6
59+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
5860
with:
5961
repository: codeigniter4/framework
6062
token: ${{ secrets.ACCESS_TOKEN }}
6163
path: framework
64+
persist-credentials: false
6265

6366
- name: Chmod
6467
run: chmod +x ./source/.github/scripts/deploy-framework
6568

6669
- name: Deploy
70+
env:
71+
PUSH_TOKEN: ${{ secrets.ACCESS_TOKEN }}
6772
run: ./source/.github/scripts/deploy-framework ${GITHUB_WORKSPACE}/source ${GITHUB_WORKSPACE}/framework ${GITHUB_REF##*/}
6873

6974
- name: Release
70-
uses: actions/github-script@v8
75+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
7176
with:
7277
github-token: ${{secrets.ACCESS_TOKEN}}
7378
script: |
@@ -99,25 +104,29 @@ jobs:
99104
git config --global user.name "${GITHUB_ACTOR}"
100105
101106
- name: Checkout source
102-
uses: actions/checkout@v6
107+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
103108
with:
104109
path: source
110+
persist-credentials: false
105111

106112
- name: Checkout target
107-
uses: actions/checkout@v6
113+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
108114
with:
109115
repository: codeigniter4/appstarter
110116
token: ${{ secrets.ACCESS_TOKEN }}
111117
path: appstarter
118+
persist-credentials: false
112119

113120
- name: Chmod
114121
run: chmod +x ./source/.github/scripts/deploy-appstarter
115122

116123
- name: Deploy
124+
env:
125+
PUSH_TOKEN: ${{ secrets.ACCESS_TOKEN }}
117126
run: ./source/.github/scripts/deploy-appstarter ${GITHUB_WORKSPACE}/source ${GITHUB_WORKSPACE}/appstarter ${GITHUB_REF##*/}
118127

119128
- name: Release
120-
uses: actions/github-script@v8
129+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
121130
with:
122131
github-token: ${{secrets.ACCESS_TOKEN}}
123132
script: |
@@ -149,19 +158,21 @@ jobs:
149158
git config --global user.name "${GITHUB_ACTOR}"
150159
151160
- name: Checkout source
152-
uses: actions/checkout@v6
161+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
153162
with:
154163
path: source
164+
persist-credentials: false
155165

156166
- name: Checkout target
157-
uses: actions/checkout@v6
167+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
158168
with:
159169
repository: codeigniter4/userguide
160170
token: ${{ secrets.ACCESS_TOKEN }}
161171
path: userguide
172+
persist-credentials: false
162173

163174
- name: Setup Python
164-
uses: actions/setup-python@v6
175+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
165176
with:
166177
python-version: '3.12'
167178

@@ -174,10 +185,12 @@ jobs:
174185
run: chmod +x ./source/.github/scripts/deploy-userguide
175186

176187
- name: Deploy
188+
env:
189+
PUSH_TOKEN: ${{ secrets.ACCESS_TOKEN }}
177190
run: ./source/.github/scripts/deploy-userguide ${GITHUB_WORKSPACE}/source ${GITHUB_WORKSPACE}/userguide ${GITHUB_REF##*/}
178191

179192
- name: Release
180-
uses: actions/github-script@v8
193+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
181194
with:
182195
github-token: ${{secrets.ACCESS_TOKEN}}
183196
script: |

.github/workflows/deploy-userguide-latest.yml

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,24 @@ jobs:
1919
build:
2020
name: Deploy to gh-pages
2121
permissions:
22-
# Allow ad-m/github-push-action to push commit to branch gh-pages
22+
# Allow push to branch gh-pages
2323
contents: write
2424
if: (github.repository == 'codeigniter4/CodeIgniter4')
2525
runs-on: ubuntu-24.04
2626
steps:
2727
- name: Checkout
28-
uses: actions/checkout@v6
28+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
29+
with:
30+
persist-credentials: false
2931

3032
- name: Setup PHP
31-
uses: shivammathur/setup-php@v2
33+
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # 2.36.0
3234
with:
3335
php-version: '8.2'
3436
coverage: none
3537

3638
- name: Setup Python
37-
uses: actions/setup-python@v6
39+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
3840
with:
3941
python-version: '3.12'
4042

@@ -57,7 +59,7 @@ jobs:
5759
5860
# Create an artifact of the html output
5961
- name: Upload artifact
60-
uses: actions/upload-artifact@v7
62+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
6163
with:
6264
name: HTML Documentation
6365
path: user_guide_src/build/html/
@@ -75,8 +77,7 @@ jobs:
7577
git commit -m "Update User Guide" -a || true
7678
7779
- name: Push changes
78-
uses: ad-m/github-push-action@v1.0.0
79-
with:
80-
branch: gh-pages
81-
directory: gh-pages
82-
github_token: ${{ secrets.ACCESS_TOKEN }}
80+
working-directory: gh-pages
81+
env:
82+
PUSH_TOKEN: ${{ secrets.ACCESS_TOKEN }}
83+
run: bash ${GITHUB_WORKSPACE}/.github/scripts/secure-git-push https://github.com/codeigniter4/CodeIgniter4.git HEAD:gh-pages

.github/workflows/label-add-conflict-all-pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
runs-on: ubuntu-24.04
1818
steps:
1919
- name: Checkout
20-
uses: actions/checkout@v6
20+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2121

2222
- name: Get PR List
2323
id: PR-list

.github/workflows/label-signing.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ jobs:
1919
runs-on: ubuntu-24.04
2020
steps:
2121
- name: Checkout
22-
uses: actions/checkout@v6
22+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2323

2424
- name: Check signed commits in PR
25-
uses: 1Password/check-signed-commits-action@v1
25+
uses: 1Password/check-signed-commits-action@ed2885f3ed2577a4f5d3c3fe895432a557d23d52 # v1.2.0
2626
with:
2727
comment: |
2828
You must GPG-sign your work, certifying that you either wrote the work or otherwise have the right to pass it on to an open-source project. See Developer's Certificate of Origin. See [signing][1].

0 commit comments

Comments
 (0)