Skip to content

Harden reusable workflow security#24

Open
darwinboersma wants to merge 3 commits into
mainfrom
dboersma/security-audit-fixes
Open

Harden reusable workflow security#24
darwinboersma wants to merge 3 commits into
mainfrom
dboersma/security-audit-fixes

Conversation

@darwinboersma

Copy link
Copy Markdown
Collaborator

Summary

  • inline the coverage-report enforcement instead of calling coverage-check@main, and pin remaining third-party Actions to immutable SHAs
  • remove the unpinned file-existence action, pin npm/Knip tool versions, and move publish pre-install commands before registry auth without eval
  • validate E2E environment names before deploy branch pushes and make raw CodeBuild log streaming opt-in
  • update docs for trusted publishing, pinned Knip usage, and production workflow pinning guidance

Validation

  • ./actionlint -color=false
  • uvx zizmor --format plain .
  • uvx --from detect-secrets detect-secrets scan --all-files --force-use-all-plugins
  • git diff --check
  • high-signal git history secret pattern scan

Follow-up

  • The repository ruleset/status-check enforcement finding is a GitHub admin setting, not a code change. This PR leaves a clean workflow security scan ready to use as a required check.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the security posture of the repo’s reusable GitHub Actions workflows by pinning third-party Action references, removing unsafe patterns (e.g., eval), tightening permissions, and inlining coverage enforcement logic to avoid mutable workflow/action refs.

Changes:

  • Pin third-party Actions to immutable commit SHAs and set explicit workflow/job permissions.
  • Inline PR coverage reporting + enforcement logic into coverage-report.yml (instead of calling coverage-check@main) and adjust related coverage artifact handling.
  • Improve workflow safety/operability: validate E2E environment names before deploy-branch pushes, make raw CodeBuild log streaming opt-in, and update docs/examples (trusted publishing + pinned Knip usage + pinning guidance).

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
coverage-check/action.yml Pins actions/upload-artifact to an immutable SHA for the composite action.
README.md Updates usage guidance (pinning), renames/updates workflow examples, documents pinned tool versions and trusted publishing.
.github/workflows/publish-npm-package.yml Pins Actions, adds minimal permissions, removes eval, and reorders pre-install setup ahead of registry auth.
.github/workflows/pr-title-checker.yml Adds explicit permissions and minor workflow metadata cleanup.
.github/workflows/knip.yml Pins Actions and pins Knip execution via npx knip@<version>.
.github/workflows/ghactionlint.yml Updates zizmor default version and pins checkout action; adds job name.
.github/workflows/e2e-codebuild.yml Adds environment validation before deploy pushes and makes CodeBuild log streaming opt-in.
.github/workflows/coverage-report.yml Pins Actions, adds scoped permissions, and inlines baseline download + PR comment + enforcement logic.
.github/workflows/ci.yml Adds a clearer job name for the ghactionlint reusable workflow job.
.github/workflows/check-links.yml Adds explicit permissions and a job name for consistency/minimal privilege.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +96 to +102
if command -v jq &> /dev/null; then
echo "jq already installed: $(jq --version)"
else
echo "Installing jq..."
ARCH=$(dpkg --print-architecture 2>/dev/null || echo amd64)
curl -sL -o /usr/local/bin/jq "https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-${ARCH}"
chmod +x /usr/local/bin/jq
Comment on lines +204 to +207
echo "$CHANGED_FILES" \
| grep -E "$SOURCE_FILE_PATTERN" \
| grep -vE "$SOURCE_FILE_EXCLUDE" \
| grep -vE '/index\.(ts|tsx)$' \
Comment on lines +126 to +139
- name: Validate environment
env:
TARGET_ENV: ${{ inputs.environment }}
run: |
set -euo pipefail
case "$TARGET_ENV" in
predev|predev2|predev3|predev4|predev5|predev6|predev7|predev8|dev|preuat)
;;
*)
echo "::error::Unknown environment: $TARGET_ENV"
exit 1
;;
esac

darwinboersma and others added 2 commits May 4, 2026 10:25
zizmor's ref-version-mismatch check was failing because the # v2
comments next to pinned SHAs resolve to v2.7.0 (lychee-action) and
v2.9.3 (vitest-coverage-report-action) respectively.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the `bash <(curl ...)` actionlint installer and the pipx/PyPI
zizmor installer with direct GitHub release downloads, each verified
against a pinned SHA-256. Both tools now run from local binaries with
no remote-script execution and no Python toolchain in the trust path.

New `actionlint_sha256` and `zizmor_sha256` workflow inputs default to
the hashes for the default versions; bumping a version requires
supplying the matching hash.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants