summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-04-11 09:39:44 +0000
committerCoprDistGit <infra@openeuler.org>2023-04-11 09:39:44 +0000
commit69bf1de46ad34a8f4a109646c7cfd611f8f31651 (patch)
tree75c133951ae53270208690e9cac59a8507a31e13
parentfa860183e45a7a27c7720a9cecbf3c07bd1639b0 (diff)
automatic import of python-cdk-nag
-rw-r--r--.gitignore1
-rw-r--r--python-cdk-nag.spec1949
-rw-r--r--sources1
3 files changed, 1951 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..9b50b84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/cdk-nag-2.25.8.tar.gz
diff --git a/python-cdk-nag.spec b/python-cdk-nag.spec
new file mode 100644
index 0000000..6e0306d
--- /dev/null
+++ b/python-cdk-nag.spec
@@ -0,0 +1,1949 @@
+%global _empty_manifest_terminate_build 0
+Name: python-cdk-nag
+Version: 2.25.8
+Release: 1
+Summary: Check CDK v2 applications for best practices using a combination on available rule packs.
+License: Apache-2.0
+URL: https://github.com/cdklabs/cdk-nag.git
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/08/78/9aefd08ea8b276fae197ee31d5d8c90ce653dd8c688b3c7056f3021d7e39/cdk-nag-2.25.8.tar.gz
+BuildArch: noarch
+
+Requires: python3-aws-cdk-lib
+Requires: python3-constructs
+Requires: python3-jsii
+Requires: python3-publication
+Requires: python3-typeguard
+
+%description
+<!--
+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)
+
+[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>
+
+```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>
+
+## Suppressing a Rule
+
+<details>
+ <summary>Example 1) Default Construct</summary>
+
+```python
+import { SecurityGroup, Vpc, Peer, Port } from 'aws-cdk-lib/aws-ec2';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+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) On Multiple Constructs</summary>
+
+```python
+import { SecurityGroup, Vpc, Peer, Port } from 'aws-cdk-lib/aws-ec2';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+import { NagSuppressions } from 'cdk-nag';
+
+export class CdkTestStack extends Stack {
+ constructor(scope: Construct, id: string, props?: StackProps) {
+ super(scope, id, props);
+ const vpc = new Vpc(this, 'vpc');
+ const test1 = new SecurityGroup(this, 'test', { vpc });
+ test1.addIngressRule(Peer.anyIpv4(), Port.allTraffic());
+ const test2 = new SecurityGroup(this, 'test', { vpc });
+ test2.addIngressRule(Peer.anyIpv4(), Port.allTraffic());
+ NagSuppressions.addResourceSuppressions(
+ [test1, test2],
+ [{ id: 'AwsSolutions-EC23', reason: 'lorem ipsum' }]
+ );
+ }
+}
+```
+
+</details><details>
+ <summary>Example 3) Child Constructs</summary>
+
+```python
+import { User, PolicyStatement } from 'aws-cdk-lib/aws-iam';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+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 4) Stack Level </summary>
+
+```python
+import { App, Aspects } from 'aws-cdk-lib';
+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 5) 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-lib/aws-s3';
+import { BucketDeployment } from 'aws-cdk-lib/aws-s3-deployment';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+import { NagSuppressions } from 'cdk-nag';
+
+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 6) 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] 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
+
+```python
+import { User } from 'aws-cdk-lib/aws-iam';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+import { NagSuppressions } from 'cdk-nag';
+
+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
+
+```bash
+[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.
+```
+
+</details>
+
+## Suppressing `aws-cdk-lib/pipelines` Violations
+
+The [aws-cdk-lib/pipelines.CodePipeline](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.CodePipeline.html) construct and its child constructs are not guaranteed to be "Visited" by `Aspects`, as they are not added during the "Construction" phase of the [cdk lifecycle](https://docs.aws.amazon.com/cdk/v2/guide/apps.html#lifecycle). Because of this behavior, you may experience problems such as rule violations not appearing or the inability to suppress violations on these constructs.
+
+You can remediate these rule violation and suppression problems by forcing the pipeline construct creation forward by calling `.buildPipeline()` on your `CodePipeline` object. Otherwise you may see errors such as:
+
+```
+Error: Suppression path "/this/construct/path" did not match any resource. This can occur when a resource does not exist or if a suppression is applied before a resource is created.
+```
+
+See [this issue](https://github.com/aws/aws-cdk/issues/18440) for more information.
+
+<details>
+ <summary>Example) Supressing Violations in Pipelines</summary>
+
+`example-app.ts`
+
+```python
+import { App, Aspects } from 'aws-cdk-lib';
+import { AwsSolutionsChecks } from 'cdk-nag';
+import { ExamplePipeline } from '../lib/example-pipeline';
+
+const app = new App();
+new ExamplePipeline(app, 'example-cdk-pipeline');
+Aspects.of(app).add(new AwsSolutionsChecks({ verbose: true }));
+app.synth();
+```
+
+`example-pipeline.ts`
+
+```python
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Repository } from 'aws-cdk-lib/aws-codecommit';
+import {
+ CodePipeline,
+ CodePipelineSource,
+ ShellStep,
+} from 'aws-cdk-lib/pipelines';
+import { NagSuppressions } from 'cdk-nag';
+import { Construct } from 'constructs';
+
+export class ExamplePipeline extends Stack {
+ constructor(scope: Construct, id: string, props?: StackProps) {
+ super(scope, id, props);
+
+ const exampleSynth = new ShellStep('ExampleSynth', {
+ commands: ['yarn build --frozen-lockfile'],
+ input: CodePipelineSource.codeCommit(
+ new Repository(this, 'ExampleRepo', { repositoryName: 'ExampleRepo' }),
+ 'main'
+ ),
+ });
+
+ const ExamplePipeline = new CodePipeline(this, 'ExamplePipeline', {
+ synth: exampleSynth,
+ });
+
+ // Force the pipeline construct creation forward before applying suppressions.
+ // @See https://github.com/aws/aws-cdk/issues/18440
+ ExamplePipeline.buildPipeline();
+
+ // The path suppression will error if you comment out "ExamplePipeline.buildPipeline();""
+ NagSuppressions.addResourceSuppressionsByPath(
+ this,
+ '/example-cdk-pipeline/ExamplePipeline/Pipeline/ArtifactsBucket/Resource',
+ [
+ {
+ id: 'AwsSolutions-S1',
+ reason: 'Because I said so',
+ },
+ ]
+ );
+ }
+}
+```
+
+</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 suppress the issue like in the following example.
+
+<details>
+ <summary>Example) Property Overrides</summary>
+
+```python
+import {
+ Instance,
+ InstanceType,
+ InstanceClass,
+ MachineImage,
+ Vpc,
+ CfnInstance,
+} from 'aws-cdk-lib/aws-ec2';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+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.',
+ },
+ ]);
+ }
+}
+```
+
+</details>
+
+## Conditionally Ignoring Suppressions
+
+You can optionally create a condition that prevents certain rules from being suppressed. You can create conditions for any variety of reasons. Examples include a condition that always ignores a suppression, a condition that ignores a suppression based on the date, a condition that ignores a suppression based on the reason. You can read [the developer docs](./docs/IgnoreSuppressionConditions.md) for more information on creating your own conditions.
+
+<details>
+ <summary>Example) Using the pre-built `SuppressionIgnoreErrors` class to ignore suppressions on any `Error` level rules.</summary>
+
+```python
+import { App, Aspects } from 'aws-cdk-lib';
+import { CdkTestStack } from '../lib/cdk-test-stack';
+import { AwsSolutionsChecks, SuppressionIgnoreErrors } from 'cdk-nag';
+
+const app = new App();
+new CdkTestStack(app, 'CdkNagDemo');
+// Ignore Suppressions on any errors
+Aspects.of(app).add(
+ new AwsSolutionsChecks({
+ suppressionIgnoreCondition: new SuppressionIgnoreErrors(),
+ })
+);
+```
+
+</details>
+
+## Customizing Logging
+
+`NagLogger`s give `NagPack` authors and users the ability to create their own custom reporting mechanisms. All pre-built `NagPacks`come with the `AnnotationsLogger`and the `NagReportLogger` (with CSV reports) enabled by default.
+
+See the [NagLogger](./docs/NagLogger.md) developer docs for more information.
+
+<details>
+ <summary>Example) Adding the `ExtremelyHelpfulConsoleLogger` example from the NagLogger docs</summary>
+
+```python
+import { App, Aspects } from 'aws-cdk-lib';
+import { CdkTestStack } from '../lib/cdk-test-stack';
+import { ExtremelyHelpfulConsoleLogger } from './docs/NagLogger';
+import { AwsSolutionsChecks } from 'cdk-nag';
+
+const app = new App();
+new CdkTestStack(app, 'CdkNagDemo');
+Aspects.of(app).add(
+ new AwsSolutionsChecks({
+ additionalLoggers: [new ExtremelyHelpfulConsoleLogger()],
+ })
+);
+```
+
+</details>
+
+## 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_install) module.
+
+<details>
+ <summary>Example 1) CloudFormation template with suppression</summary>
+
+Sample CloudFormation template with suppression
+
+```json
+{
+ "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
+
+```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');
+Aspects.of(app).add(new AwsSolutionsChecks());
+```
+
+Sample Stack with imported template
+
+```python
+import { CfnInclude } from 'aws-cdk-lib/cloudformation-include';
+import { NagSuppressions } from 'cdk-nag';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+
+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',
+ },
+ ]
+ );
+ }
+}
+```
+
+</details><details>
+ <summary>Example 2) CloudFormation template with granular suppressions</summary>
+
+Sample CloudFormation template with suppression
+
+```json
+{
+ "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
+
+```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');
+Aspects.of(app).add(new AwsSolutionsChecks());
+```
+
+Sample Stack with imported template
+
+```python
+import { CfnInclude } from 'aws-cdk-lib/cloudformation-include';
+import { NagSuppressions } from 'cdk-nag';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+
+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*'],
+ },
+ ]
+ );
+ }
+}
+```
+
+</details>
+
+## Contributing
+
+See [CONTRIBUTING](./CONTRIBUTING.md) for more information.
+
+## License
+
+This project is licensed under the Apache-2.0 License.
+
+
+%package -n python3-cdk-nag
+Summary: Check CDK v2 applications for best practices using a combination on available rule packs.
+Provides: python-cdk-nag
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-cdk-nag
+<!--
+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)
+
+[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>
+
+```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>
+
+## Suppressing a Rule
+
+<details>
+ <summary>Example 1) Default Construct</summary>
+
+```python
+import { SecurityGroup, Vpc, Peer, Port } from 'aws-cdk-lib/aws-ec2';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+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) On Multiple Constructs</summary>
+
+```python
+import { SecurityGroup, Vpc, Peer, Port } from 'aws-cdk-lib/aws-ec2';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+import { NagSuppressions } from 'cdk-nag';
+
+export class CdkTestStack extends Stack {
+ constructor(scope: Construct, id: string, props?: StackProps) {
+ super(scope, id, props);
+ const vpc = new Vpc(this, 'vpc');
+ const test1 = new SecurityGroup(this, 'test', { vpc });
+ test1.addIngressRule(Peer.anyIpv4(), Port.allTraffic());
+ const test2 = new SecurityGroup(this, 'test', { vpc });
+ test2.addIngressRule(Peer.anyIpv4(), Port.allTraffic());
+ NagSuppressions.addResourceSuppressions(
+ [test1, test2],
+ [{ id: 'AwsSolutions-EC23', reason: 'lorem ipsum' }]
+ );
+ }
+}
+```
+
+</details><details>
+ <summary>Example 3) Child Constructs</summary>
+
+```python
+import { User, PolicyStatement } from 'aws-cdk-lib/aws-iam';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+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 4) Stack Level </summary>
+
+```python
+import { App, Aspects } from 'aws-cdk-lib';
+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 5) 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-lib/aws-s3';
+import { BucketDeployment } from 'aws-cdk-lib/aws-s3-deployment';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+import { NagSuppressions } from 'cdk-nag';
+
+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 6) 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] 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
+
+```python
+import { User } from 'aws-cdk-lib/aws-iam';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+import { NagSuppressions } from 'cdk-nag';
+
+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
+
+```bash
+[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.
+```
+
+</details>
+
+## Suppressing `aws-cdk-lib/pipelines` Violations
+
+The [aws-cdk-lib/pipelines.CodePipeline](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.CodePipeline.html) construct and its child constructs are not guaranteed to be "Visited" by `Aspects`, as they are not added during the "Construction" phase of the [cdk lifecycle](https://docs.aws.amazon.com/cdk/v2/guide/apps.html#lifecycle). Because of this behavior, you may experience problems such as rule violations not appearing or the inability to suppress violations on these constructs.
+
+You can remediate these rule violation and suppression problems by forcing the pipeline construct creation forward by calling `.buildPipeline()` on your `CodePipeline` object. Otherwise you may see errors such as:
+
+```
+Error: Suppression path "/this/construct/path" did not match any resource. This can occur when a resource does not exist or if a suppression is applied before a resource is created.
+```
+
+See [this issue](https://github.com/aws/aws-cdk/issues/18440) for more information.
+
+<details>
+ <summary>Example) Supressing Violations in Pipelines</summary>
+
+`example-app.ts`
+
+```python
+import { App, Aspects } from 'aws-cdk-lib';
+import { AwsSolutionsChecks } from 'cdk-nag';
+import { ExamplePipeline } from '../lib/example-pipeline';
+
+const app = new App();
+new ExamplePipeline(app, 'example-cdk-pipeline');
+Aspects.of(app).add(new AwsSolutionsChecks({ verbose: true }));
+app.synth();
+```
+
+`example-pipeline.ts`
+
+```python
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Repository } from 'aws-cdk-lib/aws-codecommit';
+import {
+ CodePipeline,
+ CodePipelineSource,
+ ShellStep,
+} from 'aws-cdk-lib/pipelines';
+import { NagSuppressions } from 'cdk-nag';
+import { Construct } from 'constructs';
+
+export class ExamplePipeline extends Stack {
+ constructor(scope: Construct, id: string, props?: StackProps) {
+ super(scope, id, props);
+
+ const exampleSynth = new ShellStep('ExampleSynth', {
+ commands: ['yarn build --frozen-lockfile'],
+ input: CodePipelineSource.codeCommit(
+ new Repository(this, 'ExampleRepo', { repositoryName: 'ExampleRepo' }),
+ 'main'
+ ),
+ });
+
+ const ExamplePipeline = new CodePipeline(this, 'ExamplePipeline', {
+ synth: exampleSynth,
+ });
+
+ // Force the pipeline construct creation forward before applying suppressions.
+ // @See https://github.com/aws/aws-cdk/issues/18440
+ ExamplePipeline.buildPipeline();
+
+ // The path suppression will error if you comment out "ExamplePipeline.buildPipeline();""
+ NagSuppressions.addResourceSuppressionsByPath(
+ this,
+ '/example-cdk-pipeline/ExamplePipeline/Pipeline/ArtifactsBucket/Resource',
+ [
+ {
+ id: 'AwsSolutions-S1',
+ reason: 'Because I said so',
+ },
+ ]
+ );
+ }
+}
+```
+
+</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 suppress the issue like in the following example.
+
+<details>
+ <summary>Example) Property Overrides</summary>
+
+```python
+import {
+ Instance,
+ InstanceType,
+ InstanceClass,
+ MachineImage,
+ Vpc,
+ CfnInstance,
+} from 'aws-cdk-lib/aws-ec2';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+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.',
+ },
+ ]);
+ }
+}
+```
+
+</details>
+
+## Conditionally Ignoring Suppressions
+
+You can optionally create a condition that prevents certain rules from being suppressed. You can create conditions for any variety of reasons. Examples include a condition that always ignores a suppression, a condition that ignores a suppression based on the date, a condition that ignores a suppression based on the reason. You can read [the developer docs](./docs/IgnoreSuppressionConditions.md) for more information on creating your own conditions.
+
+<details>
+ <summary>Example) Using the pre-built `SuppressionIgnoreErrors` class to ignore suppressions on any `Error` level rules.</summary>
+
+```python
+import { App, Aspects } from 'aws-cdk-lib';
+import { CdkTestStack } from '../lib/cdk-test-stack';
+import { AwsSolutionsChecks, SuppressionIgnoreErrors } from 'cdk-nag';
+
+const app = new App();
+new CdkTestStack(app, 'CdkNagDemo');
+// Ignore Suppressions on any errors
+Aspects.of(app).add(
+ new AwsSolutionsChecks({
+ suppressionIgnoreCondition: new SuppressionIgnoreErrors(),
+ })
+);
+```
+
+</details>
+
+## Customizing Logging
+
+`NagLogger`s give `NagPack` authors and users the ability to create their own custom reporting mechanisms. All pre-built `NagPacks`come with the `AnnotationsLogger`and the `NagReportLogger` (with CSV reports) enabled by default.
+
+See the [NagLogger](./docs/NagLogger.md) developer docs for more information.
+
+<details>
+ <summary>Example) Adding the `ExtremelyHelpfulConsoleLogger` example from the NagLogger docs</summary>
+
+```python
+import { App, Aspects } from 'aws-cdk-lib';
+import { CdkTestStack } from '../lib/cdk-test-stack';
+import { ExtremelyHelpfulConsoleLogger } from './docs/NagLogger';
+import { AwsSolutionsChecks } from 'cdk-nag';
+
+const app = new App();
+new CdkTestStack(app, 'CdkNagDemo');
+Aspects.of(app).add(
+ new AwsSolutionsChecks({
+ additionalLoggers: [new ExtremelyHelpfulConsoleLogger()],
+ })
+);
+```
+
+</details>
+
+## 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_install) module.
+
+<details>
+ <summary>Example 1) CloudFormation template with suppression</summary>
+
+Sample CloudFormation template with suppression
+
+```json
+{
+ "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
+
+```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');
+Aspects.of(app).add(new AwsSolutionsChecks());
+```
+
+Sample Stack with imported template
+
+```python
+import { CfnInclude } from 'aws-cdk-lib/cloudformation-include';
+import { NagSuppressions } from 'cdk-nag';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+
+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',
+ },
+ ]
+ );
+ }
+}
+```
+
+</details><details>
+ <summary>Example 2) CloudFormation template with granular suppressions</summary>
+
+Sample CloudFormation template with suppression
+
+```json
+{
+ "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
+
+```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');
+Aspects.of(app).add(new AwsSolutionsChecks());
+```
+
+Sample Stack with imported template
+
+```python
+import { CfnInclude } from 'aws-cdk-lib/cloudformation-include';
+import { NagSuppressions } from 'cdk-nag';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+
+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*'],
+ },
+ ]
+ );
+ }
+}
+```
+
+</details>
+
+## Contributing
+
+See [CONTRIBUTING](./CONTRIBUTING.md) for more information.
+
+## License
+
+This project is licensed under the Apache-2.0 License.
+
+
+%package help
+Summary: Development documents and examples for cdk-nag
+Provides: python3-cdk-nag-doc
+%description help
+<!--
+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)
+
+[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>
+
+```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>
+
+## Suppressing a Rule
+
+<details>
+ <summary>Example 1) Default Construct</summary>
+
+```python
+import { SecurityGroup, Vpc, Peer, Port } from 'aws-cdk-lib/aws-ec2';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+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) On Multiple Constructs</summary>
+
+```python
+import { SecurityGroup, Vpc, Peer, Port } from 'aws-cdk-lib/aws-ec2';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+import { NagSuppressions } from 'cdk-nag';
+
+export class CdkTestStack extends Stack {
+ constructor(scope: Construct, id: string, props?: StackProps) {
+ super(scope, id, props);
+ const vpc = new Vpc(this, 'vpc');
+ const test1 = new SecurityGroup(this, 'test', { vpc });
+ test1.addIngressRule(Peer.anyIpv4(), Port.allTraffic());
+ const test2 = new SecurityGroup(this, 'test', { vpc });
+ test2.addIngressRule(Peer.anyIpv4(), Port.allTraffic());
+ NagSuppressions.addResourceSuppressions(
+ [test1, test2],
+ [{ id: 'AwsSolutions-EC23', reason: 'lorem ipsum' }]
+ );
+ }
+}
+```
+
+</details><details>
+ <summary>Example 3) Child Constructs</summary>
+
+```python
+import { User, PolicyStatement } from 'aws-cdk-lib/aws-iam';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+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 4) Stack Level </summary>
+
+```python
+import { App, Aspects } from 'aws-cdk-lib';
+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 5) 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-lib/aws-s3';
+import { BucketDeployment } from 'aws-cdk-lib/aws-s3-deployment';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+import { NagSuppressions } from 'cdk-nag';
+
+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 6) 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] 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
+
+```python
+import { User } from 'aws-cdk-lib/aws-iam';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+import { NagSuppressions } from 'cdk-nag';
+
+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
+
+```bash
+[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.
+```
+
+</details>
+
+## Suppressing `aws-cdk-lib/pipelines` Violations
+
+The [aws-cdk-lib/pipelines.CodePipeline](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.CodePipeline.html) construct and its child constructs are not guaranteed to be "Visited" by `Aspects`, as they are not added during the "Construction" phase of the [cdk lifecycle](https://docs.aws.amazon.com/cdk/v2/guide/apps.html#lifecycle). Because of this behavior, you may experience problems such as rule violations not appearing or the inability to suppress violations on these constructs.
+
+You can remediate these rule violation and suppression problems by forcing the pipeline construct creation forward by calling `.buildPipeline()` on your `CodePipeline` object. Otherwise you may see errors such as:
+
+```
+Error: Suppression path "/this/construct/path" did not match any resource. This can occur when a resource does not exist or if a suppression is applied before a resource is created.
+```
+
+See [this issue](https://github.com/aws/aws-cdk/issues/18440) for more information.
+
+<details>
+ <summary>Example) Supressing Violations in Pipelines</summary>
+
+`example-app.ts`
+
+```python
+import { App, Aspects } from 'aws-cdk-lib';
+import { AwsSolutionsChecks } from 'cdk-nag';
+import { ExamplePipeline } from '../lib/example-pipeline';
+
+const app = new App();
+new ExamplePipeline(app, 'example-cdk-pipeline');
+Aspects.of(app).add(new AwsSolutionsChecks({ verbose: true }));
+app.synth();
+```
+
+`example-pipeline.ts`
+
+```python
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Repository } from 'aws-cdk-lib/aws-codecommit';
+import {
+ CodePipeline,
+ CodePipelineSource,
+ ShellStep,
+} from 'aws-cdk-lib/pipelines';
+import { NagSuppressions } from 'cdk-nag';
+import { Construct } from 'constructs';
+
+export class ExamplePipeline extends Stack {
+ constructor(scope: Construct, id: string, props?: StackProps) {
+ super(scope, id, props);
+
+ const exampleSynth = new ShellStep('ExampleSynth', {
+ commands: ['yarn build --frozen-lockfile'],
+ input: CodePipelineSource.codeCommit(
+ new Repository(this, 'ExampleRepo', { repositoryName: 'ExampleRepo' }),
+ 'main'
+ ),
+ });
+
+ const ExamplePipeline = new CodePipeline(this, 'ExamplePipeline', {
+ synth: exampleSynth,
+ });
+
+ // Force the pipeline construct creation forward before applying suppressions.
+ // @See https://github.com/aws/aws-cdk/issues/18440
+ ExamplePipeline.buildPipeline();
+
+ // The path suppression will error if you comment out "ExamplePipeline.buildPipeline();""
+ NagSuppressions.addResourceSuppressionsByPath(
+ this,
+ '/example-cdk-pipeline/ExamplePipeline/Pipeline/ArtifactsBucket/Resource',
+ [
+ {
+ id: 'AwsSolutions-S1',
+ reason: 'Because I said so',
+ },
+ ]
+ );
+ }
+}
+```
+
+</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 suppress the issue like in the following example.
+
+<details>
+ <summary>Example) Property Overrides</summary>
+
+```python
+import {
+ Instance,
+ InstanceType,
+ InstanceClass,
+ MachineImage,
+ Vpc,
+ CfnInstance,
+} from 'aws-cdk-lib/aws-ec2';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+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.',
+ },
+ ]);
+ }
+}
+```
+
+</details>
+
+## Conditionally Ignoring Suppressions
+
+You can optionally create a condition that prevents certain rules from being suppressed. You can create conditions for any variety of reasons. Examples include a condition that always ignores a suppression, a condition that ignores a suppression based on the date, a condition that ignores a suppression based on the reason. You can read [the developer docs](./docs/IgnoreSuppressionConditions.md) for more information on creating your own conditions.
+
+<details>
+ <summary>Example) Using the pre-built `SuppressionIgnoreErrors` class to ignore suppressions on any `Error` level rules.</summary>
+
+```python
+import { App, Aspects } from 'aws-cdk-lib';
+import { CdkTestStack } from '../lib/cdk-test-stack';
+import { AwsSolutionsChecks, SuppressionIgnoreErrors } from 'cdk-nag';
+
+const app = new App();
+new CdkTestStack(app, 'CdkNagDemo');
+// Ignore Suppressions on any errors
+Aspects.of(app).add(
+ new AwsSolutionsChecks({
+ suppressionIgnoreCondition: new SuppressionIgnoreErrors(),
+ })
+);
+```
+
+</details>
+
+## Customizing Logging
+
+`NagLogger`s give `NagPack` authors and users the ability to create their own custom reporting mechanisms. All pre-built `NagPacks`come with the `AnnotationsLogger`and the `NagReportLogger` (with CSV reports) enabled by default.
+
+See the [NagLogger](./docs/NagLogger.md) developer docs for more information.
+
+<details>
+ <summary>Example) Adding the `ExtremelyHelpfulConsoleLogger` example from the NagLogger docs</summary>
+
+```python
+import { App, Aspects } from 'aws-cdk-lib';
+import { CdkTestStack } from '../lib/cdk-test-stack';
+import { ExtremelyHelpfulConsoleLogger } from './docs/NagLogger';
+import { AwsSolutionsChecks } from 'cdk-nag';
+
+const app = new App();
+new CdkTestStack(app, 'CdkNagDemo');
+Aspects.of(app).add(
+ new AwsSolutionsChecks({
+ additionalLoggers: [new ExtremelyHelpfulConsoleLogger()],
+ })
+);
+```
+
+</details>
+
+## 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_install) module.
+
+<details>
+ <summary>Example 1) CloudFormation template with suppression</summary>
+
+Sample CloudFormation template with suppression
+
+```json
+{
+ "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
+
+```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');
+Aspects.of(app).add(new AwsSolutionsChecks());
+```
+
+Sample Stack with imported template
+
+```python
+import { CfnInclude } from 'aws-cdk-lib/cloudformation-include';
+import { NagSuppressions } from 'cdk-nag';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+
+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',
+ },
+ ]
+ );
+ }
+}
+```
+
+</details><details>
+ <summary>Example 2) CloudFormation template with granular suppressions</summary>
+
+Sample CloudFormation template with suppression
+
+```json
+{
+ "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
+
+```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');
+Aspects.of(app).add(new AwsSolutionsChecks());
+```
+
+Sample Stack with imported template
+
+```python
+import { CfnInclude } from 'aws-cdk-lib/cloudformation-include';
+import { NagSuppressions } from 'cdk-nag';
+import { Stack, StackProps } from 'aws-cdk-lib';
+import { Construct } from 'constructs';
+
+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*'],
+ },
+ ]
+ );
+ }
+}
+```
+
+</details>
+
+## Contributing
+
+See [CONTRIBUTING](./CONTRIBUTING.md) for more information.
+
+## License
+
+This project is licensed under the Apache-2.0 License.
+
+
+%prep
+%autosetup -n cdk-nag-2.25.8
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-cdk-nag -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Tue Apr 11 2023 Python_Bot <Python_Bot@openeuler.org> - 2.25.8-1
+- Package Spec generated
diff --git a/sources b/sources
new file mode 100644
index 0000000..8a4aec7
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+02ee2a3cfddce317787598dcccd53ba8 cdk-nag-2.25.8.tar.gz