GitHub Actions
Rulesets, least-privilege GITHUB_TOKEN, CodeQL, dependency review, Trivy, artifact attestations, and environment-gated deploys to Azure with OIDC.
Secure SDLC field guide ยท CI/CD automation
Hands-on tutorials for building secure delivery pipelines on GitHub Actions, Azure DevOps and GitLab CI/CD. One reference pipeline, three platforms, and every security gate explained with working YAML.
The reference pipeline
Every platform tutorial builds this same pipeline. A change moves left to right. At each amber gate a failed check stops it, so nothing reaches production without passing the checks before it.
Pick your platform
Each tutorial starts with platform settings you change once, then builds the pipeline file by file. Every third-party action and image is pinned, and every example authenticates to the cloud with OIDC.
Rulesets, least-privilege GITHUB_TOKEN, CodeQL, dependency review, Trivy, artifact attestations, and environment-gated deploys to Azure with OIDC.
Organization lockdown, a required extends template, workload identity federation, Advanced Security tasks, Notation signing, and environments with approvals and checks.
Protected branches and variables, the job-token allowlist, built-in security templates, security policies, Sigstore keyless signing with id_tokens, and protected environments.
Principles
The platforms name things differently, but a secure pipeline makes the same six decisions everywhere. The tutorials show how each one is done.
A pipeline holds deploy rights to production. Protect its definition files with code owners, review changes to them like application code, and log who changed what.
Use OIDC workload identity federation. The job receives a short-lived token scoped to one repository, branch or environment, and nothing is left behind to leak.
Start every job's token at read-only or no access and grant only what that job needs. Scope service connections and runners to the projects that use them.
Reference actions by full commit SHA, templates by tag or SHA, and container images by digest. Let Dependabot or Renovate propose updates so pinning stays current.
Code from a pull request, especially from a fork, runs without secrets and without write tokens. Jobs that hold secrets only run on reviewed, protected branches.
A gate that cannot run counts as a failure. Exceptions are explicit, owned, and expire, so a dismissed finding comes back for review instead of disappearing.
Why the rules exist
Each of these attacks went through the build system rather than the application. Each one maps to a rule above.
Attackers planted an implant on the build servers that swapped source files during compilation. The resulting updates were signed and shipped through the normal channel to thousands of customers.
RuleTreat the pipeline as production. Isolate build machines and record provenance from a hardened builder.
A modified copy of a script that many pipelines downloaded and piped to bash sent the CI environment, including credentials, to an attacker for about two months before discovery.
RulePin everything you execute and verify checksums. Keep secrets out of jobs that do not need them.
The action's version tags were moved to a malicious commit that printed runner secrets into build logs. Workflows that referenced a tag ran it automatically; workflows pinned to a commit SHA did not.
RulePin to full commit SHAs and restrict which actions an organization allows.
With stolen credentials, attackers force-pushed 76 of 77 trivy-action tags and all setup-trivy tags, and published a malicious Trivy v0.69.4. A credential stealer ran before the real scan, so jobs still looked normal.
RuleSecurity tools are dependencies too. Pin them, enforce pinning by policy, and use short-lived credentials so a stolen token expires quickly.