Skip to main content

cdk-nag

Language cdk-nag monocdk-nag
Python PyPI version PyPI version
TypeScript npm version npm version
Java Maven version Maven version
.NET NuGet version NuGet version
  • If your project uses cdk version 1.x.x use cdk-nag ^1.0.0
  • If your project uses cdk version 2.x.x use cdk-nag ^2.0.0
  • If your project uses monocdk use monocdk-nag ^1.0.0

Check CDK applications or CloudFormation templates for best practices using a combination of available rule packs. Inspired by cfn_nag

Available Packs

See RULES for more information on all the available packs.

  1. AWS Solutions
  2. HIPAA Security
  3. NIST 800-53 rev 4
  4. NIST 800-53 rev 5
  5. PCI DSS 3.2.1

Read the NagPack developer docs if you are interested in creating your own pack.

Usage

For a full list of options See NagPackProps in the API.md

cdk
import { App, Aspects } from '@aws-cdk/core';
import { CdkTestStack } from '../lib/cdk-test-stack';
import { AwsSolutionsChecks } from 'cdk-nag';

const app = new App();
new CdkTestStack(app, 'CdkNagDemo');
// Simple rule informational messages
Aspects.of(app).add(new AwsSolutionsChecks());
// Additional explanations on the purpose of triggered rules
// Aspects.of(stack).add(new AwsSolutionsChecks({ verbose: true }));
cdk v2
import { App, Aspects } from 'aws-cdk-lib';
import { CdkTestStack } from '../lib/cdk-test-stack';
import { AwsSolutionsChecks } from 'cdk-nag';

const app = new App();
new CdkTestStack(app, 'CdkNagDemo');
// Simple rule informational messages
Aspects.of(app).add(new AwsSolutionsChecks());
// Additional explanations on the purpose of triggered rules
// Aspects.of(stack).add(new AwsSolutionsChecks({ verbose: true }));
monocdk
import { App, Aspects } from 'monocdk';
import { CdkTestStack } from '../lib/my-stack';
import { AwsSolutionsChecks } from 'monocdk-nag';

const app = new App();
new CdkTestStack(app, 'CdkNagDemo');
// Simple rule informational messages
Aspects.of(app).add(new AwsSolutionsChecks());
// Additional explanations on the purpose of triggered rules
// Aspects.of(stack).add(new AwsSolutionsChecks({ verbose: true }));

Suppressing a Rule

Example 1) Default Construct
import { SecurityGroup, Vpc, Peer, Port } from '@aws-cdk/aws-ec2';
import { Construct, Stack, StackProps } from '@aws-cdk/core';
import { NagSuppressions } from 'cdk-nag';

export class CdkTestStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    const test = new SecurityGroup(this, 'test', {
      vpc: new Vpc(this, 'vpc'),
    });
    test.addIngressRule(Peer.anyIpv4(), Port.allTraffic());
    NagSuppressions.addResourceSuppressions(test, [
      { id: 'AwsSolutions-EC23', reason: 'lorem ipsum' },
    ]);
  }
}
Example 2) Child Constructs
import { User, PolicyStatement } from '@aws-cdk/aws-iam';
import { Construct, Stack, StackProps } from '@aws-cdk/core';
import { NagSuppressions } from 'cdk-nag';

export class CdkTestStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    const user = new User(this, 'rUser');
    user.addToPolicy(
      new PolicyStatement({
        actions: ['s3:PutObject'],
        resources: ['arn:aws:s3:::bucket_name/*'],
      })
    );
    // Enable adding suppressions to child constructs
    NagSuppressions.addResourceSuppressions(
      user,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason: 'lorem ipsum',
          appliesTo: ['Resource::arn:aws:s3:::bucket_name/*'], // optional
        },
      ],
      true
    );
  }
}
Example 3) Stack Level
import { App, Aspects } from '@aws-cdk/core';
import { CdkTestStack } from '../lib/cdk-test-stack';
import { AwsSolutionsChecks, NagSuppressions } from 'cdk-nag';

const app = new App();
const stack = new CdkTestStack(app, 'CdkNagDemo');
Aspects.of(app).add(new AwsSolutionsChecks());
NagSuppressions.addStackSuppressions(stack, [
  { id: 'AwsSolutions-EC23', reason: 'lorem ipsum' },
]);
Example 4) Construct path

If you received the following error on synth/deploy

[Error at /StackName/Custom::CDKBucketDeployment8675309/ServiceRole/Resource] AwsSolutions-IAM4: The IAM user, role, or group uses AWS managed policies
import { Bucket } from '@aws-cdk/aws-s3';
import { BucketDeployment } from '@aws-cdk/aws-s3-deployment';
import { NagSuppressions } from 'cdk-nag';
import { Construct, Stack, StackProps } from '@aws-cdk/core';

