Why build security into the CI/CD pipeline rather than handle it afterward Traditional security often comes in at the end of the cycle, after deployment, when fixing a vulnerability becomes costly and blocking. Building security controls directly into the CI/CD pipeline, an approach called DevSecOps, radically changes this dynamic. Vulnerabilities are detected and fixed at the moment the code is written and committed, not weeks or months later. This drastically reduces the cost of fixes, because a developer who gets immediate feedback on a non-compliant dependency can fix it in minutes, whereas a vulnerability discovered in production may require emergency patches, cross-team coordination, and out-of-process deployments. From a compliance standpoint, building audits into the pipeline creates continuous, documented traceability of every change. Instead of relying on manual checks and retrospective reports, you have an automated record of who did what, when, and with which validated security controls. It also transforms the team culture: developers become responsible for the security of the code they write, rather than seeing it as a burden added by a third party at the end of the process. ## The three pillars of security in a CI/CD pipeline For pipeline security to be effective and practical, it rests on three interconnected pillars: detection, compliance, and audit. Detection concerns the automated scanning of artifacts at each stage (source code, dependencies, binaries). A pipeline must scan the code for dangerous patterns (via SAST, Static Application Security Testing), identify dependencies with known vulnerabilities (via composition analysis or SCA, Software Composition Analysis), and check container images to detect vulnerabilities or unauthorized artifacts (via image scanning). Compliance ensures that every change respects business and regulatory rules. This includes infrastructure-as-code (IaC) scanning, which validates that your Terraform or CloudFormation configuration respects AWS security best practices, secret access, and internal-standard compliance. Audit creates a written trail. Every stage of the pipeline must be traced: who triggered the deployment, which security controls were applied, which results were recorded, and was any rule waived or step bypassed? These three pillars are not isolated. A non-compliant Docker image (pillar 2) must be detected (pillar 1) and the gap documented (pillar 3) so that you can fix and audit it. ## Integrating SAST and SCA scans without creating bottlenecks SAST (Static Application Security Testing) and SCA (Software Composition Analysis) scans are the first automated barriers of a secure pipeline, but if misconfigured, they can paralyze delivery. A SAST scan analyzes the source code for dangerous patterns: SQL injections, hardcoded credentials, insufficient input validation, and so on. Popular tools include Semgrep, SonarQube, or Snyk Code. The common trap is enabling ALL the rules with a zero-tolerance threshold, which drowns the team in false positives and slows every commit. The good practice is to start with a set of critical rules (the vulnerabilities that are genuinely blocking for your context) and progressively expand. False positives must be easily suppressible via a code annotation (a comment, for example) so that developers do not learn to ignore legitimate alerts. An SCA scan examines the dependencies (npm, pip, Maven packages, and so on) and cross-checks each version against known-vulnerability databases (NVD, Snyk DB, and so on). Here too, the majority of alerts are often false positives: a dependency with a known CVE is not necessarily exploitable if your application does not use the vulnerable function. Stralya's approach is to integrate these scans in non-blocking mode initially (warning only), then progressively move to blocking mode once you have cleaned up the critical dependencies. Technically, the scans should run in parallel in the pipeline, not in sequence, so as not to multiply the delays. On AWS, this means using CodeBuild with several parallel jobs or delegating to an orchestrator like Jenkins with distributed agents. ## Infrastructure-as-code validation and secret management Your infrastructure (servers, databases, networks) is defined in code (Terraform, CloudFormation) that must be as secure as your application code. A common leak: forgetting to encrypt EBS volumes, forgetting to configure security groups with the most restrictive rules, or accidentally exposing an RDS database on the Internet. Tools like Checkov, Bridgecrew, or TerraformCloud/Sentinel scan your IaC before it is applied and block dangerous configurations. The pipeline must validate the IaC configuration both at code commit (in the CI phase) and at the time of the apply plan (terraform plan) with security gates. As for secrets (API keys, database credentials, SSL certificates), they must NEVER be stored in clear text in the code or in the pipeline. AWS offers AWS Secrets Manager and Parameter Store; a good practice is to reference secrets from the pipeline (for example, via a CodeBuild step that retrieves the secret from Parameter Store, rather than hardcoding the value). Secret scans (tools like Detect Secrets, Trivy, TruffleHog) must run on every commit to detect secrets accidentally committed and prevent the push. Combined with a GitHub/GitLab policy that scans pushes before they reach the protected branch, this creates a very effective double barrier. ## Container image scanning and registry management If you deploy containers (Docker), every image must be scanned before it reaches production. A malicious or misconfigured image can expose system vulnerabilities (obsolete OS version, dangerous C libraries, and so on) independently of the application code. AWS ECR (Elastic Container Registry) offers built-in image scanning; third-party tools like Trivy, Aqua, or Snyk offer more granular controls. The pipeline must scan the image after the Docker build, before the push to the registry. If critical vulnerabilities are detected, the pipeline rejects the image. Minor vulnerabilities can be tolerated with explicit approval. Beyond scanning, the registry must enforce image signing (Docker Content Trust or Notary on AWS) to guarantee that only images built by your authorized pipeline are deployed. Without signing, an attacker could inject a malicious image into the registry. Finally, scanned and approved images must be tagged traceably (e.g., tagged with the commit or build ID, never a floating latest tag in production), so that you can quickly trace which build introduced a problem and recall a compromised version. ## Audit and traceability: SBOM, logs, and compliance reporting Detection and compliance are only worth it if they are traced. An external auditor or a compliance officer (CISO) must be able to answer the question: on what date was this version of the application deployed, which security controls validated this deployment, and were there any approved exceptions? This requires a complete audit trail. SBOMs (Software Bill of Materials) are at the heart of this traceability. An SBOM is a file (JSON or XML format, e.g., CycloneDX) that lists all the components and dependencies of a build (which libraries, which versions, which patches applied). Generating an SBOM for each deployed artifact makes it possible not only to know exactly what is running in production, but also to react quickly if a vulnerability is discovered: instead of scanning all the code, you consult the SBOMs of the versions in place and instantly identify which ones are affected. AWS CodeBuild can generate SBOMs via Syft or other tools, and store them alongside the artifacts. Pipeline logs must capture every approval decision, every security-gate bypass, and every scan failure, with context (who, when, why). These logs must be centralized (CloudWatch Logs, Splunk, ELK) and immutable (long-term storage in S3 with versioning enabled and MFA Delete to prevent accidental deletion). Finally, compliance reports are generated automatically: for example, each month or at each release, a report aggregates the scans, the approvals, the security incidents, and the deployment compliance rate. These reports are essential for internal and external audits (SOC 2, ISO 27001) and for customer demonstrations. ## Rolling it out progressively: roadmap and key tools Transforming an existing pipeline to build in security is a marathon, not a sprint. A progressive approach avoids slowing the team down. Weeks 1-2: deploy the basics. Enable SAST and SCA scanning on new commits in warning mode (non-blocking). Choose a tool (Semgrep for SAST, Snyk or Dependabot for SCA). In parallel, configure the pipeline logs in CloudWatch. Weeks 3-4: infrastructure and secrets. Set up IaC scanning (Checkov integrated with terraform apply). Implement secret management (AWS Secrets Manager or Parameter Store). Block committed secrets via pre-commit hooks on the repositories. Month 2: containers and signing. If you use Docker, enable ECR image scanning and Docker Content Trust signing. Generate the first SBOMs. Month 3+: maturation and reporting. Move the SAST and SCA gates to blocking mode, with a transition period so the team can clean up the dependencies. Set up automated compliance reports. Integrate with your internal ticketing system (Jira, GitHub Issues) so that each non-blocking security alert creates an assigned remediation ticket. The key tools for an AWS team are AWS CodeBuild (orchestration), Snyk or Checkov (scanning), AWS Secrets Manager (secrets), ECR with signing (images), CloudWatch Logs (audit), and a central dashboard (Grafana or AWS CloudWatch Dashboard) for real-time visibility into the pipeline's security posture. Stralya supports teams in the design and implementation of this roadmap, adapting the pace to your current maturity and your release context (you probably do not deploy at the same cadence as Netflix). ## Managing security exceptions and waivers No set of controls is perfect. Sometimes a vulnerable dependency does not actually expose your application (if the code does not use the vulnerable function), or a very strict IaC rule blocks a legitimate business need. Without a structured waiver process, there are two risks: either the team bypasses the gates (disables them), weakening security, or it stops at every minor alert, slowing delivery. The right approach is a documented, time-limited waiver process. For vulnerable but non-exploitable dependencies, add an exception in the SCA configuration (with a comment justifying why it is acceptable) and review this exception quarterly. For a justified IaC violation (e.g., a rule too strict for a limited case), document the waiver in the IaC code itself (Terraform comment + tag explaining the business need) and sign it. All waivers must be approved by a peer and a manager (e.g., the CTO or the compliance officer), and logged automatically. On AWS, this can be implemented via an AWS Approval Step in CodePipeline, which creates an approve/reject ticket before deploying a version with a waiver. Waivers must also have a validity period: for example, a waiver for a minor vulnerability expires automatically after 90 days, after which it must be renewed or the problem fixed. This prevents the accumulation of invisible security debt.