Skip to content

Commit d78ef4e

Browse files
ci(gha): fix zizmor security findings in workflows
Add zizmor linter step to the Tekton linter pipeline and a .github/zizmor.yml config to suppress false positives for e2e.yaml. Fix expression injection in container.yaml by replacing ${{ github.ref_name }} and ${{ github.ref }} with env vars in run scripts. Add persist-credentials: false to all checkout steps and minimal permissions blocks to e2e-tests and notify-slack jobs. Move secrets from $GITHUB_ENV writes to step-level env blocks and use step outputs instead of $GITHUB_ENV for smee URLs. Co-authored-by: Chmouel Boudjnah <chmouel@redhat.com> Signed-off-by: Akshay Pant <akpant@redhat.com>
1 parent 8c1e41e commit d78ef4e

File tree

4 files changed

+66
-13
lines changed

4 files changed

+66
-13
lines changed

.github/workflows/container.yaml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ jobs:
3737
steps:
3838
- name: Checkout repository
3939
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
40+
with:
41+
persist-credentials: false
4042

4143
- name: Set up Go
4244
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
@@ -50,13 +52,13 @@ jobs:
5052
run: |
5153
set -x
5254
releaseBranchFormat='release-v'
53-
if [[ ${{ github.ref_name }} == ${releaseBranchFormat}* ]]; then
54-
tag=v$(echo ${{ github.ref_name }}|sed "s,${releaseBranchFormat},,")
55-
elif [[ ${{ github.ref }} == refs/pull/* ]]; then
56-
tag=pr-$(echo ${{ github.ref }} | cut -c11-|sed 's,/merge,,')
55+
if [[ ${GITHUB_REF_NAME} == ${releaseBranchFormat}* ]]; then
56+
tag=v$(echo ${GITHUB_REF_NAME}|sed "s,${releaseBranchFormat},,")
57+
elif [[ ${GITHUB_REF} == refs/pull/* ]]; then
58+
tag=pr-$(echo ${GITHUB_REF} | cut -c11-|sed 's,/merge,,')
5759
else
5860
# Sanitize the tag by replacing invalid characters with hyphens
59-
tag=$(echo ${{ github.ref_name }}|sed 's,/merge,,' | sed 's,[/.],-,g')
61+
tag=$(echo ${GITHUB_REF_NAME}|sed 's,/merge,,' | sed 's,[/.],-,g')
6062
fi
6163
for image in ./cmd/*;do
6264
ko build -B -t "${tag}" --platform="${{ env.PLATFORMS }}" "${image}"

.github/workflows/e2e.yaml

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ jobs:
4141

4242
name: e2e tests
4343
runs-on: ubuntu-latest
44+
permissions:
45+
contents: read
46+
issues: write
47+
pull-requests: read
4448
strategy:
4549
fail-fast: false
4650
matrix:
@@ -125,6 +129,7 @@ jobs:
125129
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
126130
with:
127131
ref: ${{ inputs.target_ref || github.event.pull_request.head.sha || github.sha }}
132+
persist-credentials: false
128133

129134
- name: Check user permissions on PRs
130135
if: github.event_name == 'pull_request_target'
@@ -164,7 +169,7 @@ jobs:
164169
repo: chmouel/snazy
165170

166171
- name: Install minica
167-
run: |
172+
run: | # zizmor: ignore[github-env]
168173
go install github.com/jsha/minica@latest
169174
echo "${HOME}/go/bin" >> "$GITHUB_PATH"
170175
@@ -173,10 +178,13 @@ jobs:
173178
with:
174179
repository: openshift-pipelines/startpaac
175180
path: startpaac
181+
persist-credentials: false
176182

177183
- name: Run gosmee for main controller
184+
env:
185+
PYSMEE_URL: ${{ secrets.PYSMEE_URL }}
178186
run: |
179-
nohup gosmee client --saveDir /tmp/gosmee-replay ${{ secrets.PYSMEE_URL }} "https://${CONTROLLER_DOMAIN_URL}" > /tmp/gosmee-main.log 2>&1 &
187+
nohup gosmee client --saveDir /tmp/gosmee-replay "${PYSMEE_URL}" "https://${CONTROLLER_DOMAIN_URL}" > /tmp/gosmee-main.log 2>&1 &
180188
181189
- name: Generate unique gosmee URL for Gitea tests
182190
if: startsWith(matrix.provider, 'gitea') || matrix.provider == 'concurrency'
@@ -185,10 +193,11 @@ jobs:
185193
SMEE_URL=$(curl -s https://hook.pipelinesascode.com -o /dev/null -w '%{redirect_url}')
186194
echo "Generated unique smee URL: ${SMEE_URL}"
187195
echo "url=${SMEE_URL}" >> "$GITHUB_OUTPUT"
188-
echo "TEST_GITEA_SMEEURL=${SMEE_URL}" >> "$GITHUB_ENV"
189196
190197
- name: Run gosmee for main controller (Gitea)
191198
if: startsWith(matrix.provider, 'gitea') || matrix.provider == 'concurrency'
199+
env:
200+
TEST_GITEA_SMEEURL: ${{ steps.gosmee-url.outputs.url }}
192201
run: |
193202
nohup gosmee client --saveDir /tmp/gosmee-replay "${TEST_GITEA_SMEEURL}" "https://${CONTROLLER_DOMAIN_URL}" >> /tmp/gosmee-main.log 2>&1 &
194203
@@ -199,10 +208,11 @@ jobs:
199208
SMEE_URL=$(curl -s https://hook.pipelinesascode.com -o /dev/null -w '%{redirect_url}')
200209
echo "Generated unique GitLab smee URL: ${SMEE_URL}"
201210
echo "url=${SMEE_URL}" >> "$GITHUB_OUTPUT"
202-
echo "TEST_GITLAB_SMEEURL=${SMEE_URL}" >> "$GITHUB_ENV"
203211
204212
- name: Run gosmee for GitLab tests
205213
if: matrix.provider == 'gitlab_bitbucket'
214+
env:
215+
TEST_GITLAB_SMEEURL: ${{ steps.gosmee-gitlab-url.outputs.url }}
206216
run: |
207217
nohup gosmee client --saveDir /tmp/gosmee-replay-gitlab "${TEST_GITLAB_SMEEURL}" "https://${CONTROLLER_DOMAIN_URL}" >> /tmp/gosmee-gitlab.log 2>&1 &
208218
@@ -218,10 +228,11 @@ jobs:
218228
SMEE_URL=$(curl -s https://hook.pipelinesascode.com -o /dev/null -w '%{redirect_url}')
219229
echo "Generated unique GHE webhook smee URL: ${SMEE_URL}"
220230
echo "url=${SMEE_URL}" >> "$GITHUB_OUTPUT"
221-
echo "TEST_GITHUB_SECOND_WEBHOOK_SMEE_URL=${SMEE_URL}" >> "$GITHUB_ENV"
222231
223232
- name: Run gosmee for second controller GHE webhook
224233
if: startsWith(matrix.provider, 'github_ghe') || matrix.provider == 'concurrency'
234+
env:
235+
TEST_GITHUB_SECOND_WEBHOOK_SMEE_URL: ${{ steps.gosmee-ghe-webhook-url.outputs.url }}
225236
run: |
226237
nohup gosmee client --saveDir /tmp/gosmee-replay-ghe-webhook "${TEST_GITHUB_SECOND_WEBHOOK_SMEE_URL}" "https://ghe.paac-127-0-0-1.nip.io" >> /tmp/gosmee-ghe-webhook.log 2>&1 &
227238
@@ -267,7 +278,7 @@ jobs:
267278
TEST_GITLAB_API_URL: https://gitlab.com
268279
TEST_GITLAB_GROUP: pac-e2e-tests
269280
TEST_GITLAB_SECOND_GROUP: ${{ vars.TEST_GITLAB_SECOND_GROUP }}
270-
TEST_GITLAB_SMEEURL: ${{ env.TEST_GITLAB_SMEEURL }}
281+
TEST_GITLAB_SMEEURL: ${{ steps.gosmee-gitlab-url.outputs.url }}
271282
TEST_GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
272283
TEST_GITLAB_SECOND_TOKEN: ${{ secrets.TEST_GITLAB_SECOND_TOKEN }}
273284

@@ -298,16 +309,18 @@ jobs:
298309
- name: Start installing cluster with startpaac
299310
env:
300311
PAC_DIR: ${{ github.workspace }}
312+
VARS_APPLICATION_ID: ${{ vars.APPLICATION_ID }}
313+
VARS_TEST_GITHUB_SECOND_APPLICATION_ID: ${{ vars.TEST_GITHUB_SECOND_APPLICATION_ID }}
301314
run: |
302315
mkdir -p ~/secrets
303-
echo "${{ vars.APPLICATION_ID }}" > ~/secrets/github-application-id
316+
echo "${VARS_APPLICATION_ID}" > ~/secrets/github-application-id
304317
echo "${{ secrets.APP_PRIVATE_KEY }}" > ~/secrets/github-private-key
305318
echo "${{ secrets.WEBHOOK_SECRET }}" > ~/secrets/webhook.secret
306319
echo "${{ secrets.PYSMEE_URL }}" > ~/secrets/smee
307320
308321
309322
mkdir -p ~/secrets-second
310-
echo "${{ vars.TEST_GITHUB_SECOND_APPLICATION_ID }}" > ~/secrets-second/github-application-id
323+
echo "${VARS_TEST_GITHUB_SECOND_APPLICATION_ID}" > ~/secrets-second/github-application-id
311324
echo "${{ secrets.TEST_GITHUB_SECOND_PRIVATE_KEY }}" > ~/secrets-second/github-private-key
312325
echo "${{ secrets.TEST_GITHUB_SECOND_WEBHOOK_SECRET }}" > ~/secrets-second/webhook.secret
313326
echo "${{ secrets.TEST_GITHUB_SECOND_SMEE_URL }}" > ~/secrets-second/smee
@@ -393,10 +406,15 @@ jobs:
393406
notify-slack:
394407
name: Notify Slack on Failures
395408
runs-on: ubuntu-latest
409+
permissions:
410+
contents: read
411+
actions: read
396412
needs: [e2e-tests]
397413
if: ${{ always() && github.ref_name == 'main' && github.event_name == 'schedule' }}
398414
steps:
399415
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
416+
with:
417+
persist-credentials: false
400418
- name: Download all artifacts
401419
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
402420
with:

.github/zizmor.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
rules:
2+
# Secrets are gated by the ok-to-test permission check step which runs first.
3+
# Using GitHub Environments would require major workflow restructuring.
4+
secrets-outside-env:
5+
ignore:
6+
- e2e.yaml
7+
8+
# pull_request_target is required to access secrets for fork PRs.
9+
# The ok-to-test action runs as the first step and gates all subsequent steps.
10+
dangerous-triggers:
11+
ignore:
12+
- e2e.yaml

.tekton/linter.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,27 @@ spec:
263263
set -euxo pipefail
264264
yamllint -f parsable -c .yamllint $(find . -type f -regex ".*y[a]ml" -print)
265265
266+
- name: zizmor
267+
displayName: "GitHub Actions security linter"
268+
image: registry.access.redhat.com/ubi9/python-312
269+
workingDir: $(workspaces.source.path)
270+
env:
271+
- name: HUB_TOKEN
272+
valueFrom:
273+
secretKeyRef:
274+
name: "nightly-ci-github-hub-token"
275+
key: "hub-token"
276+
script: |
277+
set -euxo pipefail
278+
if uname -m | grep -q aarch64; then
279+
target=aarch64-unknown-linux-gnu
280+
else
281+
target=x86_64-unknown-linux-gnu
282+
fi
283+
version=$(curl -H "Authorization: Bearer ${HUB_TOKEN}" -L -s https://api.github.com/repos/zizmorcore/zizmor/releases/latest | python3 -c 'import sys, json; print(json.load(sys.stdin)["tag_name"])')
284+
curl -sH "Authorization: Bearer ${HUB_TOKEN}" -L "https://github.com/zizmorcore/zizmor/releases/download/${version}/zizmor-${target}.tar.gz" | tar -xz -C /tmp/ --strip-components=1 -f-
285+
/tmp/zizmor .github/workflows/
286+
266287
- name: ruff-lint
267288
displayName: "Python Linter (ruff)"
268289
image: registry.access.redhat.com/ubi9/python-312

0 commit comments

Comments
 (0)