Skip to content

Commit 0735e2b

Browse files
committed
Improve security of GitHub Actions workflows
Signed-off-by: Caleb Xu <caxu@redhat.com>
1 parent 2423138 commit 0735e2b

File tree

9 files changed

+137
-52
lines changed

9 files changed

+137
-52
lines changed

.github/workflows/add-release-info-to-pyxis.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,12 @@ jobs:
4141
--key '${{ env.KEY_FILE_LOCATION }}' \
4242
--pass '${{ secrets.certificatePassword }}' \
4343
-H 'Content-Type: application/json' \
44-
-d '{"commit":"${{ inputs.commit }}","enabled_for_testing":true,"name":"github.com/redhat-openshift-ecosystem/openshift-preflight","version":"${{ inputs.tag }}"}' \
44+
-d ${DATA_PAYLOAD} \
4545
-X POST \
46-
'https://${{ inputs.host }}/v1/tools' | jq
46+
${PYXIS_ENDPOINT} | jq
47+
env:
48+
DATA_PAYLOAD: '{"commit":"${{ inputs.commit }}","enabled_for_testing":true,"name":"github.com/redhat-openshift-ecosystem/openshift-preflight","version":"${{ inputs.tag }}"}'
49+
PYXIS_ENDPOINT: 'https://${{ inputs.host }}/v1/tools'
4750

4851
- name: Cleanup
4952
if: always()

.github/workflows/build-main.yml

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ on:
66

77
env:
88
IMAGE_NAME: preflight
9-
9+
10+
permissions:
11+
contents: read
12+
1013
jobs:
1114
build-main:
1215
name: Build and push main snapshot images
@@ -16,21 +19,27 @@ jobs:
1619
platform: [linux]
1720
runs-on: ubuntu-latest
1821
steps:
19-
- uses: actions/checkout@v4
22+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
23+
with:
24+
persist-credentials: false
25+
2026
- name: Fetch latest release version
21-
uses: reloc8/action-latest-release-version@1.0.0
27+
uses: reloc8/action-latest-release-version@b8d6337f30390558e7874a044d6a3c1314314bab # 1.0.0
2228
id: fetch-latest-release
23-
- name: Set Env Tags
24-
run: echo RELEASE_TAG=${{ steps.fetch-latest-release.outputs.latest-release }} >> $GITHUB_ENV
25-
- name: set short sha
26-
run: echo SHA_SHORT=$(git rev-parse --short HEAD) >> $GITHUB_ENV
29+
30+
- name: Set release tag and short SHA
31+
run: |
32+
echo RELEASE_TAG=${RELEASE_TAG} >> $GITHUB_ENV
33+
echo SHA_SHORT=$(git rev-parse --short HEAD) >> $GITHUB_ENV
34+
env:
35+
RELEASE_TAG: ${{ steps.fetch-latest-release.outputs.latest-release }}
2736

2837
- name: Set up QEMU
29-
uses: docker/setup-qemu-action@v3
38+
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
3039

