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:

  1. Identify security-relevant changes early in the development cycle
  2. Review actual infrastructure changes rather than abstractions
  3. Catch unintended consequences of CDK construct usage
  4. 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:

  1. Synthesizes CloudFormation templates from both the main branch and PR branch
  2. Generates a detailed diff of the templates
  3. Posts the results directly to the PR with highlighted areas requiring review
  4. 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:

  1. Required Checks: Configure GitHub branch protection rules to require:

    • Successful CDK synthesis
    • Security baseline checks
    • No high-severity findings
  2. 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 -->
    
    
  3. 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:

  1. Team Preparation
    • Schedule security review training sessions
    • Document review procedures
    • Establish escalation paths
    • Define security champions
  2. Progressive Implementation
    • Start with high-risk changes only
    • Gradually expand scope
    • Collect feedback and iterate
    • Automate common checks

Common Pitfalls to Avoid

  1. Over-reliance on Automation
    • Automated checks complement, not replace, human review
    • Maintain balance between automation and manual review
    • Regular updates to security rules
  2. Review Fatigue
    • Rotate security reviewers
    • Focus on high-impact changes
    • Clear escalation paths
    • Regular training and knowledge sharing
  3. 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:

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.

More articles

Three strategies for deploying container images to Amazon ECS using CDK

This blog post explores three strategies for deploying container images to Amazon ECS using CDK: pre-built images, custom images from separate projects, and images built alongside CDK code, providing developers with insights to choose the best approach for their specific needs and workflows.

Read more

CDK Serverless and Projen Pipelines Join the Open Construct Foundation

As an AWS Hero and advocate for open-source development, I'm excited to announce the migration of my projects, CDK Serverless and Projen Pipelines, to the Open Construct Foundation (OCF). This move reflects my commitment to fostering open collaboration and accelerating innovation within the AWS CDK ecosystem. By joining OCF, known for its community-driven initiatives, we aim to broaden participation and ensure the long-term sustainability of these tools. Set for September 2024, this transition will create new opportunities for developers to contribute and help shape the future of cloud infrastructure as code.

Read more

Tell me about your project

Taimos GmbH