<!--
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
-->
# cdk-nag
| Language | cdk-nag | monocdk-nag |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Python | [![PyPI version](https://img.shields.io/pypi/v/cdk-nag)](https://pypi.org/project/cdk-nag/) | [![PyPI version](https://img.shields.io/pypi/v/monocdk-nag)](https://pypi.org/project/monocdk-nag/) |
| TypeScript | [![npm version](https://img.shields.io/npm/v/cdk-nag)](https://www.npmjs.com/package/cdk-nag) | [![npm version](https://img.shields.io/npm/v/monocdk-nag/latest-1?label=npm)](https://www.npmjs.com/package/monocdk-nag) |
| Java | [![Maven version](https://img.shields.io/maven-central/v/io.github.cdklabs/cdknag)](https://search.maven.org/search?q=a:cdknag) | [![Maven version](https://img.shields.io/maven-central/v/io.github.cdklabs/monocdknag)](https://search.maven.org/search?q=a:monocdknag) |
| .NET | [![NuGet version](https://img.shields.io/nuget/v/Cdklabs.CdkNag)](https://www.nuget.org/packages/Cdklabs.CdkNag) | [![NuGet version](https://img.shields.io/nuget/v/Cdklabs.MonocdkNag)](https://www.nuget.org/packages/Cdklabs.MonocdkNag) |
* 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](#using-on-cloudformation-templates) for best practices using a combination of available rule packs. Inspired by [cfn_nag](https://github.com/stelligent/cfn_nag)
![](cdk_nag.gif)
## Available Packs
See [RULES](./RULES.md) for more information on all the available packs.
1. [AWS Solutions](./RULES.md#awssolutions)
2. [HIPAA Security](./RULES.md#hipaa-security)
3. [NIST 800-53 rev 4](./RULES.md#nist-800-53-rev-4)
4. [NIST 800-53 rev 5](./RULES.md#nist-800-53-rev-5)
5. [PCI DSS 3.2.1](./RULES.md#pci-dss-321)
Read the [NagPack developer docs](./docs/NagPack.md) if you are interested in creating your own pack.
## Usage
For a full list of options See `NagPackProps` in the [API.md](./API.md#struct-nagpackprops)
<details>
<summary>cdk</summary>
```python
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 }));
```
</details><details>
<summary>cdk v2</summary>
```python
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 }));
```
</details><details>
<summary>monocdk</summary>
```python
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 }));
```
</details>
## Suppressing a Rule
<details>
<summary>Example 1) Default Construct</summary>
```python
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' },
]);
}
}
```
</details><details>
<summary>Example 2) Child Constructs</summary>
```python
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
);
}
}
```
</details><details>
<summary>Example 3) Stack Level </summary>
```python
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' },
]);
```
</details><details>
<summary>Example 4) Construct path</summary>
If you received the following error on synth/deploy
```bash
[Error at /StackName/Custom::CDKBucketDeployment8675309/ServiceRole/Resource] AwsSolutions-IAM4: The IAM user, role, or group uses AWS managed policies
```
```python
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' }]
);
}
}
```
</details><details>
<summary>Example 5) Granular Suppressions of findings</summary>
Certain rules support granular suppressions of `findings`. If you received the following errors on synth/deploy
```bash
[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