Skip to content

Commit c3a37b8

Browse files
Harden security (#137)
* Add Zizmor as a pre-commit hook * Pin all reusable actions * Fix template injection, drop credential persistence * Address all other issues
1 parent 7470476 commit c3a37b8

File tree

7 files changed

+101
-45
lines changed

7 files changed

+101
-45
lines changed

.github/workflows/build.yml

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,23 @@ concurrency:
1010
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
1111
cancel-in-progress: true
1212

13+
permissions: {}
14+
1315
jobs:
1416
lint-and-test:
1517
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
name: "Lint and Test"
1621

1722
steps:
1823
- name: Checkout
19-
uses: actions/checkout@v4
24+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
25+
with:
26+
persist-credentials: false
2027

2128
- name: Base Setup
22-
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
29+
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@affc83be6020d529b9368cd4d63e467877606600 # v1
2330

2431
- name: Install dependencies
2532
run: python -m pip install -U "jupyterlab>=4.0.0,<5"
@@ -36,20 +43,23 @@ jobs:
3643
jlpm run test
3744
3845
build:
46+
name: Build JupyterLite extension
3947
runs-on: ubuntu-latest
4048

4149
steps:
4250
- name: Checkout
43-
uses: actions/checkout@v4
51+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
52+
with:
53+
persist-credentials: false
4454

4555
- name: Base Setup
46-
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
56+
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@affc83be6020d529b9368cd4d63e467877606600 # v1
4757

4858
- name: Install dependencies
4959
run: python -m pip install -U "jupyterlab>=4.0.0,<5"
5060

5161
- name: Restore Playwright browsers cache
52-
uses: actions/cache@v4
62+
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4
5363
with:
5464
path: /home/runner/.cache/ms-playwright
5565
key: playwright-browsers-${{ runner.os }}-v1
@@ -74,29 +84,35 @@ jobs:
7484
pip uninstall -y "jupytereverywhere" jupyterlab
7585
7686
- name: Upload extension packages
77-
uses: actions/upload-artifact@v4
87+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
7888
with:
7989
name: extension-artifacts
8090
path: dist/jupytereverywhere*
8191
if-no-files-found: error
8292

8393
lite:
94+
name: Build JupyterLite app
8495
needs: build
8596
runs-on: ubuntu-latest
97+
permissions:
98+
contents: read
99+
pull-requests: write
86100

87101
steps:
88102
- name: Checkout
89-
uses: actions/checkout@v4
103+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
104+
with:
105+
persist-credentials: false
90106

91107
- name: Setup Python
92-
uses: actions/setup-python@v5
108+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
93109
with:
94110
python-version: '3.11'
95111

96112
- name: Install micromamba
97113
uses: mamba-org/setup-micromamba@b09ef9b599704322748535812ca03efb2625677b # v2.0.5
98114

99-
- uses: actions/download-artifact@v4
115+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
100116
with:
101117
name: extension-artifacts
102118

@@ -123,14 +139,14 @@ jobs:
123139
jlpm build:all
124140
125141
- name: Upload artifact
126-
uses: actions/upload-artifact@v4
142+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
127143
with:
128144
name: lite-app
129145
path: ./dist
130146
if-no-files-found: error
131147

132148
- name: Upload GitHub Pages artifact
133-
uses: actions/upload-pages-artifact@v3
149+
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
134150
with:
135151
path: ./dist
136152

@@ -146,7 +162,7 @@ jobs:
146162
147163
148164
- name: Upload artifact
149-
uses: actions/upload-artifact@v4
165+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
150166
with:
151167
name: lite-app-test
152168
path: ./dist-test
@@ -168,6 +184,7 @@ jobs:
168184
echo 'Press ctrl + c to stop the server.' >> $GITHUB_STEP_SUMMARY
169185
170186
deploy:
187+
name: Deploy to GitHub Pages and Netlify
171188
needs: lite
172189
if: github.ref == 'refs/heads/main'
173190
permissions:
@@ -182,7 +199,7 @@ jobs:
182199
steps:
183200
- name: Deploy to GitHub Pages
184201
id: deployment
185-
uses: actions/deploy-pages@v4
202+
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
186203

187204
deploy-netlify:
188205
needs: lite
@@ -191,13 +208,13 @@ jobs:
191208
runs-on: ubuntu-latest
192209
steps:
193210
- name: Download lite app
194-
uses: actions/download-artifact@v4
211+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
195212
with:
196213
name: lite-app
197214
path: dist
198215

199216
- name: Publish to Netlify
200-
uses: netlify/actions/cli@3185065f4ab2f6df6f2ef41ee013626e1c02a426
217+
uses: netlify/actions/cli@3185065f4ab2f6df6f2ef41ee013626e1c02a426 # 3185065f4ab2f6df6f2ef41ee013626e1c02a426
201218
with:
202219
args: deploy --dir=dist --prod
203220
env:
@@ -206,16 +223,17 @@ jobs:
206223

207224

208225
test_isolated:
226+
name: Isolated extension test
209227
needs: build
210228
runs-on: ubuntu-latest
211229

212230
steps:
213231
- name: Install Python
214-
uses: actions/setup-python@v5
232+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
215233
with:
216234
python-version: '3.9'
217235
architecture: 'x64'
218-
- uses: actions/download-artifact@v4
236+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
219237
with:
220238
name: extension-artifacts
221239
- name: Install and Test
@@ -242,13 +260,15 @@ jobs:
242260

243261
steps:
244262
- name: Checkout
245-
uses: actions/checkout@v4
263+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
264+
with:
265+
persist-credentials: false
246266

247267
- name: Base Setup
248-
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
268+
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@affc83be6020d529b9368cd4d63e467877606600 # v1
249269

250270
- name: Download lite app (test mode)
251-
uses: actions/download-artifact@v4
271+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
252272
with:
253273
name: lite-app-test
254274
path: dist
@@ -266,7 +286,7 @@ jobs:
266286
run: jlpm install
267287

268288
- name: Set up browser cache
269-
uses: actions/cache@v4
289+
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4
270290
with:
271291
path: |
272292
${{ github.workspace }}/pw-browsers
@@ -283,7 +303,7 @@ jobs:
283303
284304
- name: Upload Playwright Test report
285305
if: always()
286-
uses: actions/upload-artifact@v4
306+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
287307
with:
288308
name: jupytereverywhere-playwright-tests
289309
path: |

.github/workflows/check-release.yml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,29 @@ concurrency:
99
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
1010
cancel-in-progress: true
1111

12+
permissions: {}
13+
1214
jobs:
1315
check_release:
16+
name: Check Release
1417
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
1520
steps:
1621
- name: Checkout
17-
uses: actions/checkout@v4
22+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
23+
with:
24+
persist-credentials: false
1825
- name: Base Setup
19-
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
26+
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@affc83be6020d529b9368cd4d63e467877606600 # v1
2027
- name: Check Release
21-
uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v2
28+
uses: jupyter-server/jupyter_releaser/.github/actions/check-release@6accaa3c07b69acaa1e14e00ba138133d8cbe879 # v2
2229
with:
2330
token: ${{ secrets.GITHUB_TOKEN }}
2431
steps_to_skip: build-changelog
2532

2633
- name: Upload Distributions
27-
uses: actions/upload-artifact@v4
34+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
2835
with:
2936
name: jupytereverywhere-releaser-dist-${{ github.run_number }}
3037
path: .jupyter_releaser_checkout/dist
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
name: Enforce PR label
22

3+
permissions: {}
4+
35
on:
46
pull_request:
57
types: [labeled, unlabeled, opened, edited, synchronize]
68
jobs:
79
enforce-label:
10+
name: Enforce labels on PRs
811
runs-on: ubuntu-latest
912
permissions:
1013
pull-requests: write
1114
steps:
1215
- name: enforce-triage-label
13-
uses: jupyterlab/maintainer-tools/.github/actions/enforce-label@v1
16+
uses: jupyterlab/maintainer-tools/.github/actions/enforce-label@affc83be6020d529b9368cd4d63e467877606600 # v1

.github/workflows/prep-release.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,21 @@ on:
2323
description: "Use PRs with activity since the last stable git tag"
2424
required: false
2525
type: boolean
26+
27+
permissions: {}
28+
2629
jobs:
2730
prep_release:
31+
name: "Prep Release"
2832
runs-on: ubuntu-latest
2933
permissions:
3034
contents: write
3135
steps:
32-
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
36+
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@affc83be6020d529b9368cd4d63e467877606600 # v1
3337

3438
- name: Prep Release
3539
id: prep-release
36-
uses: jupyter-server/jupyter_releaser/.github/actions/prep-release@v2
40+
uses: jupyter-server/jupyter_releaser/.github/actions/prep-release@6accaa3c07b69acaa1e14e00ba138133d8cbe879 # v2
3741
with:
3842
token: ${{ secrets.GITHUB_TOKEN }}
3943
version_spec: ${{ github.event.inputs.version_spec }}
@@ -45,4 +49,6 @@ jobs:
4549

4650
- name: "** Next Step **"
4751
run: |
48-
echo "Optional): Review Draft Release: ${{ steps.prep-release.outputs.release_url }}"
52+
echo "Optional): Review Draft Release: ${STEPS_PREP_RELEASE_OUTPUTS_RELEASE_URL}"
53+
env:
54+
STEPS_PREP_RELEASE_OUTPUTS_RELEASE_URL: ${{ steps.prep-release.outputs.release_url }}

.github/workflows/publish-release.yml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,28 @@ on:
1212
description: "Comma separated list of steps to skip"
1313
required: false
1414

15+
permissions: {}
16+
1517
jobs:
1618
publish_release:
19+
name: "Publish Release"
1720
runs-on: ubuntu-latest
1821
environment: release
1922
permissions:
23+
contents: write
2024
id-token: write
2125
steps:
22-
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
26+
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@affc83be6020d529b9368cd4d63e467877606600 # v1
2327

24-
- uses: actions/create-github-app-token@v1
28+
- uses: actions/create-github-app-token@d72941d797fd3113feb6b93fd0dec494b13a2547 # v1
2529
id: app-token
2630
with:
2731
app-id: ${{ vars.APP_ID }}
2832
private-key: ${{ secrets.APP_PRIVATE_KEY }}
2933

3034
- name: Populate Release
3135
id: populate-release
32-
uses: jupyter-server/jupyter_releaser/.github/actions/populate-release@v2
36+
uses: jupyter-server/jupyter_releaser/.github/actions/populate-release@6accaa3c07b69acaa1e14e00ba138133d8cbe879 # v2
3337
with:
3438
token: ${{ steps.app-token.outputs.token }}
3539
branch: ${{ github.event.inputs.branch }}
@@ -40,7 +44,7 @@ jobs:
4044
id: finalize-release
4145
env:
4246
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
43-
uses: jupyter-server/jupyter_releaser/.github/actions/finalize-release@v2
47+
uses: jupyter-server/jupyter_releaser/.github/actions/finalize-release@6accaa3c07b69acaa1e14e00ba138133d8cbe879 # v2
4448
with:
4549
token: ${{ steps.app-token.outputs.token }}
4650
release_url: ${{ steps.populate-release.outputs.release_url }}
@@ -49,10 +53,14 @@ jobs:
4953
if: ${{ success() }}
5054
run: |
5155
echo "Verify the final release"
52-
echo ${{ steps.finalize-release.outputs.release_url }}
56+
echo ${STEPS_FINALIZE_RELEASE_OUTPUTS_RELEASE_URL}
57+
env:
58+
STEPS_FINALIZE_RELEASE_OUTPUTS_RELEASE_URL: ${{ steps.finalize-release.outputs.release_url }}
5359

5460
- name: "** Failure Message **"
5561
if: ${{ failure() }}
5662
run: |
5763
echo "Failed to Publish the Draft Release Url:"
58-
echo ${{ steps.populate-release.outputs.release_url }}
64+
echo ${STEPS_POPULATE_RELEASE_OUTPUTS_RELEASE_URL}
65+
env:
66+
STEPS_POPULATE_RELEASE_OUTPUTS_RELEASE_URL: ${{ steps.populate-release.outputs.release_url }}

0 commit comments

Comments
 (0)