export class CdkTestStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    new BucketDeployment(this, 'rDeployment', {
      sources: [],
      destinationBucket: Bucket.fromBucketName(this, 'rBucket', 'foo'),
    });
    NagSuppressions.addResourceSuppressionsByPath(
      this,
      '/StackName/Custom::CDKBucketDeployment8675309/ServiceRole/Resource',
      [{ id: 'AwsSolutions-IAM4', reason: 'at least 10 characters' }]
    );
  }
}
Example 5) Granular Suppressions of findings

Certain rules support granular suppressions of findings. If you received the following errors on synth/deploy

[Error at /StackName/rFirstUser/DefaultPolicy/Resource] AwsSolutions-IAM5[Action::s3:*]: The IAM entity contains wildcard permissions and does not have a cdk_nag rule suppression with evidence for those permission.
[Error at /StackName/rFirstUser/DefaultPolicy/Resource] AwsSolutions-IAM5[Resource::*]: The IAM entity contains wildcard permissions and does not have a cdk_nag rule suppression with evidence for those permission.
[Error at /StackName/rSecondUser/DefaultPolicy/Resource] AwsSolutions-IAM5[Action::s3:*]: The IAM entity contains wildcard permissions and does not have a cdk_nag rule suppression with evidence for those permission.
[Error at /StackName/rSecondUser/DefaultPolicy/Resource] AwsSolutions-IAM5[Resource::*]: The IAM entity contains wildcard permissions and does not have a cdk_nag rule suppression with evidence for those permission.

By applying the following suppressions

import { User } from '@aws-cdk/aws-iam';
import { NagSuppressions } from 'cdk-nag';
import { Construct, Stack, StackProps } from '@aws-cdk/core';

export class CdkTestStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    const firstUser = new User(this, 'rFirstUser');
    firstUser.addToPolicy(
      new PolicyStatement({
        actions: ['s3:*'],
        resources: ['*'],
      })
    );
    const secondUser = new User(this, 'rSecondUser');
    secondUser.addToPolicy(
      new PolicyStatement({
        actions: ['s3:*'],
        resources: ['*'],
      })
    );
    const thirdUser = new User(this, 'rSecondUser');
    thirdUser.addToPolicy(
      new PolicyStatement({
        actions: ['sqs:CreateQueue'],
        resources: [`arn:aws:sqs:${this.region}:${this.account}:*`],
      })
    );
    NagSuppressions.addResourceSuppressions(
      firstUser,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason:
            "Only suppress AwsSolutions-IAM5 's3:*' finding on First User.",
          appliesTo: ['Action::s3:*'],
        },
      ],
      true
    );
    NagSuppressions.addResourceSuppressions(
      secondUser,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason: 'Suppress all AwsSolutions-IAM5 findings on Second User.',
        },
      ],
      true
    );
    NagSuppressions.addResourceSuppressions(
      thirdUser,
      [
        {
          id: 'AwsSolutions-IAM5',
          reason: 'Suppress AwsSolutions-IAM5 on the SQS resource.',
          appliesTo: [
            {
              regex: '/^Resource::arn:aws:sqs:(.*):\\*$/g',
            },
          ],
        },
      ],
      true
    );
  }
}

You would see the following error on synth/deploy

[Error at /StackName/rFirstUser/DefaultPolicy/Resource] AwsSolutions-IAM5[Resource::*]: The IAM entity contains wildcard permissions and does not have a cdk_nag rule suppression with evidence for those permission.

Rules and Property Overrides

In some cases L2 Constructs do not have a native option to remediate an issue and must be fixed via Raw Overrides. Since raw overrides take place after template synthesis these fixes are not caught by the cdk_nag. In this case you should remediate the issue and suppress the issue like in the following example.

Example) Property Overrides
import {
  Instance,
  InstanceType,
  InstanceClass,
  MachineImage,
  Vpc,
  CfnInstance,
} from '@aws-cdk/aws-ec2';
import { Construct, Stack, StackProps } from '@aws-cdk/core';
import { NagSuppressions } from 'cdk-nag';

export class CdkTestStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    const instance = new Instance(this, 'rInstance', {
      vpc: new Vpc(this, 'rVpc'),
      instanceType: new InstanceType(InstanceClass.T3),
      machineImage: MachineImage.latestAmazonLinux(),
    });
    const cfnIns = instance.node.defaultChild as CfnInstance;
    cfnIns.addPropertyOverride('DisableApiTermination', true);
    NagSuppressions.addResourceSuppressions(instance, [
      {
        id: 'AwsSolutions-EC29',
        reason: 'Remediated through property override.',
      },
    ]);
  }
}

Using on CloudFormation templates

You can use cdk-nag on existing CloudFormation templates by using the cloudformation-include module.

