DevSecOps · 6 min read · Log Academy training team
How to build security into a CI/CD pipeline
CI/CD security means building automated checks into every stage of your delivery pipeline. A practical rollout order: secret scanning first, then dependency analysis (SCA), then SAST, followed by container image minimisation and signing, and finally admission policies in Kubernetes. The key rule: every check must produce a result that is clear, explainable and fixable.
- The pipeline itself is a target: it holds secrets, production deploy rights and the artefacts you ship.
- Add checks from cheapest to most expensive: secret scanning, SCA, SAST, then containers and Kubernetes.
- Don't block everything on day one: start in observe mode, then block only new critical findings.
- A signed image and an admission policy work as a pair: only images your pipeline built reach the cluster.
- Every exception needs an owner, a reason and an expiry date.
- SLSA and NIST SSDF give you a shared language to explain what is checked and where.
What is CI/CD security, and why is the pipeline itself a target?
The job has two halves: checking the code the pipeline ships, and protecting the pipeline itself. The second half is often forgotten. Yet the build server holds cloud keys, registry passwords and the right to deploy to production. To an attacker, that is a more attractive target than the application.
The OWASP Top 10 CI/CD Security Risks list paints the picture well: insufficient flow control, dependency chain abuse, poisoned pipeline execution, poor credential hygiene and missing artefact integrity validation. In other words, pipeline security is not about installing one scanner — it is about defending the whole software supply chain. That makes it a core part of modern cybersecurity work.
In what order should you add security checks?
The most common mistake is switching on every tool in a single day. Hundreds of old findings surface at once, the build turns red and the team disables the check. Durable pipeline security starts with cheap, precise checks and moves forward in stages.
- Secret scanning: finds API keys, tokens and passwords committed to the repository. It is the cheapest and most valuable step — run it both before commit (pre-commit hook) and in the pipeline.
- Dependency analysis (SCA): flags known vulnerabilities (CVEs) and licence risks in the libraries you use. The fix is often just a version bump.
- SAST: looks for dangerous patterns such as SQL injection or unsafe deserialisation in your own code. It is noisier, so start with a small rule set and grow it gradually.
- Container image: minimal base image, non-root user, image scanning, SBOM and signature.
- Kubernetes admission policies: only workloads that follow the rules and carry a valid signature are allowed into the cluster.
| Check | What it catches | When it runs | Typical tools |
|---|---|---|---|
| Secret scanning | Keys, tokens and passwords left in code and git history | Before commit and on every push | Gitleaks, TruffleHog |
| SCA (dependency analysis) | Known vulnerabilities in libraries, licence risks | On every merge request and on a daily schedule | Trivy, OWASP Dependency-Check, Dependabot |
| SAST | Dangerous patterns in your own code | On every merge request, on changed files | Semgrep, SonarQube, CodeQL |
| Image scanning and signing | Vulnerabilities in the base image, unsigned artefacts | After build, before push to the registry | Trivy, Grype, Syft, cosign |
| Admission policy | Unsigned images, privileged containers, missing resource limits | At deploy time to the cluster | Kyverno, OPA Gatekeeper, ValidatingAdmissionPolicy |
What matters is the order, not the tool. The same logic works equally well in GitLab CI, GitHub Actions or Jenkins.
How do you shrink and sign a container image?
The fewer packages an image contains, the fewer vulnerabilities a scanner will find and the fewer tools an attacker can use. Use a multi-stage build to keep compilers out of the final image, choose a minimal or distroless base and run the container as a non-root user. Pin the base image by digest rather than by tag, so different content cannot arrive under the same name.
Signing comes next. With cosign from the Sigstore project, the image is signed after the build and an SBOM and build provenance are attached to it. Production can then answer the question “did our pipeline really build this image?” with evidence.
Which risks do Kubernetes admission policies close?
An admission controller is a mechanism that inspects a request to the Kubernetes API server before the object is persisted. A validating check rejects requests that break the rules, while a mutating one can modify them. This is exactly where the image signed in the pipeline gets verified.
- Allow only signed images from your own registry.
- Forbid privileged mode, hostPath and host networking.
- Require CPU and memory limits on every container.
- Reject the “latest” tag — accept only a specific version or digest.
Don't switch policies straight to enforce mode. Run them in audit mode first, see which existing workloads violate them, fix those, and only then move to blocking.
How do you triage findings so the team doesn't turn checks off?
Securing a pipeline usually fails for organisational rather than technical reasons. A check that blocks every build, explains nothing and is full of false positives gets disabled fast. This is the biggest point of friction between security teams and developers. A triage process prevents it.
- Create a baseline: move existing findings to a separate backlog and block only on newly introduced critical and high findings.
- Make every finding clear: which file, which line, why it is risky and how to fix it.
- Let developers mark a false positive in code with a reason — and review those marks regularly.
- Give exceptions an owner and an expiry date; an expired exception blocks the build again.
- Leaked secrets follow a separate rule: deleting them from code is not enough, rotate the key immediately.
Rule of thumb
A check should block the build only when a developer can read the result and fix it on their own. Otherwise it is seen as an obstacle and switched off at the first opportunity.
How do SLSA and NIST SSDF frame this work?
Tools change; frameworks stay. SLSA (Supply-chain Levels for Software Artifacts) describes how trustworthy a build process is in levels. In version 1.0, Build L1 requires that provenance exists, L2 that it is signed by a hosted build platform, and L3 that the build runs on a hardened, isolated platform.
NIST SP 800-218, the Secure Software Development Framework (SSDF), takes a broader view and groups practices into four areas: prepare the organisation, protect the software, produce well-secured software and respond to vulnerabilities. Mapping each pipeline check to one of these groups gives you a ready answer when an auditor asks “why is this step here?”.
How we do it in our lab
This is how we do it in our lab: every student gets their own virtual machine in a vSphere-based lab and, in the final project of the DevSecOps programme, builds a secure pipeline from scratch. Checks are added in the same order as in this article: secret scanning, dependency analysis, SAST, image hardening and signing, then Kubernetes policies. The project ends with the student's own audit of their pipeline: what is checked, which risk remains open, and why.
Frequently asked questions
- Which check should CI/CD security start with?
- Secret scanning. It is cheap, has few false positives and catches the most dangerous mistake — a key committed to the repository. Dependency analysis (SCA) and SAST come next.
- What is the difference between SAST and SCA?
- SAST analyses the code you wrote, while SCA matches the third-party libraries you use against databases of known vulnerabilities. One does not replace the other.
- When should a security check block the build?
- Only for newly introduced, clearly explained critical and high findings. Older findings go into a baseline and are fixed on a schedule; otherwise the team will disable the check.
- Why sign a container image?
- A signature proves the image was built by your pipeline and has not been altered since. Combined with a Kubernetes admission policy, it keeps unsigned images out of the cluster.
- How are these topics taught on the DevSecOps course?
- At Log Academy the DevSecOps programme runs for 6 months at intermediate level and is designed for developers, DevOps and systems engineers. It starts with Linux, Git and CI fundamentals, moves through code and dependency analysis, containers, Kubernetes and IaC, and ends with a final project.