CodeBuild and CodePipeline are the CI/CD that your security team inherits by default when the rest of the company picks AWS. They are not bad. They are also not the tools most platform engineers would choose if they were starting fresh. The pragmatic reality in 2026 is that many large AWS shops still run the majority of their pipelines on these services, and the hardening guidance has drifted as AWS has shipped new primitives that most teams have not yet adopted.
I have been auditing AWS-native pipelines for the last eighteen months, across finance, healthcare, and government customers. The failure patterns are consistent. This guide is a concentrated walkthrough of the controls that actually matter in 2026, ordered by how often I see them missing in production.
Why are CodeBuild projects still the most over-privileged resource in most AWS accounts?
Because the default IAM role attached to a CodeBuild project has historically been wide open, and nobody goes back to prune it. The CodeBuild service role is created once, stuffed with the permissions needed to clone the repo, pull dependencies, push to ECR, publish to S3, and deploy to whichever target — and then every new project reuses it. Six projects later, the role has permissions from six different deployment targets, and any compromised build can pivot to any of those targets.
The fix is one role per project, with a permission boundary, and no shared artifact stores between untrusted and trusted builds. That is a hard sell because it is operationally expensive, so teams compromise by keeping a small number of "build flavor" roles — one for library builds, one for container builds, one for deployments — and aligning projects to flavors. That works if the flavors are enforced at provisioning time and audited weekly.
The other thing most teams miss is that CodeBuild's aws-access-key environment variables are logged in CloudWatch by default if the customer has enabled logging of build output. The recommendation is to never use long-lived access keys in CodeBuild — use the project role, and if you need to assume a different role, use STS with a session name that includes the build ID for traceability.
How do I stop malicious buildspecs from executing?
Pin the buildspec location, require the buildspec to live in a protected branch, and block inline buildspecs in production projects. This is three controls, and most environments I see have none of them.
CodeBuild lets you specify the buildspec inline in the project configuration or in the source repository. Inline buildspecs are convenient and utterly incompatible with secure CI, because the buildspec is then mutable by anyone with the IAM permission to update the CodeBuild project, and that permission is broader than most teams realize. Require the buildspec to come from the repository at a known path, and enforce this with a service control policy that denies codebuild:UpdateProject when the source override is not null.
Once the buildspec lives in the repo, the next question is who can modify it. The answer has to be "only a protected branch review path." This means branch protection on the repo, a required code owner for buildspec.yml, and ideally a signed commit requirement. Without those, the pipeline becomes a PR-to-RCE vector: a malicious pull request modifies the buildspec, the build runs, and the build role is the attack surface.
Pull-request-triggered builds are where this gets dangerous. If you run builds on PRs from outside the organization, you have to run them with a scoped-down role that cannot access production secrets or deploy anywhere. CodeBuild supports this via webhook filter groups, but the defaults are permissive. Set PULL_REQUEST_CREATED and PULL_REQUEST_UPDATED filters explicitly, and use a separate project with a minimal role for untrusted PRs.
What should I know about CodePipeline V2 that I probably missed?
CodePipeline V2 has pipeline-level variables, manual approval gates with identity verification, and parallel stages. The important addition for supply chain is the ability to attach pipeline-level conditions that block a stage unless an external check passes, and to gate stages on a specific role identity rather than just a permission.
The condition pattern is underused. You can require that an artifact must have a Sigstore signature before the deploy stage runs, that an SBOM must be attached, or that a specific Lambda function has approved the transition. Combining pipeline conditions with AWS Signer for the binary signing step gives you a native AWS supply chain pipeline that does not require a third-party orchestrator.
The approval gate with identity verification is the control I recommend to every customer that has ever had an insider-threat incident. A manual approval in V2 can require the approver to re-authenticate with MFA at approval time, and the approval record includes the approver's SSO identity and the AWS Signer-validated timestamp. This is auditable, it is tamper-evident, and it is a lot harder to fake than the old "click a button in the console" approval.
How do I handle source integrity for CodePipeline?
Use CodeConnections with a bound external repo, require signed commits on the source, and verify the commit signature inside the pipeline before any build step runs. The CodeConnections v2 integration with GitHub, GitLab, and Bitbucket is materially better than the old personal-token-based integration, because the connection identity is an IAM resource that cannot be exfiltrated from a developer workstation.
The commit signature verification is the part people skip. CodePipeline does not verify commit signatures by default. You have to add a first-stage CodeBuild project that clones the repo, runs git verify-commit HEAD, and fails the pipeline if the signature is missing or does not match an allowlisted GPG key or Sigstore identity. This adds about 15 seconds to every pipeline run and closes the most common source integrity gap.
If you are using CodeCommit — and AWS has announced it is in maintenance mode, so you should be planning your migration — the same verification still applies, and CodeCommit never shipped the native signed-commit support that GitHub and GitLab have. Treat CodeCommit as untrusted for signature purposes and do the verification client-side.
What does a 2026-ready CodeBuild environment actually look like?
It uses BUILD_GENERAL1_MEDIUM or higher in a VPC-attached configuration, with an egress-only internet gateway that forces all outbound traffic through a scanned proxy. It uses codebuild.amazonaws.com as the assuming principal with a trust policy condition on the source ARN, not a blanket trust. It mounts secrets from Secrets Manager with a fresh retrieval at build time, never from environment variables stored in the project config. And it uses the newer Amazon Linux 2023 or Ubuntu 22.04 curated images with automatic patching rather than a pinned older image that has not seen updates in a year.
The VPC attachment is the single biggest improvement most teams can make. A VPC-attached CodeBuild project has a network identity you can log and scope, and you can route its traffic through a transit gateway with a firewall. The non-VPC default runs in an AWS-managed network where you cannot see or control egress, and an attacker who compromises a build can exfiltrate freely.
How Safeguard.sh Helps
Safeguard.sh correlates CodeBuild and CodePipeline telemetry with reachability analysis on the artifacts each pipeline produces, so a vulnerability flagged in a build is scored against whether the vulnerable code is actually called by any deployed workload — reachability consistently cuts 60 to 80 percent of CI noise on AWS pipelines. Griffin AI generates least-privilege CodeBuild service roles, pipeline-condition expressions, and buildspec hardening patches from your existing pipeline graph, and flags drift when a human edits the pipeline in the console. Safeguard's SBOM module attaches an SBOM attestation to every CodeBuild output at 100-level dependency depth, its TPRM module tracks the trust state of every external source and registry the pipeline touches, and container self-healing rewrites ECR image references in deployed workloads automatically when CodeBuild publishes a patched image that resolves a reachable CVE.