Example 1) CloudFormation template with suppression

Sample CloudFormation template with suppression

{
  "Resources": {
    "rBucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": "some-bucket-name"
      },
      "Metadata": {
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-S1",
              "reason": "at least 10 characters"
            }
          ]
        }
      }
    }
  }
}

Sample App

import { App, Aspects } from '@aws-cdk/core';
import { CdkTestStack } from '../lib/cdk-test-stack';
import { AwsSolutionsChecks } from 'cdk-nag';

const app = new App();
new CdkTestStack(app, 'CdkNagDemo');
Aspects.of(app).add(new AwsSolutionsChecks());

Sample Stack with imported template

import { CfnInclude } from '@aws-cdk/cloudformation-include';
import { NagSuppressions } from 'cdk-nag';
import { Construct, Stack, StackProps } from '@aws-cdk/core';

export class CdkTestStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    new CfnInclude(this, 'Template', {
      templateFile: 'my-template.json',
    });
    // Add any additional suppressions
    NagSuppressions.addResourceSuppressionsByPath(
      this,
      '/CdkNagDemo/Template/rBucket',
      [
        {
          id: 'AwsSolutions-S2',
          reason: 'at least 10 characters',
        },
      ]
    );
  }
}
Example 2) CloudFormation template with granular suppressions

Sample CloudFormation template with suppression

{
  "Resources": {
    "myPolicy": {
      "Type": "AWS::IAM::Policy",
      "Properties": {
        "PolicyDocument": {
          "Statement": [
            {
              "Action": [
                "kms:Decrypt",
                "kms:DescribeKey",
                "kms:Encrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*"
              ],
              "Effect": "Allow",
              "Resource": ["some-key-arn"]
            }
          ],
          "Version": "2012-10-17"
        }
      },
      "Metadata": {
        "cdk_nag": {
          "rules_to_suppress": [
            {
              "id": "AwsSolutions-IAM5",
              "reason": "Allow key data access",
              "applies_to": [
                "Action::kms:ReEncrypt*",
                "Action::kms:GenerateDataKey*"
              ]
            }
          ]
        }
      }
    }
  }
}

Sample App

import { App, Aspects } from '@aws-cdk/core';
import { CdkTestStack } from '../lib/cdk-test-stack';
import { AwsSolutionsChecks } from 'cdk-nag';

const app = new App();
new CdkTestStack(app, 'CdkNagDemo');
Aspects.of(app).add(new AwsSolutionsChecks());

Sample Stack with imported template

import { CfnInclude } from '@aws-cdk/cloudformation-include';
import { NagSuppressions } from 'cdk-nag';
import { Construct, Stack, StackProps } from '@aws-cdk/core';

export class CdkTestStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    new CfnInclude(this, 'Template', {
      templateFile: 'my-template.json',
    });
    // Add any additional suppressions
    NagSuppressions.addResourceSuppressionsByPath(
      this,
      '/CdkNagDemo/Template/myPolicy',
      [
        {
          id: 'AwsSolutions-IAM5',
          reason: 'Allow key data access',
          appliesTo: ['Action::kms:ReEncrypt*', 'Action::kms:GenerateDataKey*'],
        },
      ]
    );
  }
}

Contributing

See CONTRIBUTING for more information.

License

This project is licensed under the Apache-2.0 License.

Release files for monocdk-nag 1.14.19

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for monocdk-nag 1.14.19
File Size Uploaded
monocdk-nag-1.14.19.tar.gz 684.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for monocdk-nag 1.14.19
File Interpreter ABI Platform
monocdk_nag-1.14.19-py3-none-any.whl Python 3 none any Details

Total release size: 1.4 MB

Release files / monocdk-nag-1.14.19.tar.gz

Download URL monocdk-nag-1.14.19.tar.gz
Size 684.4 kB
Tags Source
SHA-256 checksum
How to use checksums
0ebe82163095f84f644ba31711107e65ed3f2481f5cf428a09e096697c911eab
BLAKE2b-256 checksum
How to use checksums
ad38a9812f4195296bd6c84800ae5cbbe4e6d759cf3b5a34db14c038b8b0b437
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.0 CPython/3.10.4

Release files / monocdk_nag-1.14.19-py3-none-any.whl

Download URL monocdk_nag-1.14.19-py3-none-any.whl
Size 682.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
933121e3af87d2e93c58256088de145e0679b403257d0ba0e139ff13908aa245
BLAKE2b-256 checksum
How to use checksums
09f5a643253fd7daefad7890ab6fa7ef4d48bfd901ff4870dec0f4ab68baeae6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.0 CPython/3.10.4

Release history Release notifications | RSS feed

This release

1.14.19 This release

2 release files

1.14.9

2 release files

1.14.8

2 release files

