Building Reliable CI/CD Pipelines with GitHub Actions
Build once, use short-lived identities, protect release gates, and verify the artifact you actually deploy.
Control identity, artifacts, secrets, and promotion policy along the path code already travels. A scanner report is not a security program.
Most delivery incidents that look like “security” are identity and promotion failures: a long-lived key, a workflow anyone can edit, a mutable tag, or a finding list with no owner. Adding another scanner after those are wrong will not help.
This guide uses a hypothetical GitHub Actions → OCI registry → Kubernetes path. It is educational, not a claim about a production program or a certification.
Pull requests can run unit tests, formatters, and dependency review without cloud credentials. The job that publishes an image or applies infrastructure should run from a protected branch or a GitHub Environment with reviewers, using an identity that cannot be assumed from a fork pull request.
# Educational workflow fragment. Pin actions by digest in high-risk repos.
name: publish
on:
push:
branches: [main]
permissions:
contents: read
id-token: write
jobs:
publish:
runs-on: ubuntu-latest
environment: staging
permissions:
contents: read
id-token: write
packages: write
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::111122223333:role/example-gha-ecr
aws-region: eu-west-1
- run: ./scripts/build-and-push.shid-token: write is required for OIDC. It is also a privilege: any step in that job can request a token. Keep the job small. The IAM role’s trust policy must restrict sub to the repository and environment, not repo:example/api:*.
OIDC is not secure merely because it is enabled. A trust policy that matches every ref in the repository is a stored key with extra steps.
Third-party Actions resolved by a moving tag can change under you. For workflows that deploy or handle secrets, pin by commit SHA. The same rule applies to base images: build FROM example@sha256:… or a lock file, not FROM node:latest.
An SBOM and provenance attestation help later incident response. They do not replace access review. Treat them as evidence, not as a pass/fail halo.
Build-time scans of dependencies and images catch issues when they are cheap to fix. Promotion policy decides what may enter staging and production.
A useful policy talks about exploitability and exposure, not every CVE:
# Educational gate sketch. Replace with your scanner's exit contract.
if [ "$CRITICAL_EXPLOITABLE_EXPOSED" -gt 0 ]; then
echo "promotion blocked: reachable critical finding"
exit 1
fiA gate that fails the build on every informational finding will be bypassed. A gate that never fails will not change behavior.
Secrets belong in a manager or an environment store, injected at runtime. They do not belong in Git, in echo debug steps, or in image layers.
A secrets scan that finds a token is the start of the incident. Revoke the credential, rotate dependents, and close the leak path (workflow log, forked PR, chat paste). A scanner checkbox without revocation is theatre.
The deploy role should push to one registry repository and reconcile one namespace—or apply one Terraform workspace—not administer the account. The application’s runtime identity (IRSA, workload identity) should be similarly narrow.
Admission policy can require non-root, known registries, and resource requests. Know whether a failed policy webhook fails open or closed; that choice is an availability decision.
sub and the trust policy, not only aws sts get-caller-identity after the fact.:latest tags in production manifests.Reliable GitHub Actions covers build-once promotion and verification. Multi-environment isolation covers the account and state boundaries those identities must not cross. See DevSecOps, DevOps & CI/CD, and the CI/CD lab.
Build once, use short-lived identities, protect release gates, and verify the artifact you actually deploy.
Isolate blast radius with accounts, identities, state, and promotion of the same artifact—not a shared admin role with three VPC names.
Understand readiness, surge capacity, graceful shutdown, and telemetry without treating rolling updates as an availability guarantee.