mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-17 10:15:27 -04:00
ci: harden existing workflows for the security gate (#3498)
Pin actions to commit SHAs, set persist-credentials: false on every checkout, and scope token permissions to the jobs that use them. Suppress the two findings that are safe by design: the description bot's pull_request_target trigger (no fork code runs) and an intentional word-split in the docker manifest step. Clears actionlint and zizmor against dev so the blocking gate from #1314 can pass once both land.
This commit is contained in:
@@ -20,6 +20,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
||||||
with:
|
with:
|
||||||
python-version: "3.11"
|
python-version: "3.11"
|
||||||
@@ -31,6 +33,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||||
with:
|
with:
|
||||||
node-version: "20"
|
node-version: "20"
|
||||||
@@ -53,6 +57,7 @@ jobs:
|
|||||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
# Detect whether this PR only touches documentation files.
|
# Detect whether this PR only touches documentation files.
|
||||||
# If so, skip the expensive pytest run while still reporting a passing check.
|
# If so, skip the expensive pytest run while still reporting a passing check.
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ concurrency:
|
|||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
packages: write
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
REGISTRY: ghcr.io
|
REGISTRY: ghcr.io
|
||||||
@@ -32,6 +31,9 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
name: build (${{ matrix.arch }})
|
name: build (${{ matrix.arch }})
|
||||||
runs-on: ${{ matrix.runner }}
|
runs-on: ${{ matrix.runner }}
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -44,6 +46,8 @@ jobs:
|
|||||||
runner: ubuntu-24.04-arm
|
runner: ubuntu-24.04-arm
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
- name: Set up Buildx
|
- name: Set up Buildx
|
||||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
|
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
|
||||||
- name: Log in to GHCR
|
- name: Log in to GHCR
|
||||||
@@ -78,8 +82,13 @@ jobs:
|
|||||||
name: merge manifest + tag
|
name: merge manifest + tag
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
- name: Read APP_VERSION + short sha
|
- name: Read APP_VERSION + short sha
|
||||||
id: ver
|
id: ver
|
||||||
run: |
|
run: |
|
||||||
@@ -116,6 +125,8 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
tags=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")
|
tags=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON")
|
||||||
digests=$(printf "${REGISTRY}/${IMAGE_NAME}@sha256:%s " *)
|
digests=$(printf "${REGISTRY}/${IMAGE_NAME}@sha256:%s " *)
|
||||||
|
# word-splitting is intended: $tags and $digests each expand to multiple args
|
||||||
|
# shellcheck disable=SC2086
|
||||||
docker buildx imagetools create $tags $digests
|
docker buildx imagetools create $tags $digests
|
||||||
env:
|
env:
|
||||||
REGISTRY: ${{ env.REGISTRY }}
|
REGISTRY: ${{ env.REGISTRY }}
|
||||||
|
|||||||
@@ -14,10 +14,11 @@ jobs:
|
|||||||
# Skip bots (Dependabot, release-drafter, etc.)
|
# Skip bots (Dependabot, release-drafter, etc.)
|
||||||
if: ${{ github.event.issue.user.type != 'Bot' }}
|
if: ${{ github.event.issue.user.type != 'Bot' }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||||
with:
|
with:
|
||||||
sparse-checkout: .github/scripts
|
sparse-checkout: .github/scripts
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- uses: actions/github-script@v7
|
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||||
with:
|
with:
|
||||||
script: return require('./.github/scripts/check-issue-description.js')({github, context, core})
|
script: return require('./.github/scripts/check-issue-description.js')({github, context, core})
|
||||||
|
|||||||
@@ -1,26 +1,25 @@
|
|||||||
name: ci / PR checks
|
name: ci / PR checks
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request_target:
|
# pull_request_target runs in the base-repo context (has secrets) so the check
|
||||||
|
# works on fork PRs. Safe here: the checkout pins to the base branch (no fork
|
||||||
|
# code runs) and the scripts only read context.payload and call the GitHub API.
|
||||||
|
pull_request_target: # zizmor: ignore[dangerous-triggers]
|
||||||
types: [opened, edited, synchronize, reopened, ready_for_review]
|
types: [opened, edited, synchronize, reopened, ready_for_review]
|
||||||
|
|
||||||
# pull_request_target runs in the base-repo context (has secrets).
|
# Default-deny at the workflow level; each job opts into only the scopes it needs.
|
||||||
# The checkout below pins to the base branch so no fork code is executed.
|
# Note: modifying a PR's labels/comments needs pull-requests:write even though the
|
||||||
# The script only reads context.payload and calls the GitHub API.
|
# REST path is under /issues/{n}/...; issues:write alone returns 403 on PRs.
|
||||||
# Least privilege: contents:read for the base-ref checkout, pull-requests:write
|
permissions: {}
|
||||||
# to add/remove labels and post comments on PRs, and issues:write for the same
|
|
||||||
# on real issues. NOTE: modifying a *pull request's* labels/comments needs the
|
|
||||||
# `pull-requests` scope even though the REST path is under `/issues/{n}/...`;
|
|
||||||
# `issues:write` alone returns 403 on PRs.
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
issues: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-description:
|
check-description:
|
||||||
name: Check PR description
|
name: Check PR description
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: write
|
||||||
|
issues: write
|
||||||
# Skip bots: they open PRs programmatically and have their own process.
|
# Skip bots: they open PRs programmatically and have their own process.
|
||||||
if: github.event.pull_request.user.type != 'Bot'
|
if: github.event.pull_request.user.type != 'Bot'
|
||||||
steps:
|
steps:
|
||||||
@@ -28,6 +27,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
ref: ${{ github.base_ref }}
|
ref: ${{ github.base_ref }}
|
||||||
sparse-checkout: .github/scripts
|
sparse-checkout: .github/scripts
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||||
with:
|
with:
|
||||||
@@ -36,6 +36,7 @@ jobs:
|
|||||||
check-title:
|
check-title:
|
||||||
name: Check PR title (Conventional Commits)
|
name: Check PR title (Conventional Commits)
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions: {}
|
||||||
# Skip bots: they open PRs programmatically and have their own process.
|
# Skip bots: they open PRs programmatically and have their own process.
|
||||||
if: github.event.pull_request.user.type != 'Bot'
|
if: github.event.pull_request.user.type != 'Bot'
|
||||||
steps:
|
steps:
|
||||||
@@ -59,6 +60,9 @@ jobs:
|
|||||||
check-mergeable:
|
check-mergeable:
|
||||||
name: Flag unmergeable PRs
|
name: Flag unmergeable PRs
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
issues: write
|
||||||
# Skip bots: they open PRs programmatically and have their own process.
|
# Skip bots: they open PRs programmatically and have their own process.
|
||||||
if: github.event.pull_request.user.type != 'Bot'
|
if: github.event.pull_request.user.type != 'Bot'
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
Reference in New Issue
Block a user