1.14.7

2 release files

1.14.6

2 release files

1.14.5

2 release files

1.14.4

2 release files

1.14.3

2 release files

1.14.2

2 release files

1.14.1

2 release files

1.14.0

2 release files

1.13.7

2 release files

1.13.6

2 release files

1.13.5

2 release files

1.13.4

2 release files

1.12.9

2 release files

1.12.8

2 release files

1.12.7

2 release files

1.12.6

2 release files

1.12.5

2 release files

1.12.4

2 release files

1.12.3

2 release files

1.12.2

2 release files

1.12.1

2 release files

1.12.0

2 release files

1.11.4

2 release files

1.11.3

2 release files

1.11.2

2 release files

1.11.1

2 release files

1.11.0

2 release files

1.10.5

2 release files

1.10.4

2 release files

1.10.3

2 release files

1.10.2

2 release files

1.10.1

2 release files

1.10.0

2 release files

1.9.7

2 release files

1.9.6

2 release files

1.9.5

2 release files

1.9.4

2 release files

1.9.3

2 release files

1.9.2

2 release files

1.9.1

2 release files

1.9.0

2 release files

1.8.1

2 release files

1.8.0

2 release files

1.7.9

2 release files

1.7.8

2 release files

1.7.7

2 release files

1.7.6

2 release files

1.7.5

2 release files

1.7.4

2 release files

1.7.3

2 release files

1.7.2

2 release files

1.7.1

2 release files

1.7.0

2 release files

1.6.8

2 release files

1.6.7

2 release files

1.6.6

2 release files

1.6.5

2 release files

1.6.4

2 release files

1.6.3

2 release files

1.6.2

2 release files

1.6.1

2 release files

1.6.0

2 release files

1.5.7

2 release files

1.5.6

2 release files

1.5.5

2 release files

1.5.4

2 release files

1.5.3

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.50

2 release files

1.4.49

2 release files

1.4.38

2 release files

1.4.37

2 release files

1.4.36

2 release files

1.4.35

2 release files

1.4.34

2 release files

1.4.33

2 release files

1.4.32

2 release files

1.4.31

2 release files

1.4.30

2 release files

1.4.29

2 release files

1.4.28

2 release files

1.4.27

2 release files

1.4.26

2 release files

1.4.19

2 release files

1.4.18

2 release files

1.4.17

2 release files

1.4.16

2 release files

1.4.15

2 release files

1.4.14

2 release files

1.4.13

2 release files

1.4.12

2 release files

1.4.11

2 release files

1.4.10

2 release files

1.4.9

2 release files

1.4.8

2 release files

1.4.7

2 release files

1.4.6

2 release files

1.4.5

2 release files

1.4.4

2 release files

1.4.3

2 release files

1.4.2

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.6

2 release files

1.3.5

2 release files

1.3.4

2 release files

1.3.3

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.39

2 release files

0.1.38

2 release files

0.1.37

2 release files

0.1.36

2 release files

0.1.35

2 release files

0.1.34

2 release files

0.1.33

2 release files

0.1.32

2 release files

0.1.31

2 release files

0.1.17

2 release files

0.1.16

2 release files

0.1.15

2 release files

0.1.14

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.99

2 release files

0.0.98

2 release files

0.0.97

2 release files

0.0.96

2 release files

0.0.95

2 release files

0.0.94

2 release files

0.0.93

2 release files

0.0.92

2 release files

0.0.91

2 release files

0.0.90

2 release files

0.0.89

2 release files

0.0.88

2 release files

0.0.87

2 release files

0.0.86

2 release files

0.0.85

2 release files

0.0.84

2 release files

0.0.83

2 release files

0.0.82

2 release files

0.0.81

2 release files

0.0.80

2 release files

0.0.79

2 release files

0.0.78

2 release files

0.0.77

2 release files

0.0.76

2 release files

0.0.75

2 release files

0.0.74

2 release files

0.0.73

2 release files

0.0.72

2 release files

0.0.71

2 release files

0.0.70

2 release files

0.0.61

2 release files

0.0.60

2 release files

0.0.59

2 release files

0.0.58

2 release files

0.0.57

2 release files

0.0.56

2 release files

0.0.55

2 release files

0.0.54

2 release files

0.0.53

2 release files

0.0.52

2 release files

0.0.51

2 release files

0.0.50

2 release files

0.0.49

2 release files

0.0.48

2 release files

0.0.47

2 release files

0.0.46

2 release files

0.0.45

2 release files

0.0.44

2 release files

0.0.43

2 release files

0.0.42

2 release files

0.0.41

2 release files

0.0.40

2 release files

0.0.39

2 release files

0.0.38

2 release files

0.0.37

2 release files

0.0.36

2 release files

0.0.35

2 release files

0.0.34

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page