3140
- name: Build Image
3241
id: build-image
33-
uses: redhat-actions/buildah-build@v2
42+
uses: redhat-actions/buildah-build@7a95fa7ee0f02d552a32753e7414641a04307056 # v2.13
3443
with:
3544
image: ${{ secrets.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}
3645
tags: ${{ env.SHA_SHORT }}-${{ matrix.platform }}-${{ matrix.architecture }}
@@ -44,7 +53,7 @@ jobs:
4453
4554
- name: Push Image
4655
id: push-image
47-
uses: redhat-actions/push-to-registry@v2
56+
uses: redhat-actions/push-to-registry@5ed88d269cf581ea9ef6dd6806d01562096bee9c # v2.8
4857
with:
4958
image: ${{ env.IMAGE_NAME }}
5059
tags: ${{ env.SHA_SHORT }}-${{ matrix.platform }}-${{ matrix.architecture }}
@@ -53,7 +62,9 @@ jobs:
5362
password: ${{ secrets.REGISTRY_PASSWORD }}
5463

5564
- name: Print image url
56-
run: echo "Image pushed to ${{ steps.push-image.outputs.registry-paths }}"
65+
run: echo "Image pushed to ${REGISTRY_PATHS}"
66+
env:
67+
REGISTRY_PATHS: ${{ steps.push-image.outputs.registry-paths }}
5768

5869
outputs:
5970
imageName: ${{ env.IMAGE_NAME }}
@@ -62,13 +73,15 @@ jobs:
6273
build-coverage:
6374
runs-on: ubuntu-latest
6475
steps:
65-
- uses: actions/checkout@v4
76+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
77+
with:
78+
persist-credentials: false
6679

6780
- name: Install system deps
6881
run: 'sudo apt update && sudo apt install -y libgpgme-dev libbtrfs-dev libdevmapper-dev'
6982

7083
- name: Set up Go
71-
uses: actions/setup-go@v5
84+
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
7285
with:
7386
go-version-file: go.mod
7487

@@ -85,7 +98,7 @@ jobs:
8598
run: make cover
8699

87100
- name: Coveralls
88-
uses: coverallsapp/github-action@v2
101+
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6
89102
with:
90103
github-token: ${{ secrets.GITHUB_TOKEN }}
91104
file: coverage.out

.github/workflows/build-multiarch.yml

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,37 +55,49 @@ jobs:
5555

5656
# Authenticate to container image registry to push the image
5757
- name: Podman Login
58-
uses: redhat-actions/podman-login@v1
58+
uses: redhat-actions/podman-login@4934294ad0449894bcd1e9f191899d7292469603 # v1.7
5959
with:
6060
registry: ${{ secrets.registry }}
6161
username: ${{ secrets.user }}
6262
password: ${{ secrets.password }}
6363

6464
- name: Create and add to manifest
6565
run: |
66-
buildah manifest create ${{ inputs.name }}
67-
buildah manifest add ${{ inputs.name }} ${{ secrets.registry }}/${{ inputs.name }}:${{ inputs.tag }}-linux-amd64
68-
buildah manifest add ${{ inputs.name }} ${{ secrets.registry }}/${{ inputs.name }}:${{ inputs.tag }}-linux-ppc64le
69-
buildah manifest add ${{ inputs.name }} ${{ secrets.registry }}/${{ inputs.name }}:${{ inputs.tag }}-linux-arm64
70-
buildah manifest add ${{ inputs.name }} ${{ secrets.registry }}/${{ inputs.name }}:${{ inputs.tag }}-linux-s390x
66+
buildah manifest create ${INPUT_NAME}
67+
buildah manifest add ${INPUT_NAME} ${{ secrets.registry }}/${INPUT_NAME}:${INPUT_TAG}-linux-amd64
68+
buildah manifest add ${INPUT_NAME} ${{ secrets.registry }}/${INPUT_NAME}:${INPUT_TAG}-linux-ppc64le
69+
buildah manifest add ${INPUT_NAME} ${{ secrets.registry }}/${INPUT_NAME}:${INPUT_TAG}-linux-arm64
70+
buildah manifest add ${INPUT_NAME} ${{ secrets.registry }}/${INPUT_NAME}:${INPUT_TAG}-linux-s390x
71+
env:
72+
INPUT_NAME: ${{ inputs.name }}
73+
INPUT_TAG: ${{ inputs.tag }}
7174

7275
- name: Push manifest
7376
id: push-manifest
7477
run: |
75-
podman manifest push --digestfile imagedigest ${{ inputs.name }} ${{ secrets.registry }}/${{ inputs.name }}:${{ inputs.tag }} --all
78+
podman manifest push --digestfile imagedigest ${INPUT_NAME} ${{ secrets.registry }}/${INPUT_NAME}:${INPUT_TAG} --all
7679
echo "digest=$(cat imagedigest)" | tee -a $GITHUB_OUTPUT
80+
env:
81+
INPUT_NAME: ${{ inputs.name }}
82+
INPUT_TAG: ${{ inputs.tag }}
7783

7884
- name: Sign the published manifest
7985
# only sign if release is published, not for ghactions branch push
8086
# which is used for testing and development.
8187
if: ${{ inputs.sign == true && github.event.release && github.event.action == 'published' }}
8288
run: |
83-
cosign sign --yes --recursive ${{ secrets.registry }}/${{ inputs.name }}@${{ steps.push-manifest.outputs.digest }}
89+
cosign sign --yes --recursive ${{ secrets.registry }}/${INPUT_NAME}@${DIGEST}
90+
env:
91+
DIGEST: ${{ steps.push-manifest.outputs.digest }}
92+
INPUT_NAME: ${{ inputs.name }}
8493

8594
- name: Verify the image signature
8695
if: ${{ inputs.sign == true && github.event.release && github.event.action == 'published' }}
8796
run: |
8897
cosign verify \
89-
--certificate-identity https://github.com/${{ github.repository }}/.github/workflows/build-multiarch.yml@refs/tags/${{ inputs.tag }} \
98+
--certificate-identity https://github.com/${{ github.repository }}/.github/workflows/build-multiarch.yml@refs/tags/${INPUT_TAG} \
9099
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
91-
${{ secrets.registry }}/${{ inputs.name }}:${{ inputs.tag }}
100+
${{ secrets.registry }}/${INPUT_NAME}:${INPUT_TAG}
101+
env:
102+
INPUT_NAME: ${{ inputs.name }}
103+
INPUT_TAG: ${{ inputs.tag }}

.github/workflows/build-release.yml

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,23 @@ jobs:
1717
matrix:
1818
architecture: [amd64,ppc64le,arm64,s390x]
1919
platform: [linux]
20+
permissions:
21+
contents: read
2022
runs-on: ubuntu-latest
2123
steps:
22-
- uses: actions/checkout@v4
24+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
25+
with:
26+
persist-credentials: false
27+
2328
- name: Set Env Tags
2429
run: echo RELEASE_TAG=$(echo $GITHUB_REF | cut -d '/' -f 3) >> $GITHUB_ENV
2530

2631
- name: Set up QEMU
27-
uses: docker/setup-qemu-action@v3
32+
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
2833

2934
- name: Build Image
3035
id: build-image
31-
uses: redhat-actions/buildah-build@v2
36+
uses: redhat-actions/buildah-build@7a95fa7ee0f02d552a32753e7414641a04307056 # v2.13
3237
with:
3338
image: ${{ secrets.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}
3439
tags: ${{ env.RELEASE_TAG }}-${{ matrix.platform }}-${{ matrix.architecture }}
@@ -41,7 +46,7 @@ jobs:
4146
4247
- name: Push Image
4348
id: push-image
44-
uses: redhat-actions/push-to-registry@v2
49+
uses: redhat-actions/push-to-registry@5ed88d269cf581ea9ef6dd6806d01562096bee9c # v2.8
4550
with:
4651
image: ${{ env.IMAGE_NAME }}
4752
tags: ${{ env.RELEASE_TAG }}-${{ matrix.platform }}-${{ matrix.architecture }}
@@ -50,7 +55,9 @@ jobs:
5055
password: ${{ secrets.REGISTRY_PASSWORD }}
5156

5257
- name: Print image url
53-
run: echo "Image pushed to ${{ steps.push-image.outputs.registry-paths }}"
58+
run: echo "Image pushed to ${REGISTRY_PATHS}"
59+
env:
60+
REGISTRY_PATHS: ${{ steps.push-image.outputs.registry-paths }}
5461

5562
outputs:
5663
imageName: ${{ env.IMAGE_NAME }}
@@ -78,6 +85,10 @@ jobs:
7885
token: ${{ secrets.GITHUB_TOKEN }}
7986

8087
extract-assets:
88+
permissions:
89+
# Write access to contents is needed in order to upload
90+
# files to releases.
91+
contents: write
8192
needs: build-release
8293
uses: ./.github/workflows/release-artifacts.yml
8394
with:
@@ -90,6 +101,7 @@ jobs:
90101
token: ${{ secrets.GITHUB_TOKEN }}
91102

92103
add-release-info-to-pyxis:
104+
permissions: {}
93105
needs: [build-release, extract-assets]
94106
uses: ./.github/workflows/add-release-info-to-pyxis.yml
95107
if: "!github.event.release.prerelease"
@@ -103,6 +115,7 @@ jobs:
103115
certificatePassword: ${{ secrets.PREFLIGHT_RELEASE_PASSWORD }}
104116

105117
copy-to-rhisv:
118+
permissions: {}
106119
needs: [build-release, build-multiarch]
107120
uses: ./.github/workflows/copy-to-rhisv.yml
108121
with:
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Analyze GitHub Actions security
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
pull_request:
7+
branches: ["**"]
8+
9+
permissions: {}
10+
11+
jobs:
12+
zizmor:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
17+
with:
18+
persist-credentials: false
19+
20+
- name: Run zizmor
21+
uses: zizmorcore/zizmor-action@f52a838cfabf134edcbaa7c8b3677dde20045018 # v0.1.1
22+
with:
23+
advanced-security: false

.github/workflows/code-review.yml

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
name: Gemini AI Code Review
22

3-
on:
3+
# pull_request_target is needed to access the Gemini key and modify (set/remove labels, comment on)
4+
# the pull request.
5+
on: # zizmor: ignore[dangerous-triggers]
46
pull_request_target:
57
types: [opened, synchronize, reopened, labeled]
68

7-
permissions:
8-
contents: read
9-
pull-requests: write
10-
119
concurrency:
1210
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }}
1311
cancel-in-progress: true
@@ -18,18 +16,23 @@ jobs:
1816
outputs:
1917
should_run_review: ${{ steps.prep.outputs.should_run_review }}
2018
permissions:
19+
contents: read
2120
pull-requests: write
2221
steps:
2322
- name: Checkout repository
24-
uses: actions/checkout@v4
23+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
24+
with:
25+
persist-credentials: false
26+
2527
- name: Handle review label
2628
id: prep
2729
env:
2830
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2931
PR_NUMBER: ${{ github.event.pull_request.number }}
32+
LABEL_JSON: ${{ toJSON(github.event.pull_request.labels.*.name) }}
33+
EVENT_ACTION: ${{ github.event.action }}
3034
run: |
31-
HAS_LABEL=$(echo '${{ toJSON(github.event.pull_request.labels.*.name) }}' | jq 'any(. == "gemini-review")')
32-
EVENT_ACTION="${{ github.event.action }}"
35+
HAS_LABEL=$(jq -n 'env.LABEL_JSON | fromjson | any(. == "gemini-review")')
3336
3437
if [[ "$HAS_LABEL" == "true" && "$EVENT_ACTION" != "labeled" ]]; then
3538
echo "gemini-review label found on a '${EVENT_ACTION}' event. Removing label and skipping review."
@@ -47,15 +50,19 @@ jobs:
4750
runs-on: ubuntu-latest
4851
needs: [handle-label]
4952
if: needs.handle-label.outputs.should_run_review == 'true'
53+
permissions:
54+
contents: read
55+
pull-requests: write
5056
steps:
5157
- name: Checkout repository
5258
uses: actions/checkout@v4
5359
with:
5460
ref: refs/pull/${{ github.event.pull_request.number }}/merge
61+
persist-credentials: false
5562
fetch-depth: 0
5663

