2.3 Security Scanning, SAST/DAST & Approval Gates
Key Takeaways
- Static Application Security Testing (SAST) analyzes source code for vulnerabilities and secrets in CodeBuild, while Dynamic Application Security Testing (DAST) evaluates running staging endpoints against live attack vectors.
- Software Composition Analysis (SCA) scans open-source dependencies for known vulnerabilities (CVEs) and license compliance before packaging application artifacts.
- Amazon ECR Basic Scanning uses AWS-native scanning technology against the CVE database and covers operating system packages only, whereas Enhanced Scanning uses Amazon Inspector for continuous, automated vulnerability scanning of both OS and programming language dependencies.
- Policy-as-code tools like cfn-guard (declarative DSL) and cfn-nag (pattern matching) audit CloudFormation and CDK templates within CodeBuild before infrastructure provisioning occurs.
- Continuous delivery pipelines utilize SNS-notified manual approval actions alongside event-driven Lambda functions that automatically approve or reject stages based on aggregated Security Hub and vulnerability scan thresholds.
Modern continuous delivery pipelines must integrate security verification directly into the automated release cycle—a practice known as DevSecOps or "shifting left." Identifying security vulnerabilities during the build and staging phases costs a fraction of remediation after a production compromise. On the AWS DOP-C02 exam, you will encounter complex scenarios requiring the orchestration of static code analysis, software composition scanning, container vulnerability management, dynamic application testing, and automated approval gating.
DevSecOps: Shifting Left in AWS CI/CD
Security verification is distributed across distinct pipeline phases to balance scan execution time against detection depth:
[Code Commit] ──> [Build & Package] ──> [Container Push] ──> [Staging Deploy] ──> [Prod Promotion]
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
Secret Scanning SAST & SCA ECR Enhanced DAST Automated Approval
(Gitleaks/Git) (Bandit/Snyk/ (Amazon Inspector) (OWASP ZAP / Gate (Lambda +
cfn-guard) Synthetics) Security Hub)
SAST, SCA & Secret Scanning in CodeBuild
1. Static Application Security Testing (SAST)
SAST tools inspect application source code, abstract syntax trees (ASTs), and byte code without executing the program. SAST identifies common programming flaws, including SQL injection, cross-site scripting (XSS), insecure deserialization, and improper error handling.
- Execution in CodeBuild: SAST tools (such as Bandit for Python, Semgrep, SonarQube Scanner, or Checkmarx) run in the
buildorpre_buildphase. - Exit Code Enforcement: The buildspec executes the scanner and parses the output. If high-severity or critical vulnerabilities are identified, the command exits with a non-zero status, terminating the build before artifacts are generated.
2. Software Composition Analysis (SCA)
Modern applications consist predominantly of open-source third-party dependencies (npm packages, Python wheels, Java JARs). SCA tools (such as OWASP Dependency-Check, Snyk, or Trivy) parse dependency manifests (package-lock.json, pom.xml, Pipfile.lock) and cross-reference them against the National Vulnerability Database (NVD) for known Common Vulnerabilities and Exposures (CVEs).
- CodeArtifact Integration: AWS CodeArtifact can act as a secure package repository mirror with upstream connections to npmjs, PyPI, or Maven Central. Teams can automate vulnerability audits at the artifact registry level, restricting developers from pulling packages with known critical CVEs.
3. Secret Detection
Hardcoded credentials (AWS access keys, database passwords, private API tokens) represent a major vulnerability class. Tools like Gitleaks or TruffleHog execute during the pre_build phase of CodeBuild to scan commit histories and diffs for regex patterns matching AWS access keys (AKIA[0-9A-Z]{16}) and private certificates.
Container Image Security: Amazon ECR Basic vs Enhanced Scanning
When packaging microservices into container images, container repositories must be audited for base operating system vulnerabilities and embedded language runtime packages. AWS provides two distinct scanning tiers in Amazon Elastic Container Registry (ECR):
Comprehensive Comparison: ECR Scanning Tiers
| Feature | ECR Basic Scanning | ECR Enhanced Scanning |
|---|---|---|
| Core Engine | AWS-native scanner using the Common Vulnerabilities and Exposures (CVE) database. Basic scanning originally used the open-source Clair project; AWS retired Clair-based scanning and migrated ECR accounts to the native engine. | Amazon Inspector |
| Scan Coverage | Operating system packages only (RPM, Debian, Alpine Linux) | Both OS packages AND programming language packages (Node.js, Python, Java, Go, Ruby) |
| Scan Triggers | Manual (via API) or Scan-on-Push | Continuous scanning + Scan-on-push |
| Continuous Monitoring | No. Images are only scanned when pushed or manually requested. | Yes. Images are continuously re-evaluated whenever new CVEs are published to the NVD. |
| AWS Integration | ECR console and ECR DescribeImageScanFindings API | Direct integration with AWS Security Hub and Amazon EventBridge |
| Scan Frequency Rules | Configurable at repository level (Push or Manual) | Configurable at registry level (Continuous, Lifetime, or Push) |
Automated Pipeline Gating with ECR & Inspector
To gate an AWS CodePipeline workflow based on ECR container scan findings:
- Push & Wait: CodeBuild builds the Docker image and pushes it to Amazon ECR.
- Scan Execution: ECR Enhanced Scanning (Amazon Inspector) automatically analyzes the image.
- Gating Check in CodeBuild: A
post_buildscript queries the findings via the AWS CLI:
echo "Querying Amazon ECR image scan findings..."
SCAN_FINDINGS=$(aws ecr describe-image-scan-findings \
--repository-name my-app-repo \
--image-id imageTag=$IMAGE_TAG \
--query 'imageScanFindings.findingSeverityCounts' \
--output json)
CRITICAL_COUNT=$(echo $SCAN_FINDINGS | jq '.CRITICAL // 0')
HIGH_COUNT=$(echo $SCAN_FINDINGS | jq '.HIGH // 0')
echo "Scan Results: Critical=$CRITICAL_COUNT, High=$HIGH_COUNT"
if [ "$CRITICAL_COUNT" -gt 0 ] || [ "$HIGH_COUNT" -gt 5 ]; then
echo "ERROR: Security gate failed! Critical/High vulnerabilities exceed threshold." >&2
exit 1
fi
If critical vulnerabilities exceed the threshold, CodeBuild exits with code 1, stopping the pipeline before the image is deployed to ECS or EKS.
Dynamic Application Security Testing (DAST) & IaC Policy-as-Code
Dynamic Application Security Testing (DAST)
Unlike SAST, DAST analyzes an application from the outside in while it is running in a live staging environment. DAST tools (such as OWASP ZAP or commercial scanners running in CodeBuild containers) send malicious payloads to test for runtime vulnerabilities:
- Cross-Site Scripting (XSS) reflection
- SQL and Command Injection
- Broken Object Level Authorization (BOLA)
- Insecure Transport Layer Security (TLS) cipher suites and missing HTTP security headers (CSP, HSTS)
DAST should be executed against dedicated, isolated staging environments rather than shared or production stacks, as automated fuzzing can corrupt backend database records.
Infrastructure as Code (IaC) Policy-as-Code: cfn-guard vs cfn-nag
Security must also protect infrastructure configurations before CloudFormation templates are provisioned:
-
cfn-guard(AWS CloudFormation Guard): An open-source, general-purpose policy-as-code evaluation tool developed by AWS. It uses a lightweight, human-readable Domain Specific Language (DSL) to enforce custom organizational compliance policies on CloudFormation templates, CDK output, and Terraform JSON.Example
cfn-guardrule ensuring all S3 buckets have server-side encryption enabled:let s3_buckets = Resources.*[ Type == 'AWS::S3::Bucket' ] rule S3_BUCKET_ENCRYPTION_CHECK when %s3_buckets !empty { %s3_buckets.Properties.BucketEncryption.ServerSideEncryptionConfiguration[*] { ServerSideEncryptionByDefault.SSEAlgorithm in ['AES256', 'aws:kms'] } } -
cfn-nag: A community Ruby tool that statically scans CloudFormation templates for known insecurity patterns (e.g., IAM policies withResource: *, security groups with ingress from0.0.0.0/0on port 22 or 3389, or unencrypted EBS volumes).
Both tools execute in CodeBuild before any CloudFormation CreateChangeSet or ExecuteChangeSet action, failing the build if compliance checks are violated.
Approval Gates: Manual Notifications vs Automated Lambda Gating
1. Manual Approval Actions with Amazon SNS
In enterprise regulated environments, promoting code to production requires human authorization. AWS CodePipeline includes a native Manual Approval action:
- Configuration: You specify an Amazon SNS Topic ARN and optional custom approval URL (e.g., linking to test dashboards or security scan summaries).
- Notification: When the pipeline reaches the approval stage, CodePipeline publishes a message to the SNS topic. Subscribers (engineers, release managers, or Amazon Q Developer in chat applications in Slack or Microsoft Teams) receive the notification.
- Timeout: The manual approval action generates a unique execution approval token. Exam Watchout: The account-level default timeout is 7 days — if nobody approves or rejects within that window, the action is marked failed and the execution stops. The timeout is overridable per action through
timeoutInMinutes, from a minimum of 5 minutes up to 86,400 minutes (60 days).
2. Automated Lambda-Based Approval Gating
To achieve true continuous deployment without manual human bottlenecks, organizations implement automated approval gates using AWS Lambda and Amazon EventBridge:
[CodePipeline Stage: Security Approval]
│
(Enters Pending Approval)
│
▼
[Amazon EventBridge Rule]
(Matches CodePipeline Action State Change: InProgress)
│
▼
[AWS Lambda Function]
│
┌───────────┴───────────┐
▼ ▼
[Query Security Hub] [Query Inspector / SonarQube]
│ │
└───────────┬───────────┘
▼
{Are Critical CVEs == 0?}
├── Yes ──> [Call PutApprovalResult (Approved)] ──> [Pipeline Proceeds to Prod]
└── No ──> [Call PutApprovalResult (Rejected)] ──> [Pipeline Aborted & SNS Alert]
The Lambda function queries AWS Security Hub for findings associated with the current pipeline execution version. If all security criteria are met, the Lambda function calls codepipeline:PutApprovalResult with Status: Approved. If any critical vulnerability exists, it passes Status: Rejected along with the finding summary, preventing production promotion.
Comparison: Security Testing Modalities
| Modality | Target Analyzed | Pipeline Stage | Tool Examples | What it Detects |
|---|---|---|---|---|
| Secret Scanning | Git commits, diffs, source files | Pre-build | Gitleaks, TruffleHog | Hardcoded API keys, private keys, database passwords |
| SAST | Source code, AST, byte code | Build (pre_build / build) | Bandit, Semgrep, SonarQube | SQL injection, XSS, insecure coding logic |
| SCA | Manifests, third-party libraries | Build (build) | Snyk, OWASP Dependency-Check | Known CVEs in open-source dependencies |
| IaC Scanning | CloudFormation, CDK templates | Build (post_build) | cfn-guard, cfn-nag | Overly permissive IAM, unencrypted S3/EBS, open security groups |
| Container Scan | Docker images (layers, packages) | Post-Push / Registry | Amazon Inspector (ECR Enhanced) | OS CVEs and language package vulnerabilities |
| DAST | Running application endpoints | Staging (Post-deployment) | OWASP ZAP, Arachni | Runtime auth bypass, header misconfigurations, live XSS |
Exam Watchouts & Operational Pitfalls
[!IMPORTANT] ECR Basic Scanning vs Enhanced Scanning Scope: Questions on the DOP-C02 exam frequently test whether ECR Basic Scanning can detect vulnerabilities in application dependencies (e.g., Python
pippackages or Node.jsnpmmodules). It cannot. ECR Basic Scanning only scans Linux operating system packages. To continuously detect vulnerabilities in both OS and application programming language packages, you must enable Amazon ECR Enhanced Scanning powered by Amazon Inspector.
[!WARNING] Approval Timeout: The account-level default timeout for a manual approval action is 7 days, so an execution left pending longer than that fails unless the action raises its own timeout. If your release cadence requires a change advisory board (CAB) that meets bi-weekly, either set
timeoutInMinuteson that action (up to 86,400 minutes / 60 days), separate build artifact creation from deployment pipelines, or trigger release pipelines on demand.
[!NOTE] DAST Scan Impact on Staging Data: DAST tools actively submit forms, inject SQL escape characters, and fuzz API endpoints. Running unconstrained DAST scans against shared databases can lead to data corruption, account lockouts, or triggering rate-limiting WAF rules. Always configure DAST tools to target sanitized, ephemeral test databases with rate-limiting constraints.
A financial services organization requires all container images stored in Amazon ECR to be continuously scanned for vulnerabilities in both operating system packages and application programming language libraries (such as Python pip and Node.js npm packages). When new CVEs are discovered, the findings must be automatically forwarded to AWS Security Hub. How should the DevOps engineer implement this requirement?
A security policy requires that all AWS CloudFormation templates used across an enterprise must be audited in the CI/CD pipeline before infrastructure is created or updated. Specifically, the policy mandates that Amazon S3 buckets must not have public read access and Amazon EBS volumes must have encryption enabled. If a template violates these rules, the pipeline must fail immediately. What is the most efficient and native way to enforce this policy in AWS CodePipeline?
An enterprise wants to implement an automated security gate in AWS CodePipeline before promoting application updates to production. The pipeline must pause before the production deployment stage, evaluate whether any open CRITICAL or HIGH severity findings exist in AWS Security Hub for the application's container image, and automatically approve or reject the deployment without human intervention. How should this automated gate be implemented?