GitHub Actions Security Hardening — What I Actually Use
GitHub Actions Security Hardening — What I Actually Use
GitHub Actions Security Hardening — What I Actually Use
I tightened my pipelines without slowing anyone down. This is the short list that stuck for me across personal projects and DevOps work.
What I Secured First
- OIDC to AWS/Azure/GCP (no long‑lived keys), least‑privilege roles
- Required reviews on workflow changes and branch protection on
main
- Dependency + secret scanning on every PR
Reusable Workflows That Helped
lint-test-build.yml
that app repos call withworkflow_call
plan.yml
for IaC PRs;apply.yml
onmain
with manual approval
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# .github/workflows/lint-test-build.yml (snippet)
permissions:
contents: read
id-token: write
on:
workflow_call:
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: pnpm i && pnpm lint && pnpm test && pnpm build
OIDC Role Examples (conceptual)
- AWS: role trust on
token.actions.githubusercontent.com
with conditions likerepo:owner/name
andref:refs/heads/main
- Azure/GCP: workload identity bindings with minimal scopes and short session lifetimes
1
2
3
4
# Example: minimal permissions in a job
permissions:
id-token: write
contents: read
What Broke (and How I Fixed It)
- Token audience mismatch → set
audience
explicitly on the cloud side - Excess default permissions → trim
permissions:
per job instead of repo‑wide - Secret sprawl → moved to OIDC + per‑env roles; kept only non‑cloud secrets in store
My Take
I think CI/CD can be good, but it comes with a lot of troubleshooting. I cannot tell you the amount of debugging I had to do 😅
This post is licensed under CC BY 4.0 by the author.