Skip to content

ci: harden GitHub Actions workflows#50

Merged
flavorjones merged 7 commits intomainfrom
flavorjones/harden-github-actions
Mar 20, 2026
Merged

ci: harden GitHub Actions workflows#50
flavorjones merged 7 commits intomainfrom
flavorjones/harden-github-actions

Conversation

@flavorjones
Copy link
Copy Markdown
Member

Summary

  • Pin all actions to SHA hashes with version comments via pinact
  • Fix zizmor findings: artipacked, excessive-permissions, dependabot-cooldown
  • Move workflow-level permissions to per-job least-privilege grants with permissions: {} at workflow level
  • Add zizmor + actionlint CI job
  • Configure dependabot with weekly batching and 10-day cooldown on all ecosystems

Test plan

  • CI passes on this branch
  • Verify zizmor reports clean: zizmor .

- Add persist-credentials: false to all checkout steps (artipacked)
- Add permissions: {} at workflow level and contents: read per job (excessive-permissions)
- Add cooldown: default-days: 10 to all dependabot ecosystems (dependabot-cooldown)
Copilot AI review requested due to automatic review settings March 19, 2026 20:22
Copy link
Copy Markdown

Copilot AI left a comment

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 repository’s GitHub Actions and Dependabot configuration by pinning actions, tightening GITHUB_TOKEN permissions to least-privilege, and adding CI checks for workflow security/linting.

Changes:

  • Pin GitHub Actions to full commit SHAs and disable persisted checkout credentials.
  • Set workflow-level permissions: {} and grant per-job permissions.
  • Add a “GitHub Actions audit” job running actionlint and zizmor, and update Dependabot configuration (grouping/cooldown).

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

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

File Description
.github/workflows/ci.yml Pins actions by SHA, adds actionlint/zizmor job, and applies least-privilege job permissions.
.github/dependabot.yml Adds grouping for GitHub Actions updates and configures cooldown for update PRs.

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

lint:
runs-on: ubuntu-latest
permissions:
contents: read
Copy link

Copilot AI Mar 19, 2026

Choose a reason for hiding this comment

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

actions/cache typically requires actions: write permission on GITHUB_TOKEN to save/update caches. With workflow-level permissions: {} and only contents: read here, the cache step may fail with "Resource not accessible by integration". Consider granting actions: write for this job (keep contents: read).

Suggested change
contents: read
contents: read
actions: write

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

GitHub Actions cache works with the implicit runner credentials, not GITHUB_TOKEN permissions. The actions/cache permission mapping confirms it needs no token permissions. See the permission-mappings reference.

Comment on lines +83 to +84
permissions:
contents: read
Copy link

Copilot AI Mar 19, 2026

Choose a reason for hiding this comment

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

This job uses caching (via ruby/setup-ruby with bundler-cache: true, and also uploads artifacts on failure). With workflow-level permissions: {} and only contents: read granted here, cache/artifact steps can fail because they typically require actions: write on GITHUB_TOKEN. Consider adding actions: write to this job’s permissions.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Cache operations use implicit runner credentials, not GITHUB_TOKEN. contents: read is sufficient. The setup-ruby and actions/cache actions don't require additional permissions for caching.

Comment on lines +64 to +65
permissions:
contents: read
Copy link

Copilot AI Mar 19, 2026

Choose a reason for hiding this comment

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

This job enables bundler-cache: true in ruby/setup-ruby, which uses the GitHub Actions cache API. With only contents: read granted, the cache save step can fail under restricted GITHUB_TOKEN permissions. Consider adding actions: write to this job’s permissions.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Cache operations use implicit runner credentials, not GITHUB_TOKEN. contents: read is sufficient. The setup-ruby and actions/cache actions don't require additional permissions for caching.

Copilot AI review requested due to automatic review settings March 19, 2026 21:04
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


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

Comment on lines 3 to +15
- package-ecosystem: bundler
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
cooldown:
default-days: 10
- package-ecosystem: github-actions
directory: "/"
groups:
github-actions:
patterns:
- "*"
Copy link

Copilot AI Mar 19, 2026

Choose a reason for hiding this comment

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

PR description says dependabot is configured with “weekly batching … on all ecosystems”, but only the github-actions ecosystem is grouped. If batching is intended for bundler too, add a groups: section for the bundler entry (or adjust the PR description if bundler grouping is intentionally out of scope).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Batching is only configured for github-actions because that's the ecosystem that generates the most individual PRs (one per action update). Bundler updates are already naturally fewer.

@flavorjones flavorjones force-pushed the flavorjones/harden-github-actions branch from 3509588 to ff4f8bd Compare March 19, 2026 21:11
Add semver-major-days/semver-minor-days/semver-patch-days so low-risk
patches flow faster while major bumps get more soak time.
Install actionlint, shellcheck, and zizmor in bin/setup so developers
have the tools available. Run actionlint and zizmor as CI steps so
workflow issues are caught locally before pushing.
Copilot AI review requested due to automatic review settings March 20, 2026 15:15
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

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


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

Comment on lines +6 to +7
step "Lint: GitHub Actions (actionlint)", "actionlint"
step "Lint: GitHub Actions (zizmor)", "zizmor ."
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

These bin/ci steps invoke actionlint and zizmor as global executables, which will make bin/ci fail on machines where those tools aren’t installed (and bin/setup currently only installs them via brew/pacman). Consider either vendoring/wrapping them under bin/ (consistent with rubocop/brakeman), or adding a preflight check that prints a clear installation hint before running the steps.

Copilot uses AI. Check for mistakes.
Comment on lines +8 to +12
cooldown:
semver-major-days: 7
semver-minor-days: 3
semver-patch-days: 2
default-days: 7
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

PR description says “10-day cooldown on all ecosystems”, but the bundler entry sets default-days: 7 (and semver-specific values). Either update the bundler cooldown values to match the described 10-day policy, or adjust the PR description to reflect the actual configuration.

Copilot uses AI. Check for mistakes.
@flavorjones flavorjones merged commit 2bb2f5d into main Mar 20, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants