Skip to content

Commit cba58c2

Browse files
authored
[SECURITY] Harden GitHub workflows (#346)
* chore: zizmor auto fixes Signed-off-by: John McCall <john@overturemaps.org> * Pin GitHub Actions and improve workflow permissions Update CI/CD workflows to pin actions to specific commit SHAs and tighten behavior. Added concurrency groups to avoid overlapping runs, adjusted permissions (including id-token for OIDC, pages, and super-linter-specific rights), and moved some job-level permissions into the jobs that need them. Replaced direct uses of expressions in shell strings with explicit env variables (e.g. PR_HEAD_SHA, GITHUB_EVENT_NUMBER) to avoid quoting issues, and updated several action references (checkout, setup-node, configure-pages, upload/download artifacts, deploy-pages, aws credentials, super-linter, etc.) to stable SHAs for reproducibility and security. Signed-off-by: John McCall <john@overturemaps.org> * Bump GitHub Actions versions in workflows Update action references across CI workflows to newer patch releases for stability and bug fixes: actions/checkout -> v6.0.2, actions/setup-node -> v6.3.0, aws-actions/configure-aws-credentials -> v6.1.0, and actions/download-artifact -> v8.0.1. Changes touch .github/workflows/lint.yml, production_deploy_documentation.yml, staging_deploy.yaml, and staging_deploy_cleanup.yaml. Signed-off-by: John McCall <john@overturemaps.org> * Update staging_deploy.yaml Signed-off-by: John McCall <john@overturemaps.org> * Update staging_deploy.yaml Signed-off-by: John McCall <john@overturemaps.org> --------- Signed-off-by: John McCall <john@overturemaps.org>
1 parent 2fa023d commit cba58c2

5 files changed

Lines changed: 75 additions & 38 deletions

File tree

.github/dependabot.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ updates:
1717
docusaurus:
1818
patterns:
1919
- "@docusaurus/*"
20+
cooldown:
21+
default-days: 7
2022

2123
# Maintain GitHub Actions dependencies
2224
- package-ecosystem: "github-actions"
@@ -29,3 +31,5 @@ updates:
2931
commit-message:
3032
prefix: "[CHORE](deps)"
3133
include: "scope"
34+
cooldown:
35+
default-days: 7

.github/workflows/lint.yml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,32 @@ on:
55
pull_request:
66
workflow_dispatch:
77

8+
concurrency:
9+
group: lint-${{ github.ref }}
10+
cancel-in-progress: true
11+
812
permissions:
913
contents: read
10-
packages: read
11-
issues: write
12-
pull-requests: write
13-
statuses: write
14+
packages: read # for reading GitHub Packages registry images used by super-linter
1415

1516
jobs:
1617
lint:
1718
name: Super-Linter
1819
runs-on: ubuntu-latest
20+
permissions:
21+
issues: write # for super-linter to create issue annotations
22+
pull-requests: write # for super-linter PR summary comments
23+
statuses: write # for super-linter commit status updates
1924
steps:
2025
- name: Checkout Repo
21-
uses: actions/checkout@v6
26+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2227
with:
2328
# Required for super-linter to detect changed files
2429
fetch-depth: 0
30+
persist-credentials: false
2531

2632
- name: Super-Linter
27-
uses: super-linter/super-linter/slim@v8.6.0
33+
uses: super-linter/super-linter/slim@9e863354e3ff62e0727d37183162c4a88873df41 # v8.6.0
2834
env:
2935
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3036
SAVE_SUPER_LINTER_SUMMARY: true

.github/workflows/production_deploy_documentation.yml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ on:
99
# Allow running from the actions tab
1010
workflow_dispatch:
1111

12+
concurrency:
13+
group: pages
14+
cancel-in-progress: false
15+
1216
permissions:
13-
id-token: write # required to use OIDC authentication
1417
contents: read # required to checkout the code from the repo
15-
pages: write # for actions/deploy-pages
1618

1719
jobs:
1820
build:
@@ -21,12 +23,13 @@ jobs:
2123
runs-on: ubuntu-latest
2224
steps:
2325
- name: Check out the docs repo
24-
uses: actions/checkout@v6
26+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
2527
with:
2628
fetch-depth: 0
29+
persist-credentials: false
2730

2831
- name: Set up Node.js
29-
uses: actions/setup-node@v6
32+
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
3033
with:
3134
node-version-file: package.json
3235

@@ -40,11 +43,11 @@ jobs:
4043
run: npm run build
4144

4245
- name: Setup Pages 🗂️
43-
uses: actions/configure-pages@v6
46+
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
4447

4548
- name: Upload static files as GH-Pages artifact 📦
4649
id: docs-website
47-
uses: actions/upload-pages-artifact@v4
50+
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
4851
with:
4952
path: build
5053

@@ -55,8 +58,11 @@ jobs:
5558
name: github-pages
5659
url: https://docs.overturemaps.org/
5760
runs-on: ubuntu-latest
61+
permissions:
62+
id-token: write # required for OIDC authentication with GitHub Pages
63+
pages: write # for actions/deploy-pages
5864

5965
steps:
6066
- name: Deploy to GitHub Pages 🚀
6167
id: docs-website
62-
uses: actions/deploy-pages@v5
68+
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0

.github/workflows/staging_deploy.yaml

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ concurrency:
1111
cancel-in-progress: true
1212

1313
permissions:
14-
id-token: write
1514
contents: read
16-
pull-requests: write
1715

1816
env:
1917
DOCS_PATH: docs
@@ -44,20 +42,22 @@ jobs:
4442
schema-ref: ${{ steps.schema-docs.outputs.schema-ref }}
4543
steps:
4644
- name: Check out the main docs repo repository and build.
47-
uses: actions/checkout@v6
45+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
46+
with:
47+
persist-credentials: false
4848

4949
- name: Set up Node.js
50-
uses: actions/setup-node@v6
50+
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
5151
with:
5252
node-version-file: 'package.json'
5353

54-
- uses: lowlydba/sustainable-npm@v3
54+
- uses: lowlydba/sustainable-npm@31d51025884f424f58f22e4e6578178bb4e79632 # v3.0.0
5555

5656
- run: npm ci --omit=dev
5757

5858
- name: Generate schema markdown docs
5959
id: schema-docs
60-
uses: OvertureMaps/workflows/.github/actions/generate-schema-docs@main
60+
uses: OvertureMaps/workflows/.github/actions/generate-schema-docs@faa3fa4bbe01d85dc2e2139ff1f74ce70feb7df9 # main -- zizmor: ignore[stale-action-refs]
6161
with:
6262
output-dir: ${{ github.workspace }}/docs/schema/reference
6363
schema-ref: 'dev' # Temporary until we feel confident in the generated schema sans human review, then should be 'main'
@@ -70,7 +70,7 @@ jobs:
7070
SCHEMA_PREVIEW: ${{ env.SCHEMA_PREVIEW }}
7171

7272
- name: Upload docs build as an artifact 📦
73-
uses: actions/upload-artifact@v7
73+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
7474
with:
7575
path: build
7676
name: build-artifact
@@ -83,14 +83,16 @@ jobs:
8383
needs: check-fork
8484
steps:
8585
- name: Check out the main docs repo repository and build.
86-
uses: actions/checkout@v6
86+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
87+
with:
88+
persist-credentials: false
8789

8890
- name: Set up Node.js
89-
uses: actions/setup-node@v6
91+
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
9092
with:
9193
node-version-file: 'package.json'
9294

93-
- uses: lowlydba/sustainable-npm@v3
95+
- uses: lowlydba/sustainable-npm@31d51025884f424f58f22e4e6578178bb4e79632 # v3.0.0
9496

9597
- run: npm ci --omit=dev
9698

@@ -102,7 +104,7 @@ jobs:
102104
SCHEMA_PREVIEW: ${{ env.SCHEMA_PREVIEW }}
103105

104106
- name: Upload docs build as an artifact 📦
105-
uses: actions/upload-artifact@v7
107+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
106108
with:
107109
path: build
108110
name: build-artifact-no-autogen
@@ -114,42 +116,51 @@ jobs:
114116
environment:
115117
name: staging
116118
url: ${{ env.STAGING_URL }}${{ env.PREVIEW_PATH }}/index.html
119+
permissions:
120+
id-token: write # for AWS OIDC authentication
121+
pull-requests: write # for posting staging preview PR comments
117122

118123
steps:
119124
- name: Configure AWS credentials 🔐
120-
uses: aws-actions/configure-aws-credentials@v6
125+
uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37 # v6.1.0
121126
with:
122127
role-to-assume: ${{ env.AWS_ROLE_ARN }}
123128
aws-region: ${{ env.AWS_REGION }}
124129

125130
- name: Download auto-gen artifact 📥
126-
uses: actions/download-artifact@v8
131+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
127132
with:
128133
name: build-artifact
129134
path: build-autogen
130135

131136
- name: Download repo schema artifact 📥
132-
uses: actions/download-artifact@v8
137+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
133138
with:
134139
name: build-artifact-no-autogen
135140
path: build-no-autogen
136141

137142
- name: Copy to S3
138143
run: |
139-
aws s3 sync --delete --quiet build-autogen s3://overture-managed-staging-usw2/gh-pages${{ env.PREVIEW_PATH }}/
140-
aws s3 sync --delete --quiet build-no-autogen s3://overture-managed-staging-usw2/gh-pages${{ env.PREVIEW_PATH_NO_AUTOGEN }}/
144+
aws s3 sync --delete --quiet build-autogen s3://overture-managed-staging-usw2/gh-pages${PREVIEW_PATH}/
145+
aws s3 sync --delete --quiet build-no-autogen s3://overture-managed-staging-usw2/gh-pages${PREVIEW_PATH_NO_AUTOGEN}/
141146
142147
- name: Bust the Cache
143148
run: |
144-
aws cloudfront create-invalidation --distribution-id E1KP2IN0H2RGGT --paths "${{ env.PREVIEW_PATH }}/*" "${{ env.PREVIEW_PATH_NO_AUTOGEN }}/*"
149+
aws cloudfront create-invalidation --distribution-id E1KP2IN0H2RGGT --paths "${PREVIEW_PATH}/*" "${PREVIEW_PATH_NO_AUTOGEN}/*"
145150
146151
- name: Gather metadata for PR comment
147152
id: deploy-metadata
148153
run: |
149154
echo "time=$(date -u +'%b %d, %Y %H:%M UTC')" >> $GITHUB_OUTPUT
150-
echo "short-sha=$(echo '${{ github.event.pull_request.head.sha }}' | cut -c1-7)" >> $GITHUB_OUTPUT
151-
echo "schema-ref-short=$(echo '${{ needs.build-auto-gen.outputs.schema-ref }}' | sed 's|refs/heads/||;s|refs/tags/||')" >> $GITHUB_OUTPUT
152-
echo "schema-short-sha=$(echo '${{ needs.build-auto-gen.outputs.schema-sha }}' | cut -c1-7)" >> $GITHUB_OUTPUT
155+
echo "short-sha=${PR_HEAD_SHA:0:7}" >> $GITHUB_OUTPUT
156+
schema_ref="${NEEDS_BUILD_AUTO_GEN_OUTPUTS_SCHEMA_REF#refs/heads/}"
157+
schema_ref="${schema_ref#refs/tags/}"
158+
echo "schema-ref-short=$schema_ref" >> $GITHUB_OUTPUT
159+
echo "schema-short-sha=${NEEDS_BUILD_AUTO_GEN_OUTPUTS_SCHEMA_SHA:0:7}" >> $GITHUB_OUTPUT
160+
env:
161+
NEEDS_BUILD_AUTO_GEN_OUTPUTS_SCHEMA_REF: ${{ needs.build-auto-gen.outputs.schema-ref }}
162+
NEEDS_BUILD_AUTO_GEN_OUTPUTS_SCHEMA_SHA: ${{ needs.build-auto-gen.outputs.schema-sha }}
163+
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
153164

154165
- name: Comment on PR
155166
uses: marocchino/sticky-pull-request-comment@d4d6b0936434b21bc8345ad45a440c5f7d2c40ff # v3.0.3

.github/workflows/staging_deploy_cleanup.yaml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ on:
66
pull_request:
77
types: [closed]
88

9+
concurrency:
10+
group: staging-cleanup-${{ github.event.number }}
11+
cancel-in-progress: true
12+
913
permissions:
1014
contents: read
1115

@@ -15,14 +19,14 @@ jobs:
1519
if: github.event.pull_request.head.repo.full_name == github.repository
1620
runs-on: ubuntu-slim
1721
permissions:
18-
id-token: write
22+
id-token: write # for AWS OIDC authentication
1923
env:
2024
AWS_ROLE_ARN: arn:aws:iam::763944545891:role/pages-staging-oidc-overturemaps
2125
AWS_REGION: us-west-2
2226

2327
steps:
2428
- name: Configure AWS credentials
25-
uses: aws-actions/configure-aws-credentials@v6
29+
uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37 # v6.1.0
2630
with:
2731
role-to-assume: ${{ env.AWS_ROLE_ARN }}
2832
aws-region: ${{ env.AWS_REGION }}
@@ -31,12 +35,18 @@ jobs:
3135
- name: Delete from S3
3236
run: |
3337
aws s3 rm --recursive \
34-
s3://overture-managed-staging-usw2/gh-pages/${{ github.event.repository.name }}/pr/${{ github.event.number }}/ || true
38+
s3://overture-managed-staging-usw2/gh-pages/${GITHUB_EVENT_REPOSITORY_NAME}/pr/${GITHUB_EVENT_NUMBER}/ || true
3539
aws s3 rm --recursive \
36-
s3://overture-managed-staging-usw2/gh-pages/${{ github.event.repository.name }}/pr/${{ github.event.number }}-no-autogen/ || true
40+
s3://overture-managed-staging-usw2/gh-pages/${GITHUB_EVENT_REPOSITORY_NAME}/pr/${GITHUB_EVENT_NUMBER}-no-autogen/ || true
41+
env:
42+
GITHUB_EVENT_REPOSITORY_NAME: ${{ github.event.repository.name }}
43+
GITHUB_EVENT_NUMBER: ${{ github.event.number }}
3744

3845
- name: Bust the cache
3946
run: |
4047
aws cloudfront create-invalidation \
4148
--distribution-id E1KP2IN0H2RGGT \
42-
--paths "/${{ github.event.repository.name }}/pr/${{ github.event.number }}/*" || true
49+
--paths "/${GITHUB_EVENT_REPOSITORY_NAME}/pr/${GITHUB_EVENT_NUMBER}/*" || true
50+
env:
51+
GITHUB_EVENT_REPOSITORY_NAME: ${{ github.event.repository.name }}
52+
GITHUB_EVENT_NUMBER: ${{ github.event.number }}

0 commit comments

Comments
 (0)