5764
- name: Gemini AI Code Review
58-
uses: sshnaidm/gemini-code-review-action@d4ccdaf0e2cad5cb79f80f6db07857c0e7fff28f
65+
uses: sshnaidm/gemini-code-review-action@d4ccdaf0e2cad5cb79f80f6db07857c0e7fff28f # v1
5966
with:
6067
gemini-key: ${{ secrets.GEMINI_API_KEY }}
6168
model: 'gemini-2.5-flash'

.github/workflows/copy-to-rhisv.yml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,24 @@ jobs:
2828
runs-on: ubuntu-latest
2929
steps:
3030
- name: Podman Login
31-
uses: redhat-actions/podman-login@v1
31+
uses: redhat-actions/podman-login@4934294ad0449894bcd1e9f191899d7292469603 # v1.7
3232
with:
33-
registry: ${{ secrets.destImageRegistry }}
33+
registry: ${DEST_IMAGE_REGISTRY}
3434
username: ${{ secrets.destRegistryUser }}
3535
password: ${{ secrets.destRegistryPassword }}
3636

3737
- name: Copy Images from Source to Dest
3838
id: skopeo-copy-image
3939
run: |
4040
skopeo -v
41-
skopeo copy --all --preserve-digests docker://${{ secrets.sourceImageRegistry }}/${{ inputs.sourceImageName }}:${{ inputs.sourceImageTag }}-linux-amd64 docker://${{ secrets.destImageRegistry }}/${{ inputs.destImageName }}:${{ inputs.sourceImageTag }}-linux-amd64
42-
skopeo copy --all --preserve-digests docker://${{ secrets.sourceImageRegistry }}/${{ inputs.sourceImageName }}:${{ inputs.sourceImageTag }}-linux-ppc64le docker://${{ secrets.destImageRegistry }}/${{ inputs.destImageName }}:${{ inputs.sourceImageTag }}-linux-ppc64le
43-
skopeo copy --all --preserve-digests docker://${{ secrets.sourceImageRegistry }}/${{ inputs.sourceImageName }}:${{ inputs.sourceImageTag }}-linux-arm64 docker://${{ secrets.destImageRegistry }}/${{ inputs.destImageName }}:${{ inputs.sourceImageTag }}-linux-arm64
44-
skopeo copy --all --preserve-digests docker://${{ secrets.sourceImageRegistry }}/${{ inputs.sourceImageName }}:${{ inputs.sourceImageTag }}-linux-s390x docker://${{ secrets.destImageRegistry }}/${{ inputs.destImageName }}:${{ inputs.sourceImageTag }}-linux-s390x
45-
skopeo copy --all --preserve-digests docker://${{ secrets.sourceImageRegistry }}/${{ inputs.sourceImageName }}:${{ inputs.sourceImageTag }} docker://${{ secrets.destImageRegistry }}/${{ inputs.destImageName }}:${{ inputs.sourceImageTag }}
41+
skopeo copy --all --preserve-digests docker://${SOURCE_IMAGE_REGISTRY}/${SOURCE_IMAGE_NAME}:${SOURCE_IMAGE_TAG}-linux-amd64 docker://${DEST_IMAGE_REGISTRY}/${DEST_IMAGE_NAME}:${SOURCE_IMAGE_TAG}-linux-amd64
42+
skopeo copy --all --preserve-digests docker://${SOURCE_IMAGE_REGISTRY}/${SOURCE_IMAGE_NAME}:${SOURCE_IMAGE_TAG}-linux-ppc64le docker://${DEST_IMAGE_REGISTRY}/${DEST_IMAGE_NAME}:${SOURCE_IMAGE_TAG}-linux-ppc64le
43+
skopeo copy --all --preserve-digests docker://${SOURCE_IMAGE_REGISTRY}/${SOURCE_IMAGE_NAME}:${SOURCE_IMAGE_TAG}-linux-arm64 docker://${DEST_IMAGE_REGISTRY}/${DEST_IMAGE_NAME}:${SOURCE_IMAGE_TAG}-linux-arm64
44+
skopeo copy --all --preserve-digests docker://${SOURCE_IMAGE_REGISTRY}/${SOURCE_IMAGE_NAME}:${SOURCE_IMAGE_TAG}-linux-s390x docker://${DEST_IMAGE_REGISTRY}/${DEST_IMAGE_NAME}:${SOURCE_IMAGE_TAG}-linux-s390x
45+
skopeo copy --all --preserve-digests docker://${SOURCE_IMAGE_REGISTRY}/${SOURCE_IMAGE_NAME}:${SOURCE_IMAGE_TAG} docker://${DEST_IMAGE_REGISTRY}/${DEST_IMAGE_NAME}:${SOURCE_IMAGE_TAG}
46+
env:
47+
SOURCE_IMAGE_REGISTRY: ${{ secrets.sourceImageRegistry }}
48+
SOURCE_IMAGE_NAME: ${{ inputs.sourceImageName }}
49+
SOURCE_IMAGE_TAG: ${{ inputs.sourceImageTag }}
50+
DEST_IMAGE_REGISTRY: ${{ secrets.destImageRegistry }}
51+
DEST_IMAGE_NAME: ${{ inputs.destImageName }}

.github/workflows/go.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@ on:
66
- main
77
- release-*
88

9+
permissions:
10+
contents: read
11+
912
jobs:
1013
build:
1114
runs-on: ubuntu-latest
1215
steps:
13-
- uses: actions/checkout@v4
16+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
17+
with:
18+
persist-credentials: false
1419

1520
- name: Install system deps
1621
run: 'sudo apt update && sudo apt install -y libgpgme-dev libbtrfs-dev libdevmapper-dev'
@@ -36,7 +41,7 @@ jobs:
3641
run: make cover
3742

3843
- name: Coveralls
39-
uses: coverallsapp/github-action@v2
44+
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b # v2.3.6
4045
with:
4146
github-token: ${{ secrets.GITHUB_TOKEN }}
4247
file: coverage.out

0 commit comments

Comments
 (0)