CDK Nag
cdk-nag is an open-source library for the AWS Cloud Development Kit (CDK) that checks CDK applications for security and compliance best practices. It functions as a linter for Infrastructure as Code, leveraging CDK Aspects to validate constructs against various rule packs like AWS Solutions, HIPAA, NIST, and PCI DSS. The library helps identify issues such as unencrypted S3 buckets, overly permissive IAM policies, and public databases before deployment. It is currently at version 2.37.55 and actively maintained with a regular release cadence.
Warnings
- gotcha When using monorepos with package managers like PNPM, `cdk-nag` might fail to enforce rule checks silently if multiple versions of `aws-cdk-lib` are present. This occurs due to `instanceof` checks that evaluate to false across different instances of the `aws-cdk-lib` module.
- gotcha Constructs within `aws-cdk-lib/pipelines.CodePipeline` and its children are not always guaranteed to be 'Visited' by `cdk-nag` Aspects during the CDK lifecycle. This can lead to missed rule violations or ineffective suppressions on pipeline-related resources.
- gotcha Suppressing `cdk-nag` findings without a clear, valid reason can undermine security posture and compliance efforts. Each suppression should be a conscious decision, not a shortcut.
- gotcha Many AWS resources, when created with default CDK configurations, do not meet common security best practices (e.g., S3 buckets without server-side encryption or access logging, SNS topics without SSL enforcement). These defaults will often trigger `cdk-nag` warnings or errors.
Install
-
pip install cdk-nag
Imports
- AwsSolutionsChecks
from cdk_nag import AwsSolutionsChecks
- NagSuppressions
from cdk_nag import NagSuppressions
- NagPack
from cdk_nag import NagPack
- NIST80053R5Checks
from cdk_nag import NIST80053R5Checks
- HIPAASecurityChecks
from cdk_nag import HIPAASecurityChecks
Quickstart
import os
from aws_cdk import App, Stack, Aspects, aws_s3 as s3
from constructs import Construct
from cdk_nag import AwsSolutionsChecks, NagSuppressions
class MyNaggedStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
# An S3 bucket that will likely trigger some AwsSolutions nags
# for missing logging, encryption, and public access blocks.
my_bucket = s3.Bucket(self, "MyInsecureBucket")
# Suppress a specific finding on the bucket with a clear reason
# This suppression is for demonstration; always address findings first.
NagSuppressions.add_resource_suppressions(
my_bucket,
[
{
"id": "AwsSolutions-S1",
"reason": "This is a demonstration bucket; access logging is not critical for this specific example."
}
]
)
app = App()
# Apply AWS Solutions Checks to the entire app
Aspects.of(app).add(AwsSolutionsChecks(verbose=True))
MyNaggedStack(app, "CdkNagDemoStack")
app.synth()