Shift Left Security: Reviewing AWS CDK Apps at Pull Request Time
by Thorsten Höger, Cloud Automation Evangelist
Discovering security issues during pre-deployment reviews can feel like finding a critical bug after your code has already been merged. It's costly, time-consuming, and often leads to deployment delays or, worse, security compromises. For teams using AWS CDK, there's a better way: conducting security reviews during the pull request phase by analyzing CloudFormation template diffs.
The Cost of Late-Stage Security Findings
Imagine: Your team has just finished a sprint's worth of infrastructure changes using AWS CDK. The code has been reviewed, tested, and merged. You're ready to deploy to production. Then, during the pre-deployment security review, a critical issue is discovered – perhaps an overly permissive IAM role or an unencrypted data store. Now you're faced with a difficult choice: delay the deployment to fix the security issue or accept the risk and deploy anyway.
This scenario plays out in organizations daily, leading to:
- Deployment delays that impact business objectives
- Rushed security fixes that may introduce new issues
- Increased pressure on security teams to expedite reviews
- Technical debt when teams choose to deploy with known issues
Breaking Free from Traditional Review Bottlenecks
Traditional infrastructure security reviews often happen too late because they're treated as a final gateway before production deployment. This approach made sense in the days of manual infrastructure provisioning, but with Infrastructure as Code (IaC) tools like AWS CDK, we can shift these reviews left – way left, to the pull request phase.
The challenge with CDK specifically is that reviewing the TypeScript/Python/Java code alone isn't sufficient. A seemingly innocent change in CDK code can result in significant security implications in the generated CloudFormation templates. This is where diff analysis comes into play.
The Power of CloudFormation Diff Analysis
By synthesizing and comparing CloudFormation templates between your PR branch and the latest commit on main
, you can:
- Identify security-relevant changes early in the development cycle
- Review actual infrastructure changes rather than abstractions
- Catch unintended consequences of CDK construct usage
- Provide developers with immediate security feedback
Consider this example:
// What looks like a simple S3 bucket creation in CDK
new s3.Bucket(this, 'MyBucket', {
bucketName: 'my-important-data',
removalPolicy: cdk.RemovalPolicy.DESTROY
});
Could generate this CloudFormation change:
{
"Resources": {
"MyBucket": {
"Type": "AWS::S3::Bucket",
"Properties": {
"BucketName": "my-important-data",
+ "PublicAccessBlockConfiguration": null,
"VersioningConfiguration": {
- "Status": "Enabled"
+ "Status": "Suspended"
}
}
}
}
}
Current State: The Limitations of CDK Code Reviews
When reviewing CDK code, several critical security aspects can slip through the cracks:
Abstract Nature of CDK Constructs
High-level constructs in CDK can mask underlying security configurations. For example, a simple DatabaseInstance
construct might create multiple security groups, IAM roles, and KMS keys – all of which need security review. Reviewing the CDK code alone might not reveal:
- Default security group rules
- Automated backup configurations
- Log retention settings
- Default encryption settings
L1 Construct Complexity
When using L1 (low-level) constructs, developers have more direct control over CloudFormation properties, but this can lead to:
- Inconsistent security configurations across similar resources
- Missing security best practices that higher-level constructs provide
- Unintended exposure of sensitive configurations
- Complex property combinations that are difficult to audit
Cross-Stack Dependencies
Modern CDK applications often span multiple stacks with complex dependencies. Security implications can arise from:
- Cross-stack references affecting resource policies
- Shared security group rules
- IAM role trust relationships
The Case for PR-Time Security Reviews
Shifting security reviews to the pull request phase transforms the development process in several ways:
Accelerated Mean Time to Remediation
When security issues are found during PR review:
- Developers are still actively engaged with the code
- Context is fresh and relevant
- Changes are smaller and more focused
- Fixes can be implemented before affecting other developers
Developer Security Empowerment
Regular exposure to security reviews during the PR phase:
- Builds security awareness within development teams
- Helps developers learn to spot common security issues
- Creates a feedback loop for continuous improvement
- Reduces dependency on dedicated security teams
Enhanced Deployment Velocity
By catching security issues early:
- Pre-deployment reviews become confirmatory rather than exploratory
- Deployment pipelines face fewer security-related blocks
- Teams can maintain deployment schedules with confidence
- Security fixes don't compete with new feature development
Implementing PR-Time Security Reviews
Shifting security reviews to the PR phase requires both technical tooling and process changes. Let's break down the implementation into actionable components.
Technical Setup
The foundation of effective PR-time security reviews is automated CDK synthesis and diff generation. Here's a complete setup using GitHub Actions:
name: CDK Security Review
on:
pull_request_target:
branches: [ main ]
jobs:
security-diff:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install dependencies
run: npm ci
- name: Synthesize main branch
run: |
git checkout main
cdk synth -q
mv cdk.out cdk.out.main
- name: Synthesize PR branch
run: |
git checkout ${{ github.event.pull_request.head.sha }}
cdk synth -q
- name: Generate security diff
run: |
cdk diff --app cdk.out MyStack --template=cdk.out.main/mystack.template.json > diff.log
- name: Comment on PR
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const diff = fs.readFileSync('diff.log', 'utf8');
const comment = `## Security Review Required
The following CloudFormation changes require security review:
<details>
<summary>Infrastructure Changes</summary>
\\`\\`\\`diff
${diff}
\\`\\`\\`
</details>
### Key Changes to Review:
- IAM changes: ${diff.includes('AWS::IAM::') ? '⚠️ Yes' : '✅ No'}
- Security Group changes: ${diff.includes('AWS::EC2::SecurityGroup') ? '⚠️ Yes' : '✅ No'}
- KMS changes: ${diff.includes('AWS::KMS::') ? '⚠️ Yes' : '✅ No'}
- S3 Policy changes: ${diff.includes('AWS::S3::BucketPolicy') ? '⚠️ Yes' : '✅ No'}`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
This workflow automates several crucial steps:
- Synthesizes CloudFormation templates from both the main branch and PR branch
- Generates a detailed diff of the templates
- Posts the results directly to the PR with highlighted areas requiring review
- Provides a quick summary of high-risk changes
Security-Focused Diff Analysis
When reviewing the generated diffs, certain changes should trigger immediate attention. Here's a prioritized checklist:
High Priority Changes
# IAM Role Policy Changes
{
"Resources": {
"ServiceRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [{
"Effect": "Allow",
"Principal": {
- "Service": "lambda.amazonaws.com"
+ "AWS": "*"
}
}]
}
}
}
}
}
# Security Group Rule Changes
{
"Resources": {
"DatabaseSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"SecurityGroupIngress": [{
- "CidrIp": "10.0.0.0/16"
+ "CidrIp": "0.0.0.0/0"
"FromPort": 5432
}]
}
}
}
}
Changes Requiring Deeper Analysis
# KMS Key Policy Changes
{
"Resources": {
"DataKey": {
"Type": "AWS::KMS::Key",
"Properties": {
+ "EnableKeyRotation": false,
"KeyPolicy": {
"Statement": [{
+ "Principal": {"AWS": "arn:aws:iam::*:root"}
}]
}
}
}
}
}
Integration with Security Scanning Tools
Complement your diff analysis with specialized security scanning tools. Here's how to integrate cdk-nag:
import { AwsSolutionsChecks } from 'cdk-nag';
import { App, Aspects } from 'aws-cdk-lib';
const app = new App();
const stack = new MyStack(app, 'SecurityStack');
// Add all AWS Solutions security checks
Aspects.of(app).add(new AwsSolutionsChecks());
Review Process Integration
To make security reviews effective, integrate them into your PR process:
-
Required Checks: Configure GitHub branch protection rules to require:
- Successful CDK synthesis
- Security baseline checks
- No high-severity findings
-
Review Templates: Create PR templates that highlight security considerations:
## Security Considerations - [ ] IAM permissions follow least privilege - [ ] Network access is appropriately restricted - [ ] Data encryption is properly configured - [ ] Security groups follow zero trust principles - [ ] Logging and monitoring are enabled ## CloudFormation Changes <!-- Automated diff will be added here -->
-
Documentation Requirements: For security-relevant changes, require:
- Justification for permission changes
- Risk assessment for network changes
- Compliance impact analysis
- Rollback procedures
This enables teams to catch security issues early while maintaining deployment velocity. The next sections will cover specific security patterns to watch for and advanced automation strategies.
Getting Started
To implement PR-time security reviews in your organization:
- Team Preparation
- Schedule security review training sessions
- Document review procedures
- Establish escalation paths
- Define security champions
- Progressive Implementation
- Start with high-risk changes only
- Gradually expand scope
- Collect feedback and iterate
- Automate common checks
Common Pitfalls to Avoid
- Over-reliance on Automation
- Automated checks complement, not replace, human review
- Maintain balance between automation and manual review
- Regular updates to security rules
- Review Fatigue
- Rotate security reviewers
- Focus on high-impact changes
- Clear escalation paths
- Regular training and knowledge sharing
- Process Overhead
- Right-size the process for your team
- Automate routine checks
- Clear documentation
- Regular process review and optimization
Conclusion
Implementing PR-time security reviews for CDK applications is a journey, not a destination. Start small, focus on high-impact changes, and gradually expand your coverage.
- Security reviews are most effective when integrated early
- Automation supports but doesn't replace human judgment
- Clear processes and documentation are crucial
- Regular training and feedback improve outcomes
By following these practices and guidelines, you'll build a robust security review process that catches issues early while maintaining development velocity.
Additional Resources
For further reading and tools:
- AWS CDK Security Documentation
- cdk-nag Security Rules
- AWS Security Best Practices
- CloudFormation Security
Take Your AWS Security to the Next Level
While this guide provides a solid foundation for implementing PR-time security reviews, building and maintaining a robust security posture requires ongoing expertise and dedication. If you'd like expert assistance in securing your AWS infrastructure, I offer comprehensive AWS Security Reviews that include a complete baseline analysis, deep-dive IAM review, and network security assessment.