# cdk-nag

> Check CDK v2 applications for best practices using a combination on available rule packs.

Latest version **3.0.2** (published 2026-08-04) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install cdk-nag
pnpm add cdk-nag
yarn add cdk-nag
bun add cdk-nag
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads; no esm support.

## Facts

| | |
|---|---|
| Version | 3.0.2 |
| Published | 2026-08-04 |
| First published | 2021-07-20 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | bundled |
| Module format | CommonJS |
| Node | >= 18.12.0 |
| Dependencies | 0 |
| Unpacked size | 3.5 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 1044 |
| Author | Amazon Web Services |
| Maintainers | amzn-oss, donti-aws, cdklabs-automation |
| Keywords | cdk |

## Links

- npm: https://www.npmjs.com/package/cdk-nag
- Repository: https://github.com/cdklabs/cdk-nag
- Homepage: https://github.com/cdklabs/cdk-nag#readme
- Issues: https://github.com/cdklabs/cdk-nag/issues
- npm.io page: https://npm.io/package/cdk-nag

## Recent versions

- 3.0.2 (latest) — 2026-08-04
- 1.14.19 (latest-1) — 2022-05-31
- 3.0.1 — 2026-06-15
- 3.0.0 — 2026-06-12
- 2.38.2 — 2026-04-27
- 2.38.1 — 2026-04-21
- 2.38.0 — 2026-04-21
- 2.37.56 — 2026-04-20
- 2.37.55 — 2025-10-17
- 2.37.54 — 2025-10-16
- 2.37.53 — 2025-10-15
- 2.37.52 — 2025-10-14
- 2.37.51 — 2025-10-12
- 2.37.50 — 2025-10-11
- 2.37.49 — 2025-10-10
- … 1592 more at https://npm.io/package/cdk-nag/versions

## README

<!--
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
-->

# cdk-nag

[![PyPI version](https://img.shields.io/pypi/v/cdk-nag)](https://pypi.org/project/cdk-nag/)
[![npm version](https://img.shields.io/npm/v/cdk-nag)](https://www.npmjs.com/package/cdk-nag)
[![Maven version](https://img.shields.io/maven-central/v/io.github.cdklabs/cdknag)](https://search.maven.org/search?q=a:cdknag)
[![NuGet version](https://img.shields.io/nuget/v/Cdklabs.CdkNag)](https://www.nuget.org/packages/Cdklabs.CdkNag)
[![Go version](https://img.shields.io/github/go-mod/go-version/cdklabs/cdk-nag-go?color=blue&filename=cdknag%2Fgo.mod)](https://github.com/cdklabs/cdk-nag-go)

[![View on Construct Hub](https://constructs.dev/badge?package=cdk-nag)](https://constructs.dev/packages/cdk-nag)

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).

Check out [this blog post](https://aws.amazon.com/blogs/devops/manage-application-security-and-compliance-with-the-aws-cloud-development-kit-and-cdk-nag/) for a guided overview!

![demo](cdk_nag.gif)

## Available Rules and 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)
6. [Serverless](./RULES.md#serverless)

[RULES](./RULES.md) also includes a collection of [additional rules](./RULES.md#additional-rules) that are not currently included in any of the pre-built NagPacks, but are still available for inclusion in custom NagPacks.

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>Including in an application</summary>

```ts nofixture
import { App, Validations } from 'aws-cdk-lib';
import { AwsSolutionsChecks, NIST80053R5Checks } from 'cdk-nag';

declare const CdkTestStack: any;

const app = new App();
new CdkTestStack(app, 'CdkNagDemo');
// Simple rule informational messages using the AWS Solutions Rule pack
Validations.of(app).addPlugins(new AwsSolutionsChecks(app));
// Multiple rule packs can be run against the same app
Validations.of(app).addPlugins(new NIST80053R5Checks(app));
// Additional explanations on the purpose of triggered rules
// Validations.of(app).addPlugins(new AwsSolutionsChecks(app, { verbose: true }));
```

</details>

## Acknowledging a Rule

Use CDK's native `Validations.of()` API to acknowledge (suppress) rule violations on specific constructs.

<details>
  <summary>Example 1) Acknowledging a rule on a construct</summary>

```ts nofixture
import { SecurityGroup, Vpc, Peer, Port } from 'aws-cdk-lib/aws-ec2';
import { Stack, StackProps, Validations } from 'aws-cdk-lib';
import { Construct } from 'constructs';

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());
    Validations.of(test).acknowledge({
      id: 'AwsSolutions-EC23',
      reason: 'This security group is used for internal testing only.',
    });
  }
}
```

</details>

<details>
  <summary>Example 2) Acknowledging a rule on a stack</summary>

```ts nofixture
import { App, Validations } from 'aws-cdk-lib';
import { AwsSolutionsChecks } from 'cdk-nag';

declare const CdkTestStack: any;

const app = new App();
const stack = new CdkTestStack(app, 'CdkNagDemo');
Validations.of(app).addPlugins(new AwsSolutionsChecks(app));
Validations.of(stack).acknowledge({
  id: 'AwsSolutions-EC23',
  reason: 'All security groups in this stack are internal only.',
});
```

</details>

<details>
  <summary>Example 3) Acknowledging a specific finding</summary>

Certain rules report multiple findings per resource (e.g., IAM wildcard permissions). Each finding has its own ID in the format `RuleId[FindingId]`.

If you received the following errors on synth/deploy:

```bash
[Error at /StackName/rUser/DefaultPolicy/Resource] AwsSolutions-IAM5[Action::s3:*]: The IAM entity contains wildcard permissions.
[Error at /StackName/rUser/DefaultPolicy/Resource] AwsSolutions-IAM5[Resource::*]: The IAM entity contains wildcard permissions.
```

You can acknowledge a specific finding:

```ts nofixture
import { User, PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { Stack, StackProps, Validations } from 'aws-cdk-lib';
import { Construct } from 'constructs';

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:*'],
        resources: ['*'],
      })
    );
    // Only acknowledge the s3:* action — Resource::* still triggers
    Validations.of(user).acknowledge({
      id: 'AwsSolutions-IAM5[Action::s3:*]',
      reason: 'Need s3:* for cross-account replication.',
    });
  }
}
```

</details>

## 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](https://docs.aws.amazon.com/cdk/latest/guide/cfn_layer.html#cfn_layer_raw). Since raw overrides take place after template synthesis these fixes are not caught by cdk-nag. In this case you should remediate the issue and acknowledge the rule.

<details>
  <summary>Example) Property Overrides</summary>

```ts nofixture
import {
  Instance,
  InstanceType,
  InstanceClass,
  MachineImage,
  Vpc,
  CfnInstance,
} from 'aws-cdk-lib/aws-ec2';
import { Stack, StackProps, Validations } from 'aws-cdk-lib';
import { Construct } from 'constructs';

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);
    Validations.of(instance).acknowledge({
      id: 'AwsSolutions-EC29',
      reason: 'Remediated through property override.',
    });
  }
}
```

</details>

## Audit Trail: CloudFormation Metadata

By default, cdk-nag writes violations to CDK's `policy-validation-report.json` in the cloud assembly. If you need the v2-compatible `cdk_nag` metadata block in your synthesized CloudFormation templates (for existing compliance tooling), enable `writeSuppressionsToCloudFormation`:

```ts nofixture
import { App, Validations } from 'aws-cdk-lib';
import { AwsSolutionsChecks } from 'cdk-nag';

const app = new App();
// Writes acknowledged rules into CfnResource Metadata as cdk_nag: { rules_to_suppress: [...] }
Validations.of(app).addPlugins(new AwsSolutionsChecks(app, { writeSuppressionsToCloudFormation: true }));
```

This registers a `WriteNagSuppressionsToCloudFormationAspect` that runs during synthesis and copies `Validations.of().acknowledge()` data into the CloudFormation template Metadata section, preserving the same format as cdk-nag v2.

## Using on CloudFormation templates

You can use cdk-nag on existing CloudFormation templates by using the [cloudformation-include](https://docs.aws.amazon.com/cdk/latest/guide/use-cfn-template.html#use-cfn-template-import) module.

<details>
  <summary>Example) CloudFormation template</summary>

Sample App

```ts nofixture
import { App, Validations } from 'aws-cdk-lib';
import { AwsSolutionsChecks } from 'cdk-nag';

declare const CdkTestStack: any;

const app = new App();
new CdkTestStack(app, 'CdkNagDemo');
Validations.of(app).addPlugins(new AwsSolutionsChecks(app));
```

Sample Stack with imported template

```ts nofixture
import { CfnInclude } from 'aws-cdk-lib/cloudformation-include';
import { Stack, StackProps, Validations } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class CdkTestStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);
    const template = new CfnInclude(this, 'Template', {
      templateFile: 'my-template.json',
    });
    // Acknowledge rules on imported resources
    const bucket = template.getResource('rBucket');
    Validations.of(bucket).acknowledge({
      id: 'AwsSolutions-S1',
      reason: 'Logging not required for this bucket.',
    });
  }
}
```

</details>

## Migrating from v2

cdk-nag v3 replaces the custom `NagSuppressions` API with CDK's native `Validations.of().acknowledge()` mechanism.

| v2 | v3 |
|---|---|
| `NagSuppressions.addResourceSuppressions(construct, [{ id, reason }])` | `Validations.of(construct).acknowledge({ id, reason })` |
| `NagSuppressions.addStackSuppressions(stack, [{ id, reason }])` | `Validations.of(stack).acknowledge({ id, reason })` |
| `NagSuppressions.addResourceSuppressionsByPath(stack, path, [...])` | `Validations.of(construct).acknowledge({ id, reason })` |
| `appliesTo: ['Action::s3:*']` | `id: 'AwsSolutions-IAM5[Action::s3:*]'` |
| `{ id: 'CdkNagValidationFailure', reason: '...' }` | `Validations.of(construct).acknowledge({ id: 'RuleId', reason: '...' })` |

**Note on bulk suppression:** In v2, suppressing a rule without `appliesTo` would suppress all findings for that rule on the construct. In v3, each finding must be acknowledged individually (e.g., `AwsSolutions-IAM5[Action::s3:*]` and `AwsSolutions-IAM5[Resource::*]` are separate acknowledgments). Prefix matching (acknowledging `AwsSolutions-IAM5` to suppress all findings) is not yet supported — tracked via [issue link].

**Removed APIs:**
- `NagSuppressions` (use `Validations.of().acknowledge()`)
- `INagSuppressionIgnore` and all condition classes
- `NagPackSuppression` interface
- `CdkNagValidationFailure` concept
- `logIgnores` and `suppressionIgnoreCondition` props

## Contributing

See [CONTRIBUTING](./CONTRIBUTING.md) for more information.

## License

This project is licensed under the Apache-2.0 License.

---
_Source: https://npm.io/package/cdk-nag · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
