# Gha Workflow Hardening

> Use when creating or modifying GitHub Actions workflows. Focus on security hardening and least privilege. Do NOT change application code unless required for workflow correctness.

- Skill: `askaret/gha-workflow-hardening` (Agent Skill)
- Install (CLI): `npx skillmds@latest add askaret/gha-workflow-hardening`
- Raw SKILL.md: https://api.skillmd.com/api/skills/askaret/gha-workflow-hardening/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: askaret (https://skillmd.com/u/askaret)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/askaret/gha-workflow-hardening

---


Goals:
- Make workflows safer by default (least privilege, immutable dependencies, safe triggers)
- Reduce supply-chain risk (pin actions, restrict third-party actions)
- Prevent common GH Actions foot-guns (untrusted code execution, secret leaks, token over-scope)

Checklist:
1) Triggers & untrusted code
- Prefer `pull_request` for PR checks; avoid `pull_request_target` unless you fully understand the risks
- If `pull_request_target` is required:
  - Never checkout or execute untrusted PR code with elevated permissions
  - Run only trusted steps (labeling, commenting, policy checks) on base repo code
- For forks:
  - Avoid granting secrets; use `pull_request` + read-only token where possible
  - Consider `workflow_run` patterns for privileged post-merge actions

2) Permissions discipline (GITHUB_TOKEN)
- Set workflow-level `permissions:` to the minimum (often `contents: read`)
- Elevate per-job only when needed (e.g., `pull-requests: write`, `packages: write`, `id-token: write`)
- If using attestations: include `attestations: write` only for the job that attests

3) Immutable dependencies (pinning)
- Pin third-party actions to a full commit SHA (preferred immutable form)
- Prefer first-party `actions/*` and well-maintained verified publishers
- Avoid floating tags (`@v1`, `@main`) for third-party actions in security-sensitive workflows

4) Secret safety
- Never echo secrets; avoid `set -x` / verbose logging around secrets
- Use environments + required reviewers for production deploy secrets
- Prefer OIDC to cloud providers over long-lived cloud keys/secrets

5) Runner & execution hardening
- Add `timeout-minutes` to jobs (avoid hung runners)
- Use `concurrency` to cancel redundant runs on same ref where appropriate
- Use `defaults.run.shell: bash` and fail-fast practices in scripts (`set -euo pipefail` in multi-line steps)
- If using self-hosted runners: assume they are high-trust; isolate, patch, and prefer ephemeral runners for prod

6) Artifact & input trust
- Treat artifacts from PR workflows as untrusted unless produced and consumed within the same trust boundary
- Validate any external input: workflow_dispatch inputs, issue comments, PR titles/labels, etc.

7) Required security checks (when available)
- Add Dependency Review on PRs that modify dependencies
- Add CodeQL scanning for supported languages
- Ensure branch protection required checks match workflow/job names exactly

Finish with:
- A concise diff-style summary of what changed in the workflow(s)
- Final permissions table (workflow-level + per-job)
- Actions pinning changes (what got pinned and why)
- Any remaining risks or follow-ups (branch protection, env reviewers, secrets/OIDC setup)

