diff --git a/.projenrc.js b/.projenrc.js
index 869e2627a8..eecfd53868 100644
--- a/.projenrc.js
+++ b/.projenrc.js
@@ -105,6 +105,7 @@ const project = new AwsCdkConstructLibrary({
});
project.package.addField('resolutions', {
'ansi-regex': '^5.0.1',
+ 'json-schema': '^0.4.0',
});
project.package.addField('prettier', {
singleQuote: true,
diff --git a/API.md b/API.md
index 468bdc6fbf..7c88300169 100644
--- a/API.md
+++ b/API.md
@@ -33,6 +33,7 @@ Name|Description
Name|Description
----|-----------
[NagMessageLevel](#cdk-nag-nagmessagelevel)|The level of the message that the rule applies.
+[NagRuleCompliance](#cdk-nag-nagrulecompliance)|The compliance level of a resource in relation to a rule.
@@ -54,6 +55,7 @@ new AwsSolutionsChecks(props?: NagPackProps)
* **props** ([NagPackProps](#cdk-nag-nagpackprops)
) *No description*
* **logIgnores** (boolean
) Whether or not to log triggered rules that have been suppressed as informational messages (default: false). __*Optional*__
+ * **reports** (boolean
) Whether or not to generate CSV compliance reports for applied Stacks in the App's output directory (default: true). __*Optional*__
* **verbose** (boolean
) Whether or not to enable extended explanatory descriptions on warning, error, and logged ignore messages (default: false). __*Optional*__
@@ -95,6 +97,7 @@ new HIPAASecurityChecks(props?: NagPackProps)
* **props** ([NagPackProps](#cdk-nag-nagpackprops)
) *No description*
* **logIgnores** (boolean
) Whether or not to log triggered rules that have been suppressed as informational messages (default: false). __*Optional*__
+ * **reports** (boolean
) Whether or not to generate CSV compliance reports for applied Stacks in the App's output directory (default: true). __*Optional*__
* **verbose** (boolean
) Whether or not to enable extended explanatory descriptions on warning, error, and logged ignore messages (default: false). __*Optional*__
@@ -136,6 +139,7 @@ new NIST80053R4Checks(props?: NagPackProps)
* **props** ([NagPackProps](#cdk-nag-nagpackprops)
) *No description*
* **logIgnores** (boolean
) Whether or not to log triggered rules that have been suppressed as informational messages (default: false). __*Optional*__
+ * **reports** (boolean
) Whether or not to generate CSV compliance reports for applied Stacks in the App's output directory (default: true). __*Optional*__
* **verbose** (boolean
) Whether or not to enable extended explanatory descriptions on warning, error, and logged ignore messages (default: false). __*Optional*__
@@ -177,6 +181,7 @@ new NIST80053R5Checks(props?: NagPackProps)
* **props** ([NagPackProps](#cdk-nag-nagpackprops)
) *No description*
* **logIgnores** (boolean
) Whether or not to log triggered rules that have been suppressed as informational messages (default: false). __*Optional*__
+ * **reports** (boolean
) Whether or not to generate CSV compliance reports for applied Stacks in the App's output directory (default: true). __*Optional*__
* **verbose** (boolean
) Whether or not to enable extended explanatory descriptions on warning, error, and logged ignore messages (default: false). __*Optional*__
@@ -216,6 +221,7 @@ new NagPack(props?: NagPackProps)
* **props** ([NagPackProps](#cdk-nag-nagpackprops)
) *No description*
* **logIgnores** (boolean
) Whether or not to log triggered rules that have been suppressed as informational messages (default: false). __*Optional*__
+ * **reports** (boolean
) Whether or not to generate CSV compliance reports for applied Stacks in the App's output directory (default: true). __*Optional*__
* **verbose** (boolean
) Whether or not to enable extended explanatory descriptions on warning, error, and logged ignore messages (default: false). __*Optional*__
@@ -228,17 +234,33 @@ Name | Type | Description
**logIgnores** | boolean
|
**packName** | string
|
**readPackName** | string
|
+**readReportStacks** | Array
|
+**reportStacks** | Array
|
+**reports** | boolean
|
**verbose** | boolean
|
### Methods
-#### applyRule(params)
+#### visit(node)
+
+All aspects can visit an IConstruct.
+
+```ts
+visit(node: IConstruct): void
+```
+
+* **node** ([IConstruct](#aws-cdk-core-iconstruct)
) *No description*
+
+
+
+
+#### protected applyRule(params)
Create a rule to be used in the NagPack.
```ts
-applyRule(params: IApplyRule): void
+protected applyRule(params: IApplyRule): void
```
* **params** ([IApplyRule](#cdk-nag-iapplyrule)
) The.
@@ -246,15 +268,63 @@ applyRule(params: IApplyRule): void
-#### visit(node)
+#### protected createComplianceReportLine(params, ruleId, compliance, explanation?)
-All aspects can visit an IConstruct.
+Helper function to create a line for the compliance report.
```ts
-visit(node: IConstruct): void
+protected createComplianceReportLine(params: IApplyRule, ruleId: string, compliance: NagRuleCompliance | string, explanation?: string): string
```
-* **node** ([IConstruct](#aws-cdk-core-iconstruct)
) *No description*
+* **params** ([IApplyRule](#cdk-nag-iapplyrule)
) The.
+* **ruleId** (string
) The id of the rule.
+* **compliance** ([NagRuleCompliance](#cdk-nag-nagrulecompliance) | string
) The compliance status of the rule.
+* **explanation** (string
) The explanation for suppressed rules.
+
+__Returns__:
+* string
+
+#### protected createMessage(ruleId, info, explanation)
+
+The message to output to the console when a rule is triggered.
+
+```ts
+protected createMessage(ruleId: string, info: string, explanation: string): string
+```
+
+* **ruleId** (string
) The id of the rule.
+* **info** (string
) Why the rule was triggered.
+* **explanation** (string
) Why the rule exists.
+
+__Returns__:
+* string
+
+#### protected ignoreRule(ignores, ruleId)
+
+Check whether a specific rule should be ignored.
+
+```ts
+protected ignoreRule(ignores: Array, ruleId: string): string
+```
+
+* **ignores** (Array<[NagPackSuppression](#cdk-nag-nagpacksuppression)>
) The ignores listed in cdk-nag metadata.
+* **ruleId** (string
) The id of the rule to ignore.
+
+__Returns__:
+* string
+
+#### protected writeToStackComplianceReport(params, ruleId, compliance, explanation?)
+
+Write a line to the rule packs compliance report for the resource's Stack.
+
+```ts
+protected writeToStackComplianceReport(params: IApplyRule, ruleId: string, compliance: NagRuleCompliance | string, explanation?: string): void
+```
+
+* **params** ([IApplyRule](#cdk-nag-iapplyrule)
) The.
+* **ruleId** (string
) The id of the rule.
+* **compliance** ([NagRuleCompliance](#cdk-nag-nagrulecompliance) | string
) The compliance status of the rule.
+* **explanation** (string
) The explanation for suppressed rules.
@@ -346,6 +416,7 @@ new PCIDSS321Checks(props?: NagPackProps)
* **props** ([NagPackProps](#cdk-nag-nagpackprops)
) *No description*
* **logIgnores** (boolean
) Whether or not to log triggered rules that have been suppressed as informational messages (default: false). __*Optional*__
+ * **reports** (boolean
) Whether or not to generate CSV compliance reports for applied Stacks in the App's output directory (default: true). __*Optional*__
* **verbose** (boolean
) Whether or not to enable extended explanatory descriptions on warning, error, and logged ignore messages (default: false). __*Optional*__
@@ -391,13 +462,13 @@ Name | Type | Description
The callback to the rule.
```ts
-rule(node: CfnResource): boolean
+rule(node: CfnResource): NagRuleCompliance
```
* **node** ([CfnResource](#aws-cdk-core-cfnresource)
) The CfnResource to check.
__Returns__:
-* boolean
+* [NagRuleCompliance](#cdk-nag-nagrulecompliance)
@@ -411,6 +482,7 @@ Interface for creating a Nag rule pack.
Name | Type | Description
-----|------|-------------
**logIgnores**? | boolean
| Whether or not to log triggered rules that have been suppressed as informational messages (default: false).
__*Optional*__
+**reports**? | boolean
| Whether or not to generate CSV compliance reports for applied Stacks in the App's output directory (default: true).
__*Optional*__
**verbose**? | boolean
| Whether or not to enable extended explanatory descriptions on warning, error, and logged ignore messages (default: false).
__*Optional*__
@@ -439,3 +511,14 @@ Name | Description
**ERROR** |
+## enum NagRuleCompliance
+
+The compliance level of a resource in relation to a rule.
+
+Name | Description
+-----|-----
+**COMPLIANT** |
+**NON_COMPLIANT** |
+**NOT_APPLICABLE** |
+
+
diff --git a/README.md b/README.md
index 2a77b585de..9b9469d1cd 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,8 @@ See [RULES](./RULES.md) for more information on all the available packs.
## Usage
+For a full list of options See `NagPackProps` in the [API.md](./API.md#struct-nagpackprops)
+
cdk
diff --git a/package.json b/package.json
index b91486806a..b633c70b2c 100644
--- a/package.json
+++ b/package.json
@@ -240,7 +240,8 @@
}
},
"resolutions": {
- "ansi-regex": "^5.0.1"
+ "ansi-regex": "^5.0.1",
+ "json-schema": "^0.4.0"
},
"prettier": {
"singleQuote": true,
diff --git a/src/nag-pack.ts b/src/nag-pack.ts
index 9f527e7322..1046dffb69 100644
--- a/src/nag-pack.ts
+++ b/src/nag-pack.ts
@@ -2,12 +2,15 @@
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
+import { appendFileSync, writeFileSync } from 'fs';
+import { join } from 'path';
import {
IAspect,
IConstruct,
Annotations,
CfnResource,
Stack,
+ App,
} from '@aws-cdk/core';
import { NagPackSuppression } from './nag-suppressions';
@@ -27,6 +30,11 @@ export interface NagPackProps {
* Whether or not to log triggered rules that have been suppressed as informational messages (default: false).
*/
readonly logIgnores?: boolean;
+
+ /**
+ * Whether or not to generate CSV compliance reports for applied Stacks in the App's output directory (default: true).
+ */
+ readonly reports?: boolean;
}
/**
@@ -57,15 +65,24 @@ export interface IApplyRule {
* The callback to the rule.
* @param node The CfnResource to check.
*/
- rule(node: CfnResource): boolean;
+ rule(node: CfnResource): NagRuleCompliance;
}
/**
* The level of the message that the rule applies.
*/
export enum NagMessageLevel {
- WARN,
- ERROR,
+ WARN = 'Warning',
+ ERROR = 'Error',
+}
+
+/**
+ * The compliance level of a resource in relation to a rule.
+ */
+export enum NagRuleCompliance {
+ COMPLIANT = 'Compliant',
+ NON_COMPLIANT = 'Non-Compliant',
+ NOT_APPLICABLE = 'N/A',
}
/**
@@ -74,6 +91,8 @@ export enum NagMessageLevel {
export abstract class NagPack implements IAspect {
protected verbose: boolean;
protected logIgnores: boolean;
+ protected reports: boolean;
+ protected reportStacks = new Array();
protected packName = '';
constructor(props?: NagPackProps) {
@@ -83,11 +102,16 @@ export abstract class NagPack implements IAspect {
props == undefined || props.logIgnores == undefined
? false
: props.logIgnores;
+ this.reports =
+ props == undefined || props.reports == undefined ? true : props.reports;
}
public get readPackName(): string {
return this.packName;
}
+ public get readReportStacks(): string[] {
+ return this.reportStacks;
+ }
/**
* All aspects can visit an IConstruct.
*/
@@ -97,7 +121,7 @@ export abstract class NagPack implements IAspect {
* Create a rule to be used in the NagPack.
* @param params The @IApplyRule interface with rule details.
*/
- public applyRule(params: IApplyRule): void {
+ protected applyRule(params: IApplyRule): void {
if (this.packName === '') {
throw Error(
'The NagPack does not have a pack name, therefore the rule could not be applied. Set a packName in the NagPack constructor.'
@@ -114,8 +138,22 @@ export abstract class NagPack implements IAspect {
: params.rule.name;
const ruleId = `${this.packName}-${ruleSuffix}`;
try {
- if (!params.rule(params.node)) {
+ const ruleCompliance = params.rule(params.node);
+ if (
+ this.reports === true &&
+ ruleCompliance === NagRuleCompliance.COMPLIANT
+ ) {
+ this.writeToStackComplianceReport(params, ruleId, ruleCompliance);
+ } else if (ruleCompliance === NagRuleCompliance.NON_COMPLIANT) {
const reason = this.ignoreRule(allIgnores, ruleId);
+ if (this.reports === true) {
+ this.writeToStackComplianceReport(
+ params,
+ ruleId,
+ ruleCompliance,
+ reason
+ );
+ }
if (reason) {
if (this.logIgnores === true) {
const message = this.createMessage(
@@ -140,6 +178,9 @@ export abstract class NagPack implements IAspect {
}
} catch (error) {
const reason = this.ignoreRule(allIgnores, VALIDATION_FAILURE_ID);
+ if (this.reports === true) {
+ this.writeToStackComplianceReport(params, ruleId, 'UNKNOWN', reason);
+ }
if (reason) {
if (this.logIgnores === true) {
const message = this.createMessage(
@@ -167,7 +208,7 @@ export abstract class NagPack implements IAspect {
* @param ruleId The id of the rule to ignore.
* @returns The reason the rule was ignored, or an empty string.
*/
- private ignoreRule(ignores: NagPackSuppression[], ruleId: string): string {
+ protected ignoreRule(ignores: NagPackSuppression[], ruleId: string): string {
for (let ignore of ignores) {
if (
ignore.id &&
@@ -195,7 +236,7 @@ export abstract class NagPack implements IAspect {
* @param explanation Why the rule exists.
* @returns The formatted message string.
*/
- private createMessage(
+ protected createMessage(
ruleId: string,
info: string,
explanation: string
@@ -203,6 +244,77 @@ export abstract class NagPack implements IAspect {
let message = `${ruleId}: ${info}`;
return this.verbose ? `${message} ${explanation}\n` : `${message}\n`;
}
+
+ /**
+ * Write a line to the rule packs compliance report for the resource's Stack
+ * @param params The @IApplyRule interface with rule details.
+ * @param ruleId The id of the rule.
+ * @param compliance The compliance status of the rule.
+ * @param explanation The explanation for suppressed rules.
+ */
+ protected writeToStackComplianceReport(
+ params: IApplyRule,
+ ruleId: string,
+ compliance:
+ | NagRuleCompliance.COMPLIANT
+ | NagRuleCompliance.NON_COMPLIANT
+ | 'UNKNOWN',
+ explanation: string = ''
+ ): void {
+ const line = this.createComplianceReportLine(
+ params,
+ ruleId,
+ compliance,
+ explanation
+ );
+ let outDir = App.of(params.node)?.outdir;
+ const fileName = `${this.packName}-${params.node.stack.stackName}-NagReport.csv`;
+ const filePath = join(outDir ? outDir : '', fileName);
+ if (!this.reportStacks.includes(fileName)) {
+ this.reportStacks.push(fileName);
+ writeFileSync(
+ filePath,
+ 'Rule ID,Resource ID,Compliance,Exception Reason,Rule Level,Rule Info\n'
+ );
+ }
+ appendFileSync(filePath, line);
+ }
+
+ /**
+ * Helper function to create a line for the compliance report
+ * @param params The @IApplyRule interface with rule details.
+ * @param ruleId The id of the rule.
+ * @param compliance The compliance status of the rule.
+ * @param explanation The explanation for suppressed rules.
+ */
+ protected createComplianceReportLine(
+ params: IApplyRule,
+ ruleId: string,
+ compliance:
+ | NagRuleCompliance.COMPLIANT
+ | NagRuleCompliance.NON_COMPLIANT
+ | 'UNKNOWN',
+ explanation: string = ''
+ ): string {
+ //| Rule ID | Resource ID | Compliance | Exception Reason | Rule Level | Rule Info
+ const line = Array();
+ line.push(ruleId);
+ line.push(params.node.node.path);
+ if (
+ (compliance === NagRuleCompliance.NON_COMPLIANT ||
+ compliance === 'UNKNOWN') &&
+ explanation !== ''
+ ) {
+ line.push('Suppressed');
+ line.push(explanation);
+ } else {
+ line.push(compliance);
+ line.push('N/A');
+ }
+ line.push(params.level);
+ line.push(params.info);
+ return line.map((i) => '"' + i.replace(/"/g, '""') + '"').join(',') + '\n';
+ }
}
/**
diff --git a/src/rules/apigw/APIGWAccessLogging.ts b/src/rules/apigw/APIGWAccessLogging.ts
index 30fb18e65c..389d688b49 100644
--- a/src/rules/apigw/APIGWAccessLogging.ts
+++ b/src/rules/apigw/APIGWAccessLogging.ts
@@ -6,37 +6,40 @@ import { parse } from 'path';
import { CfnStage } from '@aws-cdk/aws-apigateway';
import { CfnStage as CfnV2Stage } from '@aws-cdk/aws-apigatewayv2';
import { CfnResource, Stack } from '@aws-cdk/core';
-
+import { NagRuleCompliance } from '../../nag-pack';
/**
* APIs have access logging enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnStage) {
if (node.accessLogSetting == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const accessLogSetting = Stack.of(node).resolve(node.accessLogSetting);
if (
accessLogSetting.destinationArn == undefined ||
accessLogSetting.format == undefined
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnV2Stage) {
if (node.accessLogSettings == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const accessLogSetting = Stack.of(node).resolve(node.accessLogSettings);
if (
accessLogSetting.destinationArn == undefined ||
accessLogSetting.format == undefined
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/apigw/APIGWAssociatedWithWAF.ts b/src/rules/apigw/APIGWAssociatedWithWAF.ts
index d5ed3f9239..720b55add9 100644
--- a/src/rules/apigw/APIGWAssociatedWithWAF.ts
+++ b/src/rules/apigw/APIGWAssociatedWithWAF.ts
@@ -6,14 +6,17 @@ import { parse } from 'path';
import { CfnStage } from '@aws-cdk/aws-apigateway';
import { CfnWebACLAssociation } from '@aws-cdk/aws-wafv2';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* Rest API stages are associated with AWS WAFv2 web ACLs
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnStage) {
const stageLogicalId = resolveResourceFromInstrinsic(node, node.ref);
const stageName = resolveResourceFromInstrinsic(node, node.stageName);
@@ -35,10 +38,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/apigw/APIGWAuthorization.ts b/src/rules/apigw/APIGWAuthorization.ts
index df5d937e11..02f09b5fb6 100644
--- a/src/rules/apigw/APIGWAuthorization.ts
+++ b/src/rules/apigw/APIGWAuthorization.ts
@@ -6,14 +6,14 @@ import { parse } from 'path';
import { AuthorizationType, CfnMethod } from '@aws-cdk/aws-apigateway';
import { CfnRoute } from '@aws-cdk/aws-apigatewayv2';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* APIs implement authorization
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnMethod || node instanceof CfnRoute) {
const authorizationType = resolveIfPrimitive(
node,
@@ -23,10 +23,12 @@ export default Object.defineProperty(
authorizationType == undefined ||
authorizationType == AuthorizationType.NONE
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/apigw/APIGWCacheEnabledAndEncrypted.ts b/src/rules/apigw/APIGWCacheEnabledAndEncrypted.ts
index 829192b39f..7a68bcb3bd 100644
--- a/src/rules/apigw/APIGWCacheEnabledAndEncrypted.ts
+++ b/src/rules/apigw/APIGWCacheEnabledAndEncrypted.ts
@@ -5,16 +5,17 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnStage } from '@aws-cdk/aws-apigateway';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* All methods in API Gateway stages have caching enabled and encrypted
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnStage) {
if (node.methodSettings == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const methodSettings = Stack.of(node).resolve(node.methodSettings);
let found = false;
@@ -31,10 +32,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/apigw/APIGWExecutionLoggingEnabled.ts b/src/rules/apigw/APIGWExecutionLoggingEnabled.ts
index 831f76b6bf..37162cf77c 100644
--- a/src/rules/apigw/APIGWExecutionLoggingEnabled.ts
+++ b/src/rules/apigw/APIGWExecutionLoggingEnabled.ts
@@ -5,16 +5,17 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnStage, MethodLoggingLevel } from '@aws-cdk/aws-apigateway';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* API Gateway stages have logging enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnStage) {
if (node.methodSettings == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const methodSettings = Stack.of(node).resolve(node.methodSettings);
let found = false;
@@ -31,10 +32,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/apigw/APIGWRequestValidation.ts b/src/rules/apigw/APIGWRequestValidation.ts
index 1609658bca..d0bb8fc24f 100644
--- a/src/rules/apigw/APIGWRequestValidation.ts
+++ b/src/rules/apigw/APIGWRequestValidation.ts
@@ -5,14 +5,17 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnRequestValidator, CfnRestApi } from '@aws-cdk/aws-apigateway';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* Rest APIs have request validation enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnRestApi) {
const apiLogicalId = resolveResourceFromInstrinsic(node, node.ref);
let found = false;
@@ -25,10 +28,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/apigw/APIGWSSLEnabled.ts b/src/rules/apigw/APIGWSSLEnabled.ts
index 8a13745cd5..323c7a489a 100644
--- a/src/rules/apigw/APIGWSSLEnabled.ts
+++ b/src/rules/apigw/APIGWSSLEnabled.ts
@@ -5,19 +5,22 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnStage } from '@aws-cdk/aws-apigateway';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* API Gateway REST API stages are configured with SSL certificates
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnStage) {
if (node.clientCertificateId == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/apigw/APIGWXrayEnabled.ts b/src/rules/apigw/APIGWXrayEnabled.ts
index a4e823c883..4ee24fe338 100644
--- a/src/rules/apigw/APIGWXrayEnabled.ts
+++ b/src/rules/apigw/APIGWXrayEnabled.ts
@@ -5,20 +5,22 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnStage } from '@aws-cdk/aws-apigateway';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* API Gateway REST API stages have X-Ray tracing enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnStage) {
const tracingEnabled = resolveIfPrimitive(node, node.tracingEnabled);
if (tracingEnabled !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/appsync/AppSyncGraphQLRequestLogging.ts b/src/rules/appsync/AppSyncGraphQLRequestLogging.ts
index a61505c5ab..5e59a2355e 100644
--- a/src/rules/appsync/AppSyncGraphQLRequestLogging.ts
+++ b/src/rules/appsync/AppSyncGraphQLRequestLogging.ts
@@ -5,18 +5,18 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnGraphQLApi } from '@aws-cdk/aws-appsync';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* GraphQL APIs have request leveling logging enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnGraphQLApi) {
const logConfig = Stack.of(node).resolve(node.logConfig);
if (logConfig === undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const excludeVerboseContent = resolveIfPrimitive(
node,
@@ -26,10 +26,12 @@ export default Object.defineProperty(
logConfig.cloudWatchLogsRoleArn === undefined ||
excludeVerboseContent === true
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/athena/AthenaWorkgroupEncryptedQueryResults.ts b/src/rules/athena/AthenaWorkgroupEncryptedQueryResults.ts
index 4ef2e280c8..1afa54b4dd 100644
--- a/src/rules/athena/AthenaWorkgroupEncryptedQueryResults.ts
+++ b/src/rules/athena/AthenaWorkgroupEncryptedQueryResults.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnWorkGroup } from '@aws-cdk/aws-athena';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Athena workgroups encrypt query results
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnWorkGroup) {
const workGroupConfiguration = Stack.of(node).resolve(
node.workGroupConfiguration
@@ -22,7 +22,7 @@ export default Object.defineProperty(
node.workGroupConfigurationUpdates
);
if (workGroupConfigurationUpdates == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const resultConfigurationUpdates = Stack.of(node).resolve(
workGroupConfigurationUpdates.resultConfigurationUpdates
@@ -43,12 +43,12 @@ export default Object.defineProperty(
removeEncryptionConfiguration &&
encryptionConfiguration == undefined
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
} else if (
encryptionConfiguration != undefined &&
!enforceWorkGroupConfiguration
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
} else {
@@ -57,25 +57,27 @@ export default Object.defineProperty(
workGroupConfiguration.enforceWorkGroupConfiguration
);
if (!enforceWorkGroupConfiguration) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const resultConfiguration = Stack.of(node).resolve(
workGroupConfiguration.resultConfiguration
);
if (resultConfiguration == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const encryptionConfiguration = Stack.of(node).resolve(
resultConfiguration.encryptionConfiguration
);
if (encryptionConfiguration == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/autoscaling/AutoScalingGroupCooldownPeriod.ts b/src/rules/autoscaling/AutoScalingGroupCooldownPeriod.ts
index b3af8c0d68..fe9f992258 100644
--- a/src/rules/autoscaling/AutoScalingGroupCooldownPeriod.ts
+++ b/src/rules/autoscaling/AutoScalingGroupCooldownPeriod.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnAutoScalingGroup } from '@aws-cdk/aws-autoscaling';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Auto Scaling Groups have configured cooldown periods
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnAutoScalingGroup) {
const cooldown = resolveIfPrimitive(node, node.cooldown);
if (cooldown != undefined && parseInt(cooldown) == 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/autoscaling/AutoScalingGroupELBHealthCheckRequired.ts b/src/rules/autoscaling/AutoScalingGroupELBHealthCheckRequired.ts
index b41c7d3384..5574d2564c 100644
--- a/src/rules/autoscaling/AutoScalingGroupELBHealthCheckRequired.ts
+++ b/src/rules/autoscaling/AutoScalingGroupELBHealthCheckRequired.ts
@@ -5,13 +5,13 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnAutoScalingGroup } from '@aws-cdk/aws-autoscaling';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Auto Scaling groups which are associated with load balancers utilize ELB health checks
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnAutoScalingGroup) {
const classicLBs = Stack.of(node).resolve(node.loadBalancerNames);
const otherLBs = Stack.of(node).resolve(node.targetGroupArns);
@@ -22,14 +22,16 @@ export default Object.defineProperty(
const healthCheckType = resolveIfPrimitive(node, node.healthCheckType);
if (healthCheckType != undefined) {
if (healthCheckType != 'ELB') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
} else {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/autoscaling/AutoScalingGroupHealthCheck.ts b/src/rules/autoscaling/AutoScalingGroupHealthCheck.ts
index cd35d57bb2..4bb080b768 100644
--- a/src/rules/autoscaling/AutoScalingGroupHealthCheck.ts
+++ b/src/rules/autoscaling/AutoScalingGroupHealthCheck.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnAutoScalingGroup } from '@aws-cdk/aws-autoscaling';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Auto Scaling Groups have properly configured health checks
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnAutoScalingGroup) {
const healthCheckType = resolveIfPrimitive(node, node.healthCheckType);
const healthCheckGracePeriod = resolveIfPrimitive(
@@ -24,10 +24,12 @@ export default Object.defineProperty(
healthCheckType == 'ELB' &&
healthCheckGracePeriod == undefined
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/autoscaling/AutoScalingGroupScalingNotifications.ts b/src/rules/autoscaling/AutoScalingGroupScalingNotifications.ts
index 9203c38f23..c7936b1ec4 100644
--- a/src/rules/autoscaling/AutoScalingGroupScalingNotifications.ts
+++ b/src/rules/autoscaling/AutoScalingGroupScalingNotifications.ts
@@ -5,16 +5,17 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnAutoScalingGroup, ScalingEvent } from '@aws-cdk/aws-autoscaling';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Auto Scaling Groups have notifications for all scaling events configured
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnAutoScalingGroup) {
if (node.notificationConfigurations == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const notificationConfigurations = <
CfnAutoScalingGroup.NotificationConfigurationProperty[]
@@ -27,13 +28,18 @@ export default Object.defineProperty(
ScalingEvent.INSTANCE_TERMINATE_ERROR,
];
- return requiredEvents.every((req) => {
+ const compliant = requiredEvents.every((req) => {
return notificationConfigurations.some((config) => {
return config.notificationTypes?.includes(req);
});
});
+ if (compliant !== true) {
+ return NagRuleCompliance.NON_COMPLIANT;
+ }
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/autoscaling/AutoScalingLaunchConfigPublicIpDisabled.ts b/src/rules/autoscaling/AutoScalingLaunchConfigPublicIpDisabled.ts
index 834f109df2..5e075269a6 100644
--- a/src/rules/autoscaling/AutoScalingLaunchConfigPublicIpDisabled.ts
+++ b/src/rules/autoscaling/AutoScalingLaunchConfigPublicIpDisabled.ts
@@ -5,23 +5,25 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnLaunchConfiguration } from '@aws-cdk/aws-autoscaling';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Auto Scaling launch configurations have public IP addresses disabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnLaunchConfiguration) {
const associatePublicIpAddress = resolveIfPrimitive(
node,
node.associatePublicIpAddress
);
if (associatePublicIpAddress !== false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cloud9/Cloud9InstanceNoIngressSystemsManager.ts b/src/rules/cloud9/Cloud9InstanceNoIngressSystemsManager.ts
index 60193385b6..b2e6b52727 100644
--- a/src/rules/cloud9/Cloud9InstanceNoIngressSystemsManager.ts
+++ b/src/rules/cloud9/Cloud9InstanceNoIngressSystemsManager.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnEnvironmentEC2 } from '@aws-cdk/aws-cloud9';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Cloud9 instances use no-ingress EC2 instances with AWS Systems Manager
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnEnvironmentEC2) {
const connectionType = resolveIfPrimitive(node, node.connectionType);
if (connectionType == undefined || connectionType != 'CONNECT_SSM') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cloudfront/CloudFrontDistributionAccessLogging.ts b/src/rules/cloudfront/CloudFrontDistributionAccessLogging.ts
index b4fc7e9bc8..6432263de3 100644
--- a/src/rules/cloudfront/CloudFrontDistributionAccessLogging.ts
+++ b/src/rules/cloudfront/CloudFrontDistributionAccessLogging.ts
@@ -8,35 +8,38 @@ import {
CfnStreamingDistribution,
} from '@aws-cdk/aws-cloudfront';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* CloudFront distributions have access logging enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDistribution) {
const distributionConfig = Stack.of(node).resolve(
node.distributionConfig
);
if (distributionConfig.logging == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnStreamingDistribution) {
const distributionConfig = Stack.of(node).resolve(
node.streamingDistributionConfig
);
if (distributionConfig.logging == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const logging = Stack.of(node).resolve(distributionConfig.logging);
const enabled = resolveIfPrimitive(node, logging.enabled);
if (!enabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cloudfront/CloudFrontDistributionGeoRestrictions.ts b/src/rules/cloudfront/CloudFrontDistributionGeoRestrictions.ts
index c983d3ee43..2b83ff3374 100644
--- a/src/rules/cloudfront/CloudFrontDistributionGeoRestrictions.ts
+++ b/src/rules/cloudfront/CloudFrontDistributionGeoRestrictions.ts
@@ -5,20 +5,20 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDistribution } from '@aws-cdk/aws-cloudfront';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* CloudFront distributions may require Geo restrictions
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDistribution) {
const distributionConfig = Stack.of(node).resolve(
node.distributionConfig
);
if (distributionConfig.restrictions == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
} else {
const restrictions = Stack.of(node).resolve(
distributionConfig.restrictions
@@ -31,11 +31,13 @@ export default Object.defineProperty(
geoRestrictions.restrictionType
);
if (restrictionType == 'none') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cloudfront/CloudFrontDistributionNoOutdatedSSL.ts b/src/rules/cloudfront/CloudFrontDistributionNoOutdatedSSL.ts
index d08bf9ed1b..4285722dfc 100644
--- a/src/rules/cloudfront/CloudFrontDistributionNoOutdatedSSL.ts
+++ b/src/rules/cloudfront/CloudFrontDistributionNoOutdatedSSL.ts
@@ -9,14 +9,14 @@ import {
SecurityPolicyProtocol,
} from '@aws-cdk/aws-cloudfront';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* CloudFront distributions do not use SSLv3 or TLSv1 for communication to the origin
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDistribution) {
const distributionConfig = Stack.of(node).resolve(
node.distributionConfig
@@ -34,10 +34,10 @@ export default Object.defineProperty(
customOriginConfig.originProtocolPolicy
);
if (originProtocolPolicy != OriginProtocolPolicy.HTTPS_ONLY) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
if (customOriginConfig.originSslProtocols == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const outdatedValues = [
SecurityPolicyProtocol.SSL_V3,
@@ -51,14 +51,16 @@ export default Object.defineProperty(
});
for (const outdated of outdatedValues) {
if (lowerCaseProtocols.includes(outdated.toLowerCase())) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cloudfront/CloudFrontDistributionS3OriginAccessIdentity.ts b/src/rules/cloudfront/CloudFrontDistributionS3OriginAccessIdentity.ts
index fe95d38d04..d3caf598d9 100644
--- a/src/rules/cloudfront/CloudFrontDistributionS3OriginAccessIdentity.ts
+++ b/src/rules/cloudfront/CloudFrontDistributionS3OriginAccessIdentity.ts
@@ -8,13 +8,14 @@ import {
CfnStreamingDistribution,
} from '@aws-cdk/aws-cloudfront';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* CloudFront distributions use an origin access identity for S3 origins
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDistribution) {
const distributionConfig = Stack.of(node).resolve(
node.distributionConfig
@@ -30,7 +31,7 @@ export default Object.defineProperty(
/^.+\.s3(?:-website)?(?:\..+)?(?:(?:\.amazonaws\.com(?:\.cn)?)|(?:\.c2s\.ic\.gov)|(?:\.sc2s\.sgov\.gov))$/;
if (s3Regex.test(resolvedDomainName)) {
if (resolvedOrigin.s3OriginConfig == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const resolvedConfig = Stack.of(node).resolve(
resolvedOrigin.s3OriginConfig
@@ -39,11 +40,12 @@ export default Object.defineProperty(
resolvedConfig.originAccessIdentity == undefined ||
resolvedConfig.originAccessIdentity.replace(/\s/g, '').length == 0
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnStreamingDistribution) {
const distributionConfig = Stack.of(node).resolve(
node.streamingDistributionConfig
@@ -52,10 +54,12 @@ export default Object.defineProperty(
distributionConfig.s3Origin
);
if (resolvedOrigin.originAccessIdentity.replace(/\s/g, '').length == 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cloudfront/CloudFrontDistributionWAFIntegration.ts b/src/rules/cloudfront/CloudFrontDistributionWAFIntegration.ts
index be82ecbae1..b0f1bf69c6 100644
--- a/src/rules/cloudfront/CloudFrontDistributionWAFIntegration.ts
+++ b/src/rules/cloudfront/CloudFrontDistributionWAFIntegration.ts
@@ -5,22 +5,25 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDistribution } from '@aws-cdk/aws-cloudfront';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* CloudFront distributions may require integration with AWS WAF
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDistribution) {
const distributionConfig = Stack.of(node).resolve(
node.distributionConfig
);
if (distributionConfig.webAclId == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cloudtrail/CloudTrailCloudWatchLogsEnabled.ts b/src/rules/cloudtrail/CloudTrailCloudWatchLogsEnabled.ts
index 0719a7a348..2e63fd3680 100644
--- a/src/rules/cloudtrail/CloudTrailCloudWatchLogsEnabled.ts
+++ b/src/rules/cloudtrail/CloudTrailCloudWatchLogsEnabled.ts
@@ -5,21 +5,24 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnTrail } from '@aws-cdk/aws-cloudtrail';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* CloudTrail trails have CloudWatch logs enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnTrail) {
const cloudWatch = Stack.of(node).resolve(node.cloudWatchLogsLogGroupArn);
if (cloudWatch == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cloudtrail/CloudTrailEncryptionEnabled.ts b/src/rules/cloudtrail/CloudTrailEncryptionEnabled.ts
index 9e3ca96ba3..313bfddeee 100644
--- a/src/rules/cloudtrail/CloudTrailEncryptionEnabled.ts
+++ b/src/rules/cloudtrail/CloudTrailEncryptionEnabled.ts
@@ -5,21 +5,24 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnTrail } from '@aws-cdk/aws-cloudtrail';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* CloudTrail trails have encryption enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnTrail) {
const keyID = Stack.of(node).resolve(node.kmsKeyId);
if (keyID == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cloudtrail/CloudTrailLogFileValidationEnabled.ts b/src/rules/cloudtrail/CloudTrailLogFileValidationEnabled.ts
index 007b87b206..ab2a1842e4 100644
--- a/src/rules/cloudtrail/CloudTrailLogFileValidationEnabled.ts
+++ b/src/rules/cloudtrail/CloudTrailLogFileValidationEnabled.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnTrail } from '@aws-cdk/aws-cloudtrail';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* CloudTrail trails have log file validation enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnTrail) {
const enabled = resolveIfPrimitive(node, node.enableLogFileValidation);
if (enabled != true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cloudwatch/CloudWatchAlarmAction.ts b/src/rules/cloudwatch/CloudWatchAlarmAction.ts
index d14608da24..03d61b886b 100644
--- a/src/rules/cloudwatch/CloudWatchAlarmAction.ts
+++ b/src/rules/cloudwatch/CloudWatchAlarmAction.ts
@@ -5,17 +5,18 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnAlarm } from '@aws-cdk/aws-cloudwatch';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* CloudWatch alarms have at least one alarm action, one INSUFFICIENT_DATA action, or one OK action enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnAlarm) {
const actionsEnabled = Stack.of(node).resolve(node.actionsEnabled);
if (actionsEnabled === false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
// Actions can be an array with a token that then resolves to an empty array or undefined
const alarmActions = Stack.of(node).resolve(node.alarmActions);
@@ -31,10 +32,12 @@ export default Object.defineProperty(
const totalActions =
totalAlarmActions + totalInsufficientDataActions + totalOkActions;
if (totalActions == 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cloudwatch/CloudWatchLogGroupEncrypted.ts b/src/rules/cloudwatch/CloudWatchLogGroupEncrypted.ts
index 7048004f9c..a089caefaf 100644
--- a/src/rules/cloudwatch/CloudWatchLogGroupEncrypted.ts
+++ b/src/rules/cloudwatch/CloudWatchLogGroupEncrypted.ts
@@ -5,19 +5,22 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnLogGroup } from '@aws-cdk/aws-logs';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* CloudWatch Log Groups are encrypted with customer managed keys
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnLogGroup) {
if (node.kmsKeyId == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cloudwatch/CloudWatchLogGroupRetentionPeriod.ts b/src/rules/cloudwatch/CloudWatchLogGroupRetentionPeriod.ts
index 76c1b6e8f4..a72ca73a46 100644
--- a/src/rules/cloudwatch/CloudWatchLogGroupRetentionPeriod.ts
+++ b/src/rules/cloudwatch/CloudWatchLogGroupRetentionPeriod.ts
@@ -5,19 +5,22 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnLogGroup } from '@aws-cdk/aws-logs';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* CloudWatch Log Groups have an explicit retention period configured
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnLogGroup) {
if (node.retentionInDays == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/codebuild/CodeBuildProjectEnvVarAwsCred.ts b/src/rules/codebuild/CodeBuildProjectEnvVarAwsCred.ts
index 904f932280..8c56f5f5dc 100644
--- a/src/rules/codebuild/CodeBuildProjectEnvVarAwsCred.ts
+++ b/src/rules/codebuild/CodeBuildProjectEnvVarAwsCred.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnProject } from '@aws-cdk/aws-codebuild';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* CodeBuild projects do not store AWS credentials as plaintext environment variables
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnProject) {
//Check for the presence of OAUTH
const environment = Stack.of(node).resolve(node.environment);
@@ -28,13 +28,15 @@ export default Object.defineProperty(
if (name == 'AWS_ACCESS_KEY_ID' || name == 'AWS_SECRET_ACCESS_KEY') {
//is this credential being stored as plaintext?
if (type == undefined || type == 'PLAINTEXT') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/codebuild/CodeBuildProjectKMSEncryptedArtifacts.ts b/src/rules/codebuild/CodeBuildProjectKMSEncryptedArtifacts.ts
index e68c8e89ba..ae54625bfe 100644
--- a/src/rules/codebuild/CodeBuildProjectKMSEncryptedArtifacts.ts
+++ b/src/rules/codebuild/CodeBuildProjectKMSEncryptedArtifacts.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnProject } from '@aws-cdk/aws-codebuild';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Codebuild projects use an AWS KMS key for encryption
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnProject) {
const encryptionKey = resolveIfPrimitive(node, node.encryptionKey);
if (encryptionKey == undefined || encryptionKey == 'alias/aws/s3') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/codebuild/CodeBuildProjectManagedImages.ts b/src/rules/codebuild/CodeBuildProjectManagedImages.ts
index e60b4d736b..5788255e25 100644
--- a/src/rules/codebuild/CodeBuildProjectManagedImages.ts
+++ b/src/rules/codebuild/CodeBuildProjectManagedImages.ts
@@ -5,22 +5,24 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnProject } from '@aws-cdk/aws-codebuild';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Codebuild projects use images provided by the CodeBuild service or have a cdk_nag suppression rule explaining the need for a custom image
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnProject) {
const environment = Stack.of(node).resolve(node.environment);
const image = resolveIfPrimitive(node, environment.image);
if (!image.startsWith('aws/codebuild/')) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/codebuild/CodeBuildProjectPrivilegedModeDisabled.ts b/src/rules/codebuild/CodeBuildProjectPrivilegedModeDisabled.ts
index b0cb5a0725..b7e0b3611a 100644
--- a/src/rules/codebuild/CodeBuildProjectPrivilegedModeDisabled.ts
+++ b/src/rules/codebuild/CodeBuildProjectPrivilegedModeDisabled.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnProject } from '@aws-cdk/aws-codebuild';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Codebuild projects have privileged mode disabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnProject) {
const environment = Stack.of(node).resolve(node.environment);
const privilegedMode = resolveIfPrimitive(
@@ -20,10 +20,12 @@ export default Object.defineProperty(
environment.privilegedMode
);
if (privilegedMode != undefined && privilegedMode) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/codebuild/CodeBuildProjectSourceRepoUrl.ts b/src/rules/codebuild/CodeBuildProjectSourceRepoUrl.ts
index 1bf889f794..71679be42a 100644
--- a/src/rules/codebuild/CodeBuildProjectSourceRepoUrl.ts
+++ b/src/rules/codebuild/CodeBuildProjectSourceRepoUrl.ts
@@ -5,28 +5,30 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnProject } from '@aws-cdk/aws-codebuild';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Codebuild projects with a GitHub or BitBucket source repository utilize OAUTH
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnProject) {
//Check for the presence of OAUTH
const projectSource = Stack.of(node).resolve(node.source);
const projectAuth = Stack.of(node).resolve(projectSource.auth);
if (projectAuth == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
} else {
const projectAuthType = resolveIfPrimitive(node, projectAuth.type);
if (projectAuthType != 'OAUTH') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cognito/CognitoUserPoolAPIGWAuthorizer.ts b/src/rules/cognito/CognitoUserPoolAPIGWAuthorizer.ts
index 39198cf218..2e0e5592ba 100644
--- a/src/rules/cognito/CognitoUserPoolAPIGWAuthorizer.ts
+++ b/src/rules/cognito/CognitoUserPoolAPIGWAuthorizer.ts
@@ -5,19 +5,22 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnMethod } from '@aws-cdk/aws-apigateway';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Rest API methods use Cognito User Pool Authorizers
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnMethod) {
if (node.authorizationType !== 'COGNITO_USER_POOLS') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cognito/CognitoUserPoolAdvancedSecurityModeEnforced.ts b/src/rules/cognito/CognitoUserPoolAdvancedSecurityModeEnforced.ts
index 724cb767ee..bdae5b1d6f 100644
--- a/src/rules/cognito/CognitoUserPoolAdvancedSecurityModeEnforced.ts
+++ b/src/rules/cognito/CognitoUserPoolAdvancedSecurityModeEnforced.ts
@@ -5,18 +5,18 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnUserPool } from '@aws-cdk/aws-cognito';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Cognito user pools have AdvancedSecurityMode set to ENFORCED
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnUserPool) {
const userPoolAddOns = Stack.of(node).resolve(node.userPoolAddOns);
if (userPoolAddOns == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const advancedSecurityMode = resolveIfPrimitive(
node,
@@ -26,10 +26,12 @@ export default Object.defineProperty(
advancedSecurityMode == undefined ||
advancedSecurityMode != 'ENFORCED'
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cognito/CognitoUserPoolMFA.ts b/src/rules/cognito/CognitoUserPoolMFA.ts
index 4e3478b1fd..9e9e288da6 100644
--- a/src/rules/cognito/CognitoUserPoolMFA.ts
+++ b/src/rules/cognito/CognitoUserPoolMFA.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnUserPool, Mfa } from '@aws-cdk/aws-cognito';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Cognito user pools require MFA
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnUserPool) {
const mfaConfiguration = resolveIfPrimitive(node, node.mfaConfiguration);
if (mfaConfiguration == undefined || mfaConfiguration != Mfa.REQUIRED) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cognito/CognitoUserPoolNoUnauthenticatedLogins.ts b/src/rules/cognito/CognitoUserPoolNoUnauthenticatedLogins.ts
index c5ae935def..cab5f6c633 100644
--- a/src/rules/cognito/CognitoUserPoolNoUnauthenticatedLogins.ts
+++ b/src/rules/cognito/CognitoUserPoolNoUnauthenticatedLogins.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnIdentityPool } from '@aws-cdk/aws-cognito';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Cognito identity pools do not allow for unauthenticated logins without a valid reason
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnIdentityPool) {
const allowUnauthenticatedIdentities = resolveIfPrimitive(
node,
node.allowUnauthenticatedIdentities
);
if (allowUnauthenticatedIdentities) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/cognito/CognitoUserPoolStrongPasswordPolicy.ts b/src/rules/cognito/CognitoUserPoolStrongPasswordPolicy.ts
index 9de6a8a2fb..8fd196f1ec 100644
--- a/src/rules/cognito/CognitoUserPoolStrongPasswordPolicy.ts
+++ b/src/rules/cognito/CognitoUserPoolStrongPasswordPolicy.ts
@@ -5,22 +5,22 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnUserPool } from '@aws-cdk/aws-cognito';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Cognito user pools have password policies that minimally specify a password length of at least 8 characters, as well as requiring uppercase, numeric, and special characters
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnUserPool) {
const policies = Stack.of(node).resolve(node.policies);
if (policies == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const passwordPolicy = Stack.of(node).resolve(policies.passwordPolicy);
if (passwordPolicy == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const minimumLength = resolveIfPrimitive(
@@ -28,7 +28,7 @@ export default Object.defineProperty(
passwordPolicy.minimumLength
);
if (minimumLength == undefined || minimumLength < 8) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const requireUppercase = resolveIfPrimitive(
@@ -36,7 +36,7 @@ export default Object.defineProperty(
passwordPolicy.requireUppercase
);
if (requireUppercase !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const requireNumbers = resolveIfPrimitive(
@@ -44,7 +44,7 @@ export default Object.defineProperty(
passwordPolicy.requireNumbers
);
if (requireNumbers !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const requireSymbols = resolveIfPrimitive(
@@ -52,10 +52,12 @@ export default Object.defineProperty(
passwordPolicy.requireSymbols
);
if (requireSymbols !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/dms/DMSReplicationNotPublic.ts b/src/rules/dms/DMSReplicationNotPublic.ts
index 9e181a9ad6..12ded43f43 100644
--- a/src/rules/dms/DMSReplicationNotPublic.ts
+++ b/src/rules/dms/DMSReplicationNotPublic.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnReplicationInstance } from '@aws-cdk/aws-dms';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* DMS replication instances are not public
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnReplicationInstance) {
const publicAccess = resolveIfPrimitive(node, node.publiclyAccessible);
if (publicAccess !== false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/documentdb/DocumentDBClusterBackupRetentionPeriod.ts b/src/rules/documentdb/DocumentDBClusterBackupRetentionPeriod.ts
index f570094d28..8753238832 100644
--- a/src/rules/documentdb/DocumentDBClusterBackupRetentionPeriod.ts
+++ b/src/rules/documentdb/DocumentDBClusterBackupRetentionPeriod.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster } from '@aws-cdk/aws-docdb';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Document DB clusters have a reasonable minimum backup retention period configured
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
const backupRetentionPeriod = resolveIfPrimitive(
node,
node.backupRetentionPeriod
);
if (backupRetentionPeriod == undefined || backupRetentionPeriod < 7) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/documentdb/DocumentDBClusterEncryptionAtRest.ts b/src/rules/documentdb/DocumentDBClusterEncryptionAtRest.ts
index 219291abfc..895e1053c5 100644
--- a/src/rules/documentdb/DocumentDBClusterEncryptionAtRest.ts
+++ b/src/rules/documentdb/DocumentDBClusterEncryptionAtRest.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster } from '@aws-cdk/aws-docdb';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Document DB clusters have encryption at rest enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
if (node.storageEncrypted == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const storageEncrypted = resolveIfPrimitive(node, node.storageEncrypted);
if (!storageEncrypted) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/documentdb/DocumentDBClusterLogExports.ts b/src/rules/documentdb/DocumentDBClusterLogExports.ts
index 04e6eb3bed..41a33a97f2 100644
--- a/src/rules/documentdb/DocumentDBClusterLogExports.ts
+++ b/src/rules/documentdb/DocumentDBClusterLogExports.ts
@@ -5,22 +5,28 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster } from '@aws-cdk/aws-docdb';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Document DB clusters have authenticate, createIndex, and dropCollection Log Exports enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
if (node.enableCloudwatchLogsExports == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const needed = ['authenticate', 'createIndex', 'dropCollection'];
const exports = node.enableCloudwatchLogsExports;
- return needed.every((i) => exports.includes(i));
+ const compliant = needed.every((i) => exports.includes(i));
+ if (compliant !== true) {
+ return NagRuleCompliance.NON_COMPLIANT;
+ }
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/documentdb/DocumentDBClusterNonDefaultPort.ts b/src/rules/documentdb/DocumentDBClusterNonDefaultPort.ts
index 99bf1ac7bc..aee5e6e662 100644
--- a/src/rules/documentdb/DocumentDBClusterNonDefaultPort.ts
+++ b/src/rules/documentdb/DocumentDBClusterNonDefaultPort.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster } from '@aws-cdk/aws-docdb';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Document DB clusters do not use the default endpoint port
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
const port = resolveIfPrimitive(node, node.port);
if (port == undefined || port == 27017) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/documentdb/DocumentDBCredentialsInSecretsManager.ts b/src/rules/documentdb/DocumentDBCredentialsInSecretsManager.ts
index f6798f928c..47d4ffeeb1 100644
--- a/src/rules/documentdb/DocumentDBCredentialsInSecretsManager.ts
+++ b/src/rules/documentdb/DocumentDBCredentialsInSecretsManager.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster } from '@aws-cdk/aws-docdb';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Document DB clusters have the username and password stored in Secrets Manager
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
const masterUsername = resolveIfPrimitive(node, node.masterUsername);
const masterUserPassword = resolveIfPrimitive(
@@ -23,10 +23,12 @@ export default Object.defineProperty(
masterUsername.includes('{{resolve:secretsmanager') == false ||
masterUserPassword.includes('{{resolve:secretsmanager') == false
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/dynamodb/DAXEncrypted.ts b/src/rules/dynamodb/DAXEncrypted.ts
index 5406625873..adfd099940 100644
--- a/src/rules/dynamodb/DAXEncrypted.ts
+++ b/src/rules/dynamodb/DAXEncrypted.ts
@@ -5,25 +5,27 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-dax';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* DAX clusters have server-side encryption enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
if (node.sseSpecification == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const sseSpecification = Stack.of(node).resolve(node.sseSpecification);
const enabled = resolveIfPrimitive(node, sseSpecification.sseEnabled);
if (!enabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/dynamodb/DynamoDBAutoScalingEnabled.ts b/src/rules/dynamodb/DynamoDBAutoScalingEnabled.ts
index e82a5dcb49..84acb70090 100644
--- a/src/rules/dynamodb/DynamoDBAutoScalingEnabled.ts
+++ b/src/rules/dynamodb/DynamoDBAutoScalingEnabled.ts
@@ -6,7 +6,10 @@ import { parse } from 'path';
import { CfnScalableTarget } from '@aws-cdk/aws-applicationautoscaling';
import { CfnTable, BillingMode } from '@aws-cdk/aws-dynamodb';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* Provisioned capacity DynamoDB tables have auto-scaling enabled on their indexes
@@ -14,7 +17,7 @@ import { resolveResourceFromInstrinsic } from '../../nag-pack';
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnTable) {
if (
resolveResourceFromInstrinsic(node, node.billingMode) !==
@@ -60,11 +63,13 @@ export default Object.defineProperty(
}
}
if (indexWriteMatches.length != 0 || indexReadMatches.length != 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/dynamodb/DynamoDBInBackupPlan.ts b/src/rules/dynamodb/DynamoDBInBackupPlan.ts
index 7059ff6fb4..faee090911 100644
--- a/src/rules/dynamodb/DynamoDBInBackupPlan.ts
+++ b/src/rules/dynamodb/DynamoDBInBackupPlan.ts
@@ -6,7 +6,10 @@ import { parse } from 'path';
import { CfnBackupSelection } from '@aws-cdk/aws-backup';
import { CfnTable } from '@aws-cdk/aws-dynamodb';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* DynamoDB tables are part of AWS Backup plan(s)
@@ -14,7 +17,7 @@ import { resolveResourceFromInstrinsic } from '../../nag-pack';
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnTable) {
const tableLogicalId = resolveResourceFromInstrinsic(node, node.ref);
const tableName = Stack.of(node).resolve(node.tableName);
@@ -28,10 +31,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/dynamodb/DynamoDBPITREnabled.ts b/src/rules/dynamodb/DynamoDBPITREnabled.ts
index 2991d576e3..85cbc8bdfa 100644
--- a/src/rules/dynamodb/DynamoDBPITREnabled.ts
+++ b/src/rules/dynamodb/DynamoDBPITREnabled.ts
@@ -5,7 +5,7 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnTable } from '@aws-cdk/aws-dynamodb';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* DynamoDB tables have Point-in-time Recovery enabled
@@ -13,20 +13,22 @@ import { resolveIfPrimitive } from '../../nag-pack';
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnTable) {
if (node.pointInTimeRecoverySpecification == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const pitr = Stack.of(node).resolve(
node.pointInTimeRecoverySpecification
);
const enabled = resolveIfPrimitive(node, pitr.pointInTimeRecoveryEnabled);
if (!enabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ec2/EC2EBSInBackupPlan.ts b/src/rules/ec2/EC2EBSInBackupPlan.ts
index 08c77e67c6..1f62316b49 100644
--- a/src/rules/ec2/EC2EBSInBackupPlan.ts
+++ b/src/rules/ec2/EC2EBSInBackupPlan.ts
@@ -6,7 +6,10 @@ import { parse } from 'path';
import { CfnBackupSelection } from '@aws-cdk/aws-backup';
import { CfnVolume } from '@aws-cdk/aws-ec2';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* EBS volumes are part of AWS Backup plan(s)
@@ -14,7 +17,7 @@ import { resolveResourceFromInstrinsic } from '../../nag-pack';
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnVolume) {
const volumeLogicalId = resolveResourceFromInstrinsic(node, node.ref);
let found = false;
@@ -27,10 +30,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ec2/EC2EBSOptimizedInstance.ts b/src/rules/ec2/EC2EBSOptimizedInstance.ts
index 16ec180802..174296c8e4 100644
--- a/src/rules/ec2/EC2EBSOptimizedInstance.ts
+++ b/src/rules/ec2/EC2EBSOptimizedInstance.ts
@@ -5,7 +5,7 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnInstance } from '@aws-cdk/aws-ec2';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
const EBS_OPTIMIZED_SUPPORTED = [
'c1.xlarge',
@@ -33,7 +33,7 @@ const DEFAULT_TYPE = 'm1.small';
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnInstance) {
const instanceType = node.instanceType
? resolveIfPrimitive(node, node.instanceType)
@@ -43,10 +43,12 @@ export default Object.defineProperty(
EBS_OPTIMIZED_SUPPORTED.includes(instanceType) &&
ebsOptimized !== true
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ec2/EC2EBSVolumeEncrypted.ts b/src/rules/ec2/EC2EBSVolumeEncrypted.ts
index 91037bab11..5f67e2dbdc 100644
--- a/src/rules/ec2/EC2EBSVolumeEncrypted.ts
+++ b/src/rules/ec2/EC2EBSVolumeEncrypted.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnVolume } from '@aws-cdk/aws-ec2';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* EBS volumes have encryption enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnVolume) {
const encryption = resolveIfPrimitive(node, node.encrypted);
if (encryption !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ec2/EC2InstanceDetailedMonitoringEnabled.ts b/src/rules/ec2/EC2InstanceDetailedMonitoringEnabled.ts
index 15b05aed5c..77565b385f 100644
--- a/src/rules/ec2/EC2InstanceDetailedMonitoringEnabled.ts
+++ b/src/rules/ec2/EC2InstanceDetailedMonitoringEnabled.ts
@@ -6,26 +6,29 @@ import { parse } from 'path';
import { CfnLaunchConfiguration } from '@aws-cdk/aws-autoscaling';
import { CfnInstance } from '@aws-cdk/aws-ec2';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* EC2 instances have detailed monitoring enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnInstance) {
const monitoring = resolveIfPrimitive(node, node.monitoring);
if (monitoring == undefined || monitoring == false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnLaunchConfiguration) {
const monitoring = resolveIfPrimitive(node, node.instanceMonitoring);
if (monitoring != undefined && monitoring == false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ec2/EC2InstanceNoPublicIp.ts b/src/rules/ec2/EC2InstanceNoPublicIp.ts
index 3d6c63d38c..e754623487 100644
--- a/src/rules/ec2/EC2InstanceNoPublicIp.ts
+++ b/src/rules/ec2/EC2InstanceNoPublicIp.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnInstance } from '@aws-cdk/aws-ec2';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* EC2 instances do not have public IPs
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnInstance) {
const networkInterfaces = Stack.of(node).resolve(node.networkInterfaces);
if (networkInterfaces != undefined) {
@@ -24,12 +24,14 @@ export default Object.defineProperty(
resolvedInterface.associatePublicIpAddress
);
if (associatePublicIpAddress === true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ec2/EC2InstanceProfileAttached.ts b/src/rules/ec2/EC2InstanceProfileAttached.ts
index 3ed1522373..399de5878e 100644
--- a/src/rules/ec2/EC2InstanceProfileAttached.ts
+++ b/src/rules/ec2/EC2InstanceProfileAttached.ts
@@ -5,19 +5,22 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnInstance } from '@aws-cdk/aws-ec2';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* EC2 instances have an instance profile attached
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnInstance) {
if (node.iamInstanceProfile == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ec2/EC2InstanceTerminationProtection.ts b/src/rules/ec2/EC2InstanceTerminationProtection.ts
index d8f8a6053e..09795bde24 100644
--- a/src/rules/ec2/EC2InstanceTerminationProtection.ts
+++ b/src/rules/ec2/EC2InstanceTerminationProtection.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnInstance } from '@aws-cdk/aws-ec2';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* EC2 Instances outside of an ASG have Termination Protection enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnInstance) {
const disableApiTermination = resolveIfPrimitive(
node,
node.disableApiTermination
);
if (disableApiTermination !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ec2/EC2InstancesInVPC.ts b/src/rules/ec2/EC2InstancesInVPC.ts
index 929ed33843..d7224885f2 100644
--- a/src/rules/ec2/EC2InstancesInVPC.ts
+++ b/src/rules/ec2/EC2InstancesInVPC.ts
@@ -5,21 +5,24 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnInstance } from '@aws-cdk/aws-ec2';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* EC2 instances are created within VPCs
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnInstance) {
//If we are in a VPC, then we'll have a subnet
const subnetId = Stack.of(node).resolve(node.subnetId);
if (subnetId == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ec2/EC2RestrictedCommonPorts.ts b/src/rules/ec2/EC2RestrictedCommonPorts.ts
index b4d66b7a3a..6e19fd8683 100644
--- a/src/rules/ec2/EC2RestrictedCommonPorts.ts
+++ b/src/rules/ec2/EC2RestrictedCommonPorts.ts
@@ -5,7 +5,7 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnSecurityGroupIngress, CfnSecurityGroup } from '@aws-cdk/aws-ec2';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
const BLOCKED_PORTS = [20, 21, 3389, 3309, 3306, 4333];
@@ -15,7 +15,7 @@ const BLOCKED_PORTS = [20, 21, 3389, 3309, 3306, 4333];
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnSecurityGroup) {
const ingressRules = Stack.of(node).resolve(node.securityGroupIngress);
if (ingressRules != undefined) {
@@ -24,19 +24,22 @@ export default Object.defineProperty(
const resolvedRule = Stack.of(node).resolve(rule);
for (const portNum of BLOCKED_PORTS) {
if (!testPort(node, resolvedRule, portNum)) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnSecurityGroupIngress) {
for (const portNum of BLOCKED_PORTS) {
if (!testPort(node, node, portNum)) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ec2/EC2RestrictedInbound.ts b/src/rules/ec2/EC2RestrictedInbound.ts
index 7e97a08330..0bf0fc2cff 100644
--- a/src/rules/ec2/EC2RestrictedInbound.ts
+++ b/src/rules/ec2/EC2RestrictedInbound.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnSecurityGroup, CfnSecurityGroupIngress } from '@aws-cdk/aws-ec2';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* EC2 security groups do not allow for 0.0.0.0/0 or ::/0 inbound access
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnSecurityGroup) {
const ingressRules = Stack.of(node).resolve(node.securityGroupIngress);
if (ingressRules != undefined) {
@@ -24,27 +24,30 @@ export default Object.defineProperty(
resolvedRule.cidrIpv6
);
if (resolvedcidrIp != undefined && resolvedcidrIp.includes('/0')) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
if (
resolvedcidrIpv6 != undefined &&
resolvedcidrIpv6.includes('/0')
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnSecurityGroupIngress) {
const resolvedcidrIp = resolveIfPrimitive(node, node.cidrIp);
const resolvedcidrIpv6 = resolveIfPrimitive(node, node.cidrIpv6);
if (resolvedcidrIp != undefined && resolvedcidrIp.includes('/0')) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
if (resolvedcidrIpv6 != undefined && resolvedcidrIpv6.includes('/0')) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ec2/EC2RestrictedSSH.ts b/src/rules/ec2/EC2RestrictedSSH.ts
index 78398f5862..f6872fb88f 100644
--- a/src/rules/ec2/EC2RestrictedSSH.ts
+++ b/src/rules/ec2/EC2RestrictedSSH.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnSecurityGroupIngress, CfnSecurityGroup } from '@aws-cdk/aws-ec2';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Security Groups do not allow for unrestricted SSH traffic
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnSecurityGroup) {
const ingressRules = Stack.of(node).resolve(node.securityGroupIngress);
if (ingressRules != undefined) {
@@ -35,16 +35,17 @@ export default Object.defineProperty(
toPort == -1 ||
ipProtocol == '-1'
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
} else {
if (fromPort == 22 || ipProtocol == '-1') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
}
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnSecurityGroupIngress) {
const ipProtocol = resolveIfPrimitive(node, node.ipProtocol);
const cidrIp = resolveIfPrimitive(node, node.cidrIp);
@@ -63,16 +64,18 @@ export default Object.defineProperty(
toPort == -1 ||
ipProtocol == '-1'
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
} else {
if (fromPort == 22 || ipProtocol == '-1') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ec2/EC2SecurityGroupDescription.ts b/src/rules/ec2/EC2SecurityGroupDescription.ts
index bfe8455f2c..b16c345816 100644
--- a/src/rules/ec2/EC2SecurityGroupDescription.ts
+++ b/src/rules/ec2/EC2SecurityGroupDescription.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnSecurityGroup } from '@aws-cdk/aws-ec2';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Security Groups have descriptions
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnSecurityGroup) {
const description = resolveIfPrimitive(node, node.groupDescription);
if (description.length < 2) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ecr/ECROpenAccess.ts b/src/rules/ecr/ECROpenAccess.ts
index d1222ea933..d179773f03 100644
--- a/src/rules/ecr/ECROpenAccess.ts
+++ b/src/rules/ecr/ECROpenAccess.ts
@@ -5,21 +5,31 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnRegistryPolicy, CfnRepository } from '@aws-cdk/aws-ecr';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* ECR Repositories do not allow open access
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnRegistryPolicy) {
const policyText = Stack.of(node).resolve(node.policyText);
- return checkStatement(policyText);
+ const compliant = checkStatement(policyText);
+ if (compliant !== true) {
+ return NagRuleCompliance.NON_COMPLIANT;
+ }
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnRepository) {
const policyText = Stack.of(node).resolve(node.repositoryPolicyText);
- return checkStatement(policyText);
+ const compliant = checkStatement(policyText);
+ if (compliant !== true) {
+ return NagRuleCompliance.NON_COMPLIANT;
+ }
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ecs/ECSClusterCloudWatchContainerInsights.ts b/src/rules/ecs/ECSClusterCloudWatchContainerInsights.ts
index 501dfa09f8..6804be3a9c 100644
--- a/src/rules/ecs/ECSClusterCloudWatchContainerInsights.ts
+++ b/src/rules/ecs/ECSClusterCloudWatchContainerInsights.ts
@@ -5,18 +5,20 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-ecs';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* ECS Cluster has CloudWatch Container Insights Enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
if (node.clusterSettings == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const clusterSettings = Stack.of(node).resolve(node.clusterSettings);
+ let found = false;
for (const setting of clusterSettings) {
const resolvedSetting = Stack.of(node).resolve(setting);
if (
@@ -25,13 +27,17 @@ export default Object.defineProperty(
resolvedSetting.value &&
resolvedSetting.value == 'enabled'
) {
- return true;
+ found = true;
+ break;
}
}
- return false;
+ if (!found) {
+ return NagRuleCompliance.NON_COMPLIANT;
+ }
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
-
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ecs/ECSTaskDefinitionContainerLogging.ts b/src/rules/ecs/ECSTaskDefinitionContainerLogging.ts
index 286b7b7870..59e66ff787 100644
--- a/src/rules/ecs/ECSTaskDefinitionContainerLogging.ts
+++ b/src/rules/ecs/ECSTaskDefinitionContainerLogging.ts
@@ -5,21 +5,21 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-ecs';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* ECS Task Definition has awslogs logging enabled at the minimum
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
if (node.configuration == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const configuration = Stack.of(node).resolve(node.configuration);
if (configuration.executeCommandConfiguration == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const executeCommandConfiguration = resolveIfPrimitive(
node,
@@ -29,10 +29,12 @@ export default Object.defineProperty(
executeCommandConfiguration.logging == undefined ||
executeCommandConfiguration.logging == 'NONE'
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/ecs/ECSTaskDefinitionUserForHostMode.ts b/src/rules/ecs/ECSTaskDefinitionUserForHostMode.ts
index 1590087908..c78d3d4e4d 100644
--- a/src/rules/ecs/ECSTaskDefinitionUserForHostMode.ts
+++ b/src/rules/ecs/ECSTaskDefinitionUserForHostMode.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnTaskDefinition, NetworkMode } from '@aws-cdk/aws-ecs';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Containers in ECS task definitions configured for host networking have 'privileged' set to true and a non-empty non-root 'user'
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnTaskDefinition) {
if (node.networkMode === NetworkMode.HOST) {
const containerDefinitions = Stack.of(node).resolve(
@@ -28,20 +28,22 @@ export default Object.defineProperty(
);
const user = resolveIfPrimitive(node, resolvedDefinition.user);
if (privileged !== true || user === undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const rootIdentifiers = ['root', '0'];
const userParts = user.split(':');
for (const userPart of userParts) {
if (rootIdentifiers.includes(userPart.toLowerCase())) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/efs/EFSEncrypted.ts b/src/rules/efs/EFSEncrypted.ts
index 1b95235b1d..b1b5213bb6 100644
--- a/src/rules/efs/EFSEncrypted.ts
+++ b/src/rules/efs/EFSEncrypted.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnFileSystem } from '@aws-cdk/aws-efs';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Elastic File Systems are configured for encryption at rest
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnFileSystem) {
const encrypted = resolveIfPrimitive(node, node.encrypted);
if (encrypted === false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/efs/EFSInBackupPlan.ts b/src/rules/efs/EFSInBackupPlan.ts
index 338012d2f4..94c7bb7cab 100644
--- a/src/rules/efs/EFSInBackupPlan.ts
+++ b/src/rules/efs/EFSInBackupPlan.ts
@@ -6,7 +6,10 @@ import { parse } from 'path';
import { CfnBackupSelection } from '@aws-cdk/aws-backup';
import { CfnFileSystem } from '@aws-cdk/aws-efs';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* EFSs are part of AWS Backup plan(s)
@@ -14,7 +17,7 @@ import { resolveResourceFromInstrinsic } from '../../nag-pack';
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnFileSystem) {
const fileSystemLogicalId = resolveResourceFromInstrinsic(node, node.ref);
let found = false;
@@ -27,10 +30,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elasticache/ElastiCacheClusterInVPC.ts b/src/rules/elasticache/ElastiCacheClusterInVPC.ts
index 3425554f34..0d9b637026 100644
--- a/src/rules/elasticache/ElastiCacheClusterInVPC.ts
+++ b/src/rules/elasticache/ElastiCacheClusterInVPC.ts
@@ -5,13 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCacheCluster, CfnReplicationGroup } from '@aws-cdk/aws-elasticache';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* ElastiCache clusters are provisioned in a VPC
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (
node instanceof CfnCacheCluster ||
node instanceof CfnReplicationGroup
@@ -20,10 +21,12 @@ export default Object.defineProperty(
node.cacheSubnetGroupName == undefined ||
node.cacheSubnetGroupName.length == 0
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elasticache/ElastiCacheClusterNonDefaultPort.ts b/src/rules/elasticache/ElastiCacheClusterNonDefaultPort.ts
index e2f2cb2a37..c896f848d6 100644
--- a/src/rules/elasticache/ElastiCacheClusterNonDefaultPort.ts
+++ b/src/rules/elasticache/ElastiCacheClusterNonDefaultPort.ts
@@ -5,39 +5,42 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnReplicationGroup, CfnCacheCluster } from '@aws-cdk/aws-elasticache';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* ElastiCache clusters do not use the default endpoint ports
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCacheCluster) {
const port = resolveIfPrimitive(node, node.port);
if (port == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const engine = resolveIfPrimitive(node, node.engine);
if (engine.toLowerCase() == 'redis' && port == 6379) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
} else if (engine.toLowerCase() == 'memcached' && port == 11211) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnReplicationGroup) {
const port = resolveIfPrimitive(node, node.port);
if (port == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const engine = resolveIfPrimitive(node, node.engine);
if (
(engine == undefined || engine.toLowerCase() == 'redis') &&
port == 6379
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elasticache/ElastiCacheRedisClusterAutomaticBackup.ts b/src/rules/elasticache/ElastiCacheRedisClusterAutomaticBackup.ts
index 6fb094759a..cf4b225f71 100644
--- a/src/rules/elasticache/ElastiCacheRedisClusterAutomaticBackup.ts
+++ b/src/rules/elasticache/ElastiCacheRedisClusterAutomaticBackup.ts
@@ -5,27 +5,30 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCacheCluster, CfnReplicationGroup } from '@aws-cdk/aws-elasticache';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* ElastiCache Redis clusters retain automatic backups for at least 15 days
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCacheCluster) {
const engine = resolveIfPrimitive(node, node.engine.toLowerCase());
const retention = resolveIfPrimitive(node, node.snapshotRetentionLimit);
if (engine == 'redis' && (retention == undefined || retention < 15)) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnReplicationGroup) {
const retention = resolveIfPrimitive(node, node.snapshotRetentionLimit);
if (retention == undefined || retention < 15) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elasticache/ElastiCacheRedisClusterEncryption.ts b/src/rules/elasticache/ElastiCacheRedisClusterEncryption.ts
index 4329ab0440..6ebfb3a034 100644
--- a/src/rules/elasticache/ElastiCacheRedisClusterEncryption.ts
+++ b/src/rules/elasticache/ElastiCacheRedisClusterEncryption.ts
@@ -5,29 +5,30 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnReplicationGroup } from '@aws-cdk/aws-elasticache';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* ElastiCache Redis clusters have both encryption in transit and at rest enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnReplicationGroup) {
if (
node.atRestEncryptionEnabled == undefined ||
node.transitEncryptionEnabled == undefined
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const rest = resolveIfPrimitive(node, node.atRestEncryptionEnabled);
const transit = resolveIfPrimitive(node, node.transitEncryptionEnabled);
if (rest == false || transit == false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
-
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elasticache/ElastiCacheRedisClusterMultiAZ.ts b/src/rules/elasticache/ElastiCacheRedisClusterMultiAZ.ts
index a60ff2e92e..6f5acc09c2 100644
--- a/src/rules/elasticache/ElastiCacheRedisClusterMultiAZ.ts
+++ b/src/rules/elasticache/ElastiCacheRedisClusterMultiAZ.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnReplicationGroup } from '@aws-cdk/aws-elasticache';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* ElastiCache Redis clusters are deployed in a Multi-AZ configuration
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnReplicationGroup) {
if (node.multiAzEnabled == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const multiAz = resolveIfPrimitive(node, node.multiAzEnabled);
if (!multiAz) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elasticache/ElastiCacheRedisClusterRedisAuth.ts b/src/rules/elasticache/ElastiCacheRedisClusterRedisAuth.ts
index c1f33f2c1e..92abcf0951 100644
--- a/src/rules/elasticache/ElastiCacheRedisClusterRedisAuth.ts
+++ b/src/rules/elasticache/ElastiCacheRedisClusterRedisAuth.ts
@@ -5,19 +5,22 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnReplicationGroup } from '@aws-cdk/aws-elasticache';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* ElastiCache Redis clusters use Redis AUTH for user authentication
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnReplicationGroup) {
if (node.authToken == undefined || node.authToken.length == 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elasticbeanstalk/ElasticBeanstalkEC2InstanceLogsToS3.ts b/src/rules/elasticbeanstalk/ElasticBeanstalkEC2InstanceLogsToS3.ts
index 0c86589c38..b106ace6c9 100644
--- a/src/rules/elasticbeanstalk/ElasticBeanstalkEC2InstanceLogsToS3.ts
+++ b/src/rules/elasticbeanstalk/ElasticBeanstalkEC2InstanceLogsToS3.ts
@@ -5,6 +5,7 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnEnvironment } from '@aws-cdk/aws-elasticbeanstalk';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* EC2 instances in Elastic Beanstalk environments upload rotated logs to S3
@@ -12,11 +13,11 @@ import { CfnResource, Stack } from '@aws-cdk/core';
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnEnvironment) {
const optionSettings = Stack.of(node).resolve(node.optionSettings);
if (optionSettings == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
let foundEnabled = false;
for (const optionSetting of optionSettings) {
@@ -34,10 +35,12 @@ export default Object.defineProperty(
}
}
if (!foundEnabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elasticbeanstalk/ElasticBeanstalkEnhancedHealthReportingEnabled.ts b/src/rules/elasticbeanstalk/ElasticBeanstalkEnhancedHealthReportingEnabled.ts
index 3705836cd5..dd7fd9b41b 100644
--- a/src/rules/elasticbeanstalk/ElasticBeanstalkEnhancedHealthReportingEnabled.ts
+++ b/src/rules/elasticbeanstalk/ElasticBeanstalkEnhancedHealthReportingEnabled.ts
@@ -5,17 +5,18 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnEnvironment } from '@aws-cdk/aws-elasticbeanstalk';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Elastic Beanstalk environments have enhanced health reporting enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnEnvironment) {
const optionSettings = Stack.of(node).resolve(node.optionSettings);
if (optionSettings == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
let found = false;
for (const optionSetting of optionSettings) {
@@ -33,10 +34,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elasticbeanstalk/ElasticBeanstalkManagedUpdatesEnabled.ts b/src/rules/elasticbeanstalk/ElasticBeanstalkManagedUpdatesEnabled.ts
index edb26cff9f..0914b3a7bd 100644
--- a/src/rules/elasticbeanstalk/ElasticBeanstalkManagedUpdatesEnabled.ts
+++ b/src/rules/elasticbeanstalk/ElasticBeanstalkManagedUpdatesEnabled.ts
@@ -5,6 +5,7 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnEnvironment } from '@aws-cdk/aws-elasticbeanstalk';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Elastic Beanstalk environments have managed updates enabled
@@ -12,11 +13,11 @@ import { CfnResource, Stack } from '@aws-cdk/core';
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnEnvironment) {
const optionSettings = Stack.of(node).resolve(node.optionSettings);
if (optionSettings == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
let foundEnabled = false;
let foundLevel = false;
@@ -46,10 +47,12 @@ export default Object.defineProperty(
}
}
if (!foundEnabled || !foundLevel) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elasticbeanstalk/ElasticBeanstalkVPCSpecified.ts b/src/rules/elasticbeanstalk/ElasticBeanstalkVPCSpecified.ts
index 0d107a0452..239d8691c6 100644
--- a/src/rules/elasticbeanstalk/ElasticBeanstalkVPCSpecified.ts
+++ b/src/rules/elasticbeanstalk/ElasticBeanstalkVPCSpecified.ts
@@ -5,6 +5,7 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnEnvironment } from '@aws-cdk/aws-elasticbeanstalk';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Elastic Beanstalk environments are configured to use a specific VPC
@@ -12,11 +13,11 @@ import { CfnResource, Stack } from '@aws-cdk/core';
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnEnvironment) {
const optionSettings = Stack.of(node).resolve(node.optionSettings);
if (optionSettings == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
let foundEnabled = false;
for (const optionSetting of optionSettings) {
@@ -34,10 +35,12 @@ export default Object.defineProperty(
}
}
if (!foundEnabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elb/ALBHttpDropInvalidHeaderEnabled.ts b/src/rules/elb/ALBHttpDropInvalidHeaderEnabled.ts
index 53e82a3e11..088978d753 100644
--- a/src/rules/elb/ALBHttpDropInvalidHeaderEnabled.ts
+++ b/src/rules/elb/ALBHttpDropInvalidHeaderEnabled.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnLoadBalancer } from '@aws-cdk/aws-elasticloadbalancingv2';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Application Load Balancers are enabled to drop invalid headers
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnLoadBalancer) {
const type = resolveIfPrimitive(node, node.type);
if (type == undefined || type == 'application') {
@@ -21,14 +21,16 @@ export default Object.defineProperty(
const reg =
/"routing\.http\.drop_invalid_header_fields\.enabled","value":"true"/gm;
if (JSON.stringify(attributes).search(reg) == -1) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
} else {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elb/ALBHttpToHttpsRedirection.ts b/src/rules/elb/ALBHttpToHttpsRedirection.ts
index 06dd7db272..5741e9f987 100644
--- a/src/rules/elb/ALBHttpToHttpsRedirection.ts
+++ b/src/rules/elb/ALBHttpToHttpsRedirection.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnListener } from '@aws-cdk/aws-elasticloadbalancingv2';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* ALB HTTP listeners are configured to redirect to HTTPS
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnListener) {
let found = false;
const protocol = resolveIfPrimitive(node, node.protocol);
@@ -27,11 +27,12 @@ export default Object.defineProperty(
found = true;
}
}
- if (!found) return false;
+ if (!found) return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
-
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elb/ALBWAFEnabled.ts b/src/rules/elb/ALBWAFEnabled.ts
index 29819cf34f..2fcc063c49 100644
--- a/src/rules/elb/ALBWAFEnabled.ts
+++ b/src/rules/elb/ALBWAFEnabled.ts
@@ -9,6 +9,7 @@ import { CfnResource, Stack } from '@aws-cdk/core';
import {
resolveIfPrimitive,
resolveResourceFromInstrinsic,
+ NagRuleCompliance,
} from '../../nag-pack';
/**
@@ -17,7 +18,7 @@ import {
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnLoadBalancer) {
const type = resolveIfPrimitive(node, node.type);
if (type === undefined || type === 'application') {
@@ -35,11 +36,13 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elb/CLBConnectionDraining.ts b/src/rules/elb/CLBConnectionDraining.ts
index 1247f5a8f2..019fe561dd 100644
--- a/src/rules/elb/CLBConnectionDraining.ts
+++ b/src/rules/elb/CLBConnectionDraining.ts
@@ -5,26 +5,28 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnLoadBalancer } from '@aws-cdk/aws-elasticloadbalancing';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* CLBs have connection draining enabled.
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnLoadBalancer) {
if (node.connectionDrainingPolicy == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const draining = Stack.of(node).resolve(node.connectionDrainingPolicy);
const resolvedDraining = Stack.of(node).resolve(draining);
const enabled = resolveIfPrimitive(node, resolvedDraining.enabled);
if (enabled !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elb/CLBNoInboundHttpHttps.ts b/src/rules/elb/CLBNoInboundHttpHttps.ts
index 2ddeb3597b..fef16aa9ac 100644
--- a/src/rules/elb/CLBNoInboundHttpHttps.ts
+++ b/src/rules/elb/CLBNoInboundHttpHttps.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnLoadBalancer } from '@aws-cdk/aws-elasticloadbalancing';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* CLBs are not used for incoming HTTP/HTTPS traffic. Use ALBs instead.
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnLoadBalancer) {
const listeners = Stack.of(node).resolve(node.listeners);
for (const listener of listeners) {
@@ -22,11 +22,13 @@ export default Object.defineProperty(
protocol.toLowerCase() == 'http' ||
protocol.toLowerCase() == 'https'
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elb/ELBACMCertificateRequired.ts b/src/rules/elb/ELBACMCertificateRequired.ts
index 02334f427e..d123acfaa2 100644
--- a/src/rules/elb/ELBACMCertificateRequired.ts
+++ b/src/rules/elb/ELBACMCertificateRequired.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnLoadBalancer } from '@aws-cdk/aws-elasticloadbalancing';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* CLBs use ACM-managed certificates
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnLoadBalancer) {
//For each listener, ensure that it's utilizing an ACM SSL/HTTPS cert
const listeners = Stack.of(node).resolve(node.listeners);
@@ -26,17 +26,19 @@ export default Object.defineProperty(
);
//Use the ARN to check if this is an ACM managed cert
if (listenerARN == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
} else {
const acmRegex = /^arn:[^:]+:acm:.+$/;
if (!acmRegex.test(listenerARN)) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elb/ELBCrossZoneLoadBalancingEnabled.ts b/src/rules/elb/ELBCrossZoneLoadBalancingEnabled.ts
index 73a2756b85..d030dc4232 100644
--- a/src/rules/elb/ELBCrossZoneLoadBalancingEnabled.ts
+++ b/src/rules/elb/ELBCrossZoneLoadBalancingEnabled.ts
@@ -5,34 +5,36 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnLoadBalancer } from '@aws-cdk/aws-elasticloadbalancing';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* CLBs use at least two AZs with the Cross-Zone Load Balancing feature enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnLoadBalancer) {
if (node.crossZone == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
if (node.subnets == undefined) {
if (
node.availabilityZones == undefined ||
node.availabilityZones.length < 2
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
} else if (node.subnets.length < 2) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const crossZone = resolveIfPrimitive(node, node.crossZone);
if (crossZone != true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elb/ELBDeletionProtectionEnabled.ts b/src/rules/elb/ELBDeletionProtectionEnabled.ts
index 31b8b9c13f..3a82791bc2 100644
--- a/src/rules/elb/ELBDeletionProtectionEnabled.ts
+++ b/src/rules/elb/ELBDeletionProtectionEnabled.ts
@@ -5,13 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnLoadBalancer } from '@aws-cdk/aws-elasticloadbalancingv2';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* ALBs, NLBs, and GLBs have deletion protection enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnLoadBalancer) {
const attributes = Stack.of(node).resolve(node.loadBalancerAttributes);
if (attributes != undefined) {
@@ -28,13 +29,15 @@ export default Object.defineProperty(
}
}
if (!deletionProtectionEnabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
} else {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elb/ELBLoggingEnabled.ts b/src/rules/elb/ELBLoggingEnabled.ts
index a9da071d40..65fe8032a7 100644
--- a/src/rules/elb/ELBLoggingEnabled.ts
+++ b/src/rules/elb/ELBLoggingEnabled.ts
@@ -6,17 +6,17 @@ import { parse } from 'path';
import { CfnLoadBalancer } from '@aws-cdk/aws-elasticloadbalancing';
import { CfnLoadBalancer as CfnLoadBalancerV2 } from '@aws-cdk/aws-elasticloadbalancingv2';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* ELBs have access logs enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnLoadBalancer) {
if (node.accessLoggingPolicy == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const accessLoggingPolicy = Stack.of(node).resolve(
node.accessLoggingPolicy
@@ -24,17 +24,20 @@ export default Object.defineProperty(
const enabled = resolveIfPrimitive(node, accessLoggingPolicy.enabled);
if (enabled == false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnLoadBalancerV2) {
const attributes = Stack.of(node).resolve(node.loadBalancerAttributes);
const reg = /"access_logs\.s3\.enabled","value":"true"/gm;
if (JSON.stringify(attributes).search(reg) == -1) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elb/ELBTlsHttpsListenersOnly.ts b/src/rules/elb/ELBTlsHttpsListenersOnly.ts
index 2c2e4470dc..9df192ece6 100644
--- a/src/rules/elb/ELBTlsHttpsListenersOnly.ts
+++ b/src/rules/elb/ELBTlsHttpsListenersOnly.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnLoadBalancer } from '@aws-cdk/aws-elasticloadbalancing';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* CLB listeners are configured for secure (HTTPs or SSL) protocols for client communication
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnLoadBalancer) {
const listeners = Stack.of(node).resolve(node.listeners);
for (const listener of listeners) {
@@ -29,7 +29,7 @@ export default Object.defineProperty(
instanceProtocol.toLowerCase() == 'ssl'
)
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
} else if (protocol.toLowerCase() == 'https') {
if (
@@ -38,12 +38,14 @@ export default Object.defineProperty(
instanceProtocol.toLowerCase() == 'https'
)
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/elb/ELBv2ACMCertificateRequired.ts b/src/rules/elb/ELBv2ACMCertificateRequired.ts
index 483ca47565..16c03bc81a 100644
--- a/src/rules/elb/ELBv2ACMCertificateRequired.ts
+++ b/src/rules/elb/ELBv2ACMCertificateRequired.ts
@@ -5,17 +5,18 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnListener } from '@aws-cdk/aws-elasticloadbalancingv2';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* ALB, NLB, and GLB listeners use ACM-managed certificates
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnListener) {
const certificates = Stack.of(node).resolve(node.certificates);
if (certificates == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
let found = false;
for (const certificate of certificates) {
@@ -26,10 +27,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/emr/EMRAuthEC2KeyPairOrKerberos.ts b/src/rules/emr/EMRAuthEC2KeyPairOrKerberos.ts
index de0a97a25b..f03af36813 100644
--- a/src/rules/emr/EMRAuthEC2KeyPairOrKerberos.ts
+++ b/src/rules/emr/EMRAuthEC2KeyPairOrKerberos.ts
@@ -5,13 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-emr';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* EMR clusters implement authentication via an EC2 Key Pair or Kerberos
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const kerberosAttributes = Stack.of(node).resolve(
node.kerberosAttributes
@@ -19,11 +20,13 @@ export default Object.defineProperty(
if (kerberosAttributes == undefined) {
const instanceConfig = Stack.of(node).resolve(node.instances);
if (instanceConfig.ec2KeyName == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/emr/EMRKerberosEnabled.ts b/src/rules/emr/EMRKerberosEnabled.ts
index 7031c566bc..cd6460385b 100644
--- a/src/rules/emr/EMRKerberosEnabled.ts
+++ b/src/rules/emr/EMRKerberosEnabled.ts
@@ -5,22 +5,25 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-emr';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* EMR clusters have Kerberos enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const kerberosAttributes = Stack.of(node).resolve(
node.kerberosAttributes
);
if (kerberosAttributes == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/emr/EMRS3AccessLogging.ts b/src/rules/emr/EMRS3AccessLogging.ts
index d0bca18086..794f8ba4af 100644
--- a/src/rules/emr/EMRS3AccessLogging.ts
+++ b/src/rules/emr/EMRS3AccessLogging.ts
@@ -5,20 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-emr';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* EMR clusters have S3 logging enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const logUri = Stack.of(node).resolve(node.logUri);
if (logUri == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/iam/IAMGroupHasUsers.ts b/src/rules/iam/IAMGroupHasUsers.ts
index 2419177e55..ad712b5aa8 100644
--- a/src/rules/iam/IAMGroupHasUsers.ts
+++ b/src/rules/iam/IAMGroupHasUsers.ts
@@ -5,7 +5,10 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnGroup, CfnUser, CfnUserToGroupAddition } from '@aws-cdk/aws-iam';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* IAM Groups have at least one IAM User
@@ -13,7 +16,7 @@ import { resolveResourceFromInstrinsic } from '../../nag-pack';
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnGroup) {
const groupLogicalId = resolveResourceFromInstrinsic(node, node.ref);
const groupName = Stack.of(node).resolve(node.groupName);
@@ -32,10 +35,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/iam/IAMNoInlinePolicy.ts b/src/rules/iam/IAMNoInlinePolicy.ts
index 0dd6ac030a..72f63f19f1 100644
--- a/src/rules/iam/IAMNoInlinePolicy.ts
+++ b/src/rules/iam/IAMNoInlinePolicy.ts
@@ -5,13 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnRole, CfnUser, CfnGroup, CfnPolicy } from '@aws-cdk/aws-iam';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* IAM Groups, Users, and Roles do not contain inline policies
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (
node instanceof CfnGroup ||
node instanceof CfnUser ||
@@ -19,13 +20,14 @@ export default Object.defineProperty(
) {
const inlinePolicies = Stack.of(node).resolve(node.policies);
if (inlinePolicies != undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else if (node instanceof CfnPolicy) {
+ return NagRuleCompliance.NON_COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- if (node instanceof CfnPolicy) {
- return false;
- }
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/iam/IAMNoManagedPolicies.ts b/src/rules/iam/IAMNoManagedPolicies.ts
index 373d0b68a2..ff31c664d4 100644
--- a/src/rules/iam/IAMNoManagedPolicies.ts
+++ b/src/rules/iam/IAMNoManagedPolicies.ts
@@ -5,13 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnRole, CfnUser, CfnGroup } from '@aws-cdk/aws-iam';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* IAM users, roles, and groups do not use AWS managed policies
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (
node instanceof CfnGroup ||
node instanceof CfnUser ||
@@ -25,12 +26,14 @@ export default Object.defineProperty(
if (
!(/\d{12}/.test(arnPrefix) || arnPrefix.includes('AWS::AccountId'))
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/iam/IAMNoWildcardPermissions.ts b/src/rules/iam/IAMNoWildcardPermissions.ts
index f763dfdb56..e59491f0c8 100644
--- a/src/rules/iam/IAMNoWildcardPermissions.ts
+++ b/src/rules/iam/IAMNoWildcardPermissions.ts
@@ -11,13 +11,14 @@ import {
CfnManagedPolicy,
} from '@aws-cdk/aws-iam';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* IAM entities with wildcard permissions have a cdk_nag rule suppression with evidence for those permission
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (
node instanceof CfnGroup ||
node instanceof CfnUser ||
@@ -31,17 +32,20 @@ export default Object.defineProperty(
resolvedPolicy.policyDocument
);
if (JSON.stringify(resolvedPolicyDocument).includes('*')) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnPolicy || node instanceof CfnManagedPolicy) {
const policyDocument = Stack.of(node).resolve(node.policyDocument);
if (JSON.stringify(policyDocument).includes('*')) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/iam/IAMPolicyNoStatementsWithAdminAccess.ts b/src/rules/iam/IAMPolicyNoStatementsWithAdminAccess.ts
index c06ee07855..f9029c902c 100644
--- a/src/rules/iam/IAMPolicyNoStatementsWithAdminAccess.ts
+++ b/src/rules/iam/IAMPolicyNoStatementsWithAdminAccess.ts
@@ -11,23 +11,27 @@ import {
CfnRole,
} from '@aws-cdk/aws-iam';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* IAM policies do not grant admin access
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnPolicy || node instanceof CfnManagedPolicy) {
if (checkDocument(node, node.policyDocument)) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnGroup || node instanceof CfnRole) {
if (node.policies != undefined && checkDocument(node, node.policies)) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/iam/IAMPolicyNoStatementsWithFullAccess.ts b/src/rules/iam/IAMPolicyNoStatementsWithFullAccess.ts
index cc22ecee6e..2f453e91dc 100644
--- a/src/rules/iam/IAMPolicyNoStatementsWithFullAccess.ts
+++ b/src/rules/iam/IAMPolicyNoStatementsWithFullAccess.ts
@@ -11,23 +11,27 @@ import {
CfnRole,
} from '@aws-cdk/aws-iam';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* IAM policies do not grant full access
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnPolicy || node instanceof CfnManagedPolicy) {
if (checkDocument(node, node.policyDocument)) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnGroup || node instanceof CfnRole) {
if (node.policies != undefined && checkDocument(node, node.policies)) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/iam/IAMUserGroupMembership.ts b/src/rules/iam/IAMUserGroupMembership.ts
index c10b262425..d8d7db715f 100644
--- a/src/rules/iam/IAMUserGroupMembership.ts
+++ b/src/rules/iam/IAMUserGroupMembership.ts
@@ -5,20 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnUser } from '@aws-cdk/aws-iam';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* IAM users are assigned to at least one group
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnUser) {
const userGroup = Stack.of(node).resolve(node.groups);
if (userGroup == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/iam/IAMUserNoPolicies.ts b/src/rules/iam/IAMUserNoPolicies.ts
index 6ddd2e23c9..7295490fa5 100644
--- a/src/rules/iam/IAMUserNoPolicies.ts
+++ b/src/rules/iam/IAMUserNoPolicies.ts
@@ -5,25 +5,29 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnPolicy, CfnManagedPolicy, CfnUser } from '@aws-cdk/aws-iam';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* IAM policies are not attached at the user level
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnPolicy || node instanceof CfnManagedPolicy) {
const policyUsers = Stack.of(node).resolve(node.users);
if (policyUsers != undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnUser) {
const policies = Stack.of(node).resolve(node.policies);
const managedPolicyArns = Stack.of(node).resolve(node.managedPolicyArns);
if (policies != undefined || managedPolicyArns != undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/kinesis/KinesisDataAnalyticsFlinkCheckpointing.ts b/src/rules/kinesis/KinesisDataAnalyticsFlinkCheckpointing.ts
index df18c3f582..bfc68034aa 100644
--- a/src/rules/kinesis/KinesisDataAnalyticsFlinkCheckpointing.ts
+++ b/src/rules/kinesis/KinesisDataAnalyticsFlinkCheckpointing.ts
@@ -5,33 +5,33 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnApplicationV2 } from '@aws-cdk/aws-kinesisanalytics';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Kinesis Data Analytics Flink Applications have checkpointing enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnApplicationV2) {
if (node.runtimeEnvironment.toLowerCase().startsWith('flink')) {
const applicationConfiguration = Stack.of(node).resolve(
node.applicationConfiguration
);
if (applicationConfiguration == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const flinkApplicationConfiguration = Stack.of(node).resolve(
applicationConfiguration.flinkApplicationConfiguration
);
if (flinkApplicationConfiguration == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const checkpointConfiguration = Stack.of(node).resolve(
flinkApplicationConfiguration.checkpointConfiguration
);
if (checkpointConfiguration == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
if (
resolveIfPrimitive(node, checkpointConfiguration.configurationType) ==
@@ -42,12 +42,14 @@ export default Object.defineProperty(
checkpointConfiguration.checkpointingEnabled
);
if (!enabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/kinesis/KinesisDataFirehoseSSE.ts b/src/rules/kinesis/KinesisDataFirehoseSSE.ts
index 0b0c5dfec4..bbf92cf1fb 100644
--- a/src/rules/kinesis/KinesisDataFirehoseSSE.ts
+++ b/src/rules/kinesis/KinesisDataFirehoseSSE.ts
@@ -5,22 +5,25 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDeliveryStream } from '@aws-cdk/aws-kinesisfirehose';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Kinesis Data Firehose delivery stream have server-side encryption enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDeliveryStream) {
const deliveryStreamEncryptionConfigurationInput = Stack.of(node).resolve(
node.deliveryStreamEncryptionConfigurationInput
);
if (deliveryStreamEncryptionConfigurationInput == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/kinesis/KinesisDataStreamDefaultKeyWhenSSE.ts b/src/rules/kinesis/KinesisDataStreamDefaultKeyWhenSSE.ts
index 092b9e64e4..63eef9e1d4 100644
--- a/src/rules/kinesis/KinesisDataStreamDefaultKeyWhenSSE.ts
+++ b/src/rules/kinesis/KinesisDataStreamDefaultKeyWhenSSE.ts
@@ -5,22 +5,25 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnStream } from '@aws-cdk/aws-kinesis';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Kinesis Data Streams use the "aws/kinesis" key when server-sided encryption is enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnStream) {
const streamEncryption = Stack.of(node).resolve(node.streamEncryption);
if (streamEncryption !== undefined) {
if (streamEncryption.keyId !== 'alias/aws/kinesis') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/kinesis/KinesisDataStreamSSE.ts b/src/rules/kinesis/KinesisDataStreamSSE.ts
index 7c180eb1c7..c86f01bbf7 100644
--- a/src/rules/kinesis/KinesisDataStreamSSE.ts
+++ b/src/rules/kinesis/KinesisDataStreamSSE.ts
@@ -5,20 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnStream } from '@aws-cdk/aws-kinesis';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Kinesis Data Streams have server-side encryption enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnStream) {
const streamEncryption = Stack.of(node).resolve(node.streamEncryption);
if (streamEncryption == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/kms/KMSBackingKeyRotationEnabled.ts b/src/rules/kms/KMSBackingKeyRotationEnabled.ts
index bbd4ff5c26..aa53d48be3 100644
--- a/src/rules/kms/KMSBackingKeyRotationEnabled.ts
+++ b/src/rules/kms/KMSBackingKeyRotationEnabled.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnKey, KeySpec } from '@aws-cdk/aws-kms';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* KMS Symmetric keys have automatic key rotation enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnKey) {
const keySpec = Stack.of(node).resolve(node.keySpec);
if (keySpec == undefined || keySpec == KeySpec.SYMMETRIC_DEFAULT) {
@@ -21,11 +21,13 @@ export default Object.defineProperty(
node.enableKeyRotation
);
if (enableKeyRotation !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/lambda/LambdaConcurrency.ts b/src/rules/lambda/LambdaConcurrency.ts
index bb9875385c..ed3c5791a7 100644
--- a/src/rules/lambda/LambdaConcurrency.ts
+++ b/src/rules/lambda/LambdaConcurrency.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnFunction } from '@aws-cdk/aws-lambda';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Lambda functions are configured with function-level concurrent execution limits
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnFunction) {
const reservedConcurrentExecutions = resolveIfPrimitive(
node,
@@ -22,10 +22,12 @@ export default Object.defineProperty(
reservedConcurrentExecutions == undefined ||
reservedConcurrentExecutions === 0
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/lambda/LambdaDLQ.ts b/src/rules/lambda/LambdaDLQ.ts
index 86c8ec251b..943bd6cbe3 100644
--- a/src/rules/lambda/LambdaDLQ.ts
+++ b/src/rules/lambda/LambdaDLQ.ts
@@ -5,23 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnFunction } from '@aws-cdk/aws-lambda';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Lambda functions are configured with a dead-letter configuration
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnFunction) {
const deadLetterConfig = Stack.of(node).resolve(node.deadLetterConfig);
if (
deadLetterConfig == undefined ||
deadLetterConfig.targetArn == undefined
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/lambda/LambdaInsideVPC.ts b/src/rules/lambda/LambdaInsideVPC.ts
index 97fcc554fa..bf3915c49e 100644
--- a/src/rules/lambda/LambdaInsideVPC.ts
+++ b/src/rules/lambda/LambdaInsideVPC.ts
@@ -5,28 +5,31 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnFunction } from '@aws-cdk/aws-lambda';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Lambda functions are VPC enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnFunction) {
const vpcConfig = Stack.of(node).resolve(node.vpcConfig);
if (vpcConfig == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
} else {
const secgroups = Stack.of(node).resolve(vpcConfig.securityGroupIds);
const subnets = Stack.of(node).resolve(vpcConfig.subnetIds);
if (secgroups == undefined || secgroups.length == 0) {
if (subnets == undefined || subnets.length == 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/mediastore/MediaStoreCloudWatchMetricPolicy.ts b/src/rules/mediastore/MediaStoreCloudWatchMetricPolicy.ts
index c688eb4fd9..96f7556e59 100644
--- a/src/rules/mediastore/MediaStoreCloudWatchMetricPolicy.ts
+++ b/src/rules/mediastore/MediaStoreCloudWatchMetricPolicy.ts
@@ -5,28 +5,30 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnContainer } from '@aws-cdk/aws-mediastore';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Media Store containers define metric policies to send metrics to CloudWatch
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnContainer) {
const metricPolicy = Stack.of(node).resolve(node.metricPolicy);
if (metricPolicy == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const containerLevelMetrics = resolveIfPrimitive(
node,
metricPolicy.containerLevelMetrics
);
if (containerLevelMetrics != 'ENABLED') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/mediastore/MediaStoreContainerAccessLogging.ts b/src/rules/mediastore/MediaStoreContainerAccessLogging.ts
index 911f5a4176..ae182d8cd5 100644
--- a/src/rules/mediastore/MediaStoreContainerAccessLogging.ts
+++ b/src/rules/mediastore/MediaStoreContainerAccessLogging.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnContainer } from '@aws-cdk/aws-mediastore';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Media Store containers have container access logging enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnContainer) {
const accessLoggingEnabled = resolveIfPrimitive(
node,
node.accessLoggingEnabled
);
if (accessLoggingEnabled !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/mediastore/MediaStoreContainerCORSPolicy.ts b/src/rules/mediastore/MediaStoreContainerCORSPolicy.ts
index aad8fc78f5..60796c68ef 100644
--- a/src/rules/mediastore/MediaStoreContainerCORSPolicy.ts
+++ b/src/rules/mediastore/MediaStoreContainerCORSPolicy.ts
@@ -5,20 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnContainer } from '@aws-cdk/aws-mediastore';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Media Store containers define CORS policies
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnContainer) {
const corsPolicy = Stack.of(node).resolve(node.corsPolicy);
if (corsPolicy == undefined || corsPolicy.length == 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/mediastore/MediaStoreContainerHasContainerPolicy.ts b/src/rules/mediastore/MediaStoreContainerHasContainerPolicy.ts
index 80dfcea291..4b0955a540 100644
--- a/src/rules/mediastore/MediaStoreContainerHasContainerPolicy.ts
+++ b/src/rules/mediastore/MediaStoreContainerHasContainerPolicy.ts
@@ -5,20 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnContainer } from '@aws-cdk/aws-mediastore';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Media Store containers define container policies
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnContainer) {
const policy = Stack.of(node).resolve(node.policy);
if (policy == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/mediastore/MediaStoreContainerLifecyclePolicy.ts b/src/rules/mediastore/MediaStoreContainerLifecyclePolicy.ts
index 4f1bb8583c..6543bcee13 100644
--- a/src/rules/mediastore/MediaStoreContainerLifecyclePolicy.ts
+++ b/src/rules/mediastore/MediaStoreContainerLifecyclePolicy.ts
@@ -5,20 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnContainer } from '@aws-cdk/aws-mediastore';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Media Store containers define lifecycle policies
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnContainer) {
const lifecyclePolicy = Stack.of(node).resolve(node.lifecyclePolicy);
if (lifecyclePolicy == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/msk/MSKBrokerLogging.ts b/src/rules/msk/MSKBrokerLogging.ts
index 1cb3834d8b..8ce2ecac05 100644
--- a/src/rules/msk/MSKBrokerLogging.ts
+++ b/src/rules/msk/MSKBrokerLogging.ts
@@ -5,18 +5,18 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-msk';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* MSK clusters send broker logs to a supported destination
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const loggingInfo = Stack.of(node).resolve(node.loggingInfo);
if (loggingInfo == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const resolvedBrokerLogs = Stack.of(node).resolve(loggingInfo.brokerLogs);
let enabled = false;
@@ -47,10 +47,12 @@ export default Object.defineProperty(
}
}
if (!enabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/msk/MSKBrokerToBrokerTLS.ts b/src/rules/msk/MSKBrokerToBrokerTLS.ts
index 1708ab2495..24d6958c00 100644
--- a/src/rules/msk/MSKBrokerToBrokerTLS.ts
+++ b/src/rules/msk/MSKBrokerToBrokerTLS.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-msk';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* MSK clusters use TLS communication between brokers
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const encryptionInfo = Stack.of(node).resolve(node.encryptionInfo);
if (encryptionInfo != undefined) {
@@ -25,12 +25,14 @@ export default Object.defineProperty(
encryptionInTransit.inCluster
);
if (inCluster === false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/msk/MSKClientToBrokerTLS.ts b/src/rules/msk/MSKClientToBrokerTLS.ts
index e3b5816e0b..493fbaa7aa 100644
--- a/src/rules/msk/MSKClientToBrokerTLS.ts
+++ b/src/rules/msk/MSKClientToBrokerTLS.ts
@@ -3,16 +3,16 @@ Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
import { parse } from 'path';
-import { CfnCluster, ClientBrokerEncryption } from '@aws-cdk/aws-msk';
+import { CfnCluster } from '@aws-cdk/aws-msk';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* MSK clusters only uses TLS communication between clients and brokers
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const encryptionInfo = Stack.of(node).resolve(node.encryptionInfo);
if (encryptionInfo != undefined) {
@@ -24,16 +24,15 @@ export default Object.defineProperty(
node,
encryptionInTransit.clientBroker
);
- if (
- clientBroker != undefined &&
- clientBroker != ClientBrokerEncryption.TLS
- ) {
- return false;
+ if (clientBroker != undefined && clientBroker != 'TLS') {
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/neptune/NeptuneClusterAutomaticMinorVersionUpgrade.ts b/src/rules/neptune/NeptuneClusterAutomaticMinorVersionUpgrade.ts
index 093861e71a..6406125e1a 100644
--- a/src/rules/neptune/NeptuneClusterAutomaticMinorVersionUpgrade.ts
+++ b/src/rules/neptune/NeptuneClusterAutomaticMinorVersionUpgrade.ts
@@ -5,27 +5,29 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBInstance } from '@aws-cdk/aws-neptune';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Neptune DB instances have Auto Minor Version Upgrade enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBInstance) {
if (node.autoMinorVersionUpgrade == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const autoMinorVersionUpgrade = resolveIfPrimitive(
node,
node.autoMinorVersionUpgrade
);
if (!autoMinorVersionUpgrade) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/neptune/NeptuneClusterBackupRetentionPeriod.ts b/src/rules/neptune/NeptuneClusterBackupRetentionPeriod.ts
index d4f512d7ca..5299894116 100644
--- a/src/rules/neptune/NeptuneClusterBackupRetentionPeriod.ts
+++ b/src/rules/neptune/NeptuneClusterBackupRetentionPeriod.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster } from '@aws-cdk/aws-neptune';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Neptune DB clusters have a reasonable minimum backup retention period configured
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
const backupRetentionPeriod = resolveIfPrimitive(
node,
node.backupRetentionPeriod
);
if (backupRetentionPeriod == undefined || backupRetentionPeriod < 7) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/neptune/NeptuneClusterEncryptionAtRest.ts b/src/rules/neptune/NeptuneClusterEncryptionAtRest.ts
index da8ce840b3..29a57b0482 100644
--- a/src/rules/neptune/NeptuneClusterEncryptionAtRest.ts
+++ b/src/rules/neptune/NeptuneClusterEncryptionAtRest.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster } from '@aws-cdk/aws-neptune';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Neptune DB clusters have encryption at rest enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
if (node.storageEncrypted == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const storageEncrypted = resolveIfPrimitive(node, node.storageEncrypted);
if (!storageEncrypted) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/neptune/NeptuneClusterIAMAuth.ts b/src/rules/neptune/NeptuneClusterIAMAuth.ts
index 168cf9d01d..9d5a0cd5bd 100644
--- a/src/rules/neptune/NeptuneClusterIAMAuth.ts
+++ b/src/rules/neptune/NeptuneClusterIAMAuth.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster } from '@aws-cdk/aws-neptune';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Neptune DB clusters have IAM Database Authentication enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
if (node.iamAuthEnabled == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const iamAuthEnabled = resolveIfPrimitive(node, node.iamAuthEnabled);
if (!iamAuthEnabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/neptune/NeptuneClusterMultiAZ.ts b/src/rules/neptune/NeptuneClusterMultiAZ.ts
index 5cd5c37285..5089e33293 100644
--- a/src/rules/neptune/NeptuneClusterMultiAZ.ts
+++ b/src/rules/neptune/NeptuneClusterMultiAZ.ts
@@ -5,25 +5,28 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster } from '@aws-cdk/aws-neptune';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Neptune DB clusters are deployed in a Multi-AZ configuration
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
if (node.dbSubnetGroupName == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
if (
node.availabilityZones != undefined &&
node.availabilityZones.length < 2
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/opensearch/OpenSearchAllowlistedIPs.ts b/src/rules/opensearch/OpenSearchAllowlistedIPs.ts
index 7ec55a22f6..c0fa86d78c 100644
--- a/src/rules/opensearch/OpenSearchAllowlistedIPs.ts
+++ b/src/rules/opensearch/OpenSearchAllowlistedIPs.ts
@@ -6,32 +6,35 @@ import { parse } from 'path';
import { CfnDomain as LegacyCfnDomain } from '@aws-cdk/aws-elasticsearch';
import { CfnDomain } from '@aws-cdk/aws-opensearchservice';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* OpenSearch Service domains only grant access via allowlisted IP addresses
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof LegacyCfnDomain || node instanceof CfnDomain) {
const accessPolicies = Stack.of(node).resolve(node.accessPolicies);
if (accessPolicies === undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const statements = accessPolicies?.Statement;
if (statements === undefined || statements.length === 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
for (const statement of statements) {
if (statement.Effect === 'Allow') {
const allowList = statement?.Condition?.IpAddress?.['aws:sourceIp'];
if (allowList === undefined || allowList.length === 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/opensearch/OpenSearchDedicatedMasterNode.ts b/src/rules/opensearch/OpenSearchDedicatedMasterNode.ts
index c92ca1373c..f369e735c5 100644
--- a/src/rules/opensearch/OpenSearchDedicatedMasterNode.ts
+++ b/src/rules/opensearch/OpenSearchDedicatedMasterNode.ts
@@ -6,42 +6,45 @@ import { parse } from 'path';
import { CfnDomain as LegacyCfnDomain } from '@aws-cdk/aws-elasticsearch';
import { CfnDomain } from '@aws-cdk/aws-opensearchservice';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* OpenSearch Service domains use dedicated master nodes
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof LegacyCfnDomain) {
const elasticsearchClusterConfig = Stack.of(node).resolve(
node.elasticsearchClusterConfig
);
if (elasticsearchClusterConfig == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const dedicatedMasterEnabled = resolveIfPrimitive(
node,
elasticsearchClusterConfig.dedicatedMasterEnabled
);
if (!dedicatedMasterEnabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnDomain) {
const clusterConfig = Stack.of(node).resolve(node.clusterConfig);
if (clusterConfig == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const dedicatedMasterEnabled = resolveIfPrimitive(
node,
clusterConfig.dedicatedMasterEnabled
);
if (!dedicatedMasterEnabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/opensearch/OpenSearchEncryptedAtRest.ts b/src/rules/opensearch/OpenSearchEncryptedAtRest.ts
index adaacbf1de..89e1ba6e86 100644
--- a/src/rules/opensearch/OpenSearchEncryptedAtRest.ts
+++ b/src/rules/opensearch/OpenSearchEncryptedAtRest.ts
@@ -6,14 +6,14 @@ import { parse } from 'path';
import { CfnDomain as LegacyCfnDomain } from '@aws-cdk/aws-elasticsearch';
import { CfnDomain } from '@aws-cdk/aws-opensearchservice';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* OpenSearch Service domains have encryption at rest enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof LegacyCfnDomain || node instanceof CfnDomain) {
const encryptionAtRestOptions = Stack.of(node).resolve(
node.encryptionAtRestOptions
@@ -24,13 +24,15 @@ export default Object.defineProperty(
encryptionAtRestOptions.enabled
);
if (enabled !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
} else {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/opensearch/OpenSearchErrorLogsToCloudWatch.ts b/src/rules/opensearch/OpenSearchErrorLogsToCloudWatch.ts
index 657f803a53..212197a816 100644
--- a/src/rules/opensearch/OpenSearchErrorLogsToCloudWatch.ts
+++ b/src/rules/opensearch/OpenSearchErrorLogsToCloudWatch.ts
@@ -6,28 +6,31 @@ import { parse } from 'path';
import { CfnDomain as LegacyCfnDomain } from '@aws-cdk/aws-elasticsearch';
import { CfnDomain } from '@aws-cdk/aws-opensearchservice';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* OpenSearch Service domains stream error logs to CloudWatch Logs
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof LegacyCfnDomain || node instanceof CfnDomain) {
const logPublishingOptions = Stack.of(node).resolve(
node.logPublishingOptions
);
if (logPublishingOptions === undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const resolvedLog = Stack.of(node).resolve(
logPublishingOptions?.ES_APPLICATION_LOGS
);
if (resolvedLog === undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/opensearch/OpenSearchInVPCOnly.ts b/src/rules/opensearch/OpenSearchInVPCOnly.ts
index 4c754eb0a3..cbc01efd47 100644
--- a/src/rules/opensearch/OpenSearchInVPCOnly.ts
+++ b/src/rules/opensearch/OpenSearchInVPCOnly.ts
@@ -6,24 +6,27 @@ import { parse } from 'path';
import { CfnDomain as LegacyCfnDomain } from '@aws-cdk/aws-elasticsearch';
import { CfnDomain } from '@aws-cdk/aws-opensearchservice';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* OpenSearch Service domains are within VPCs
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof LegacyCfnDomain || node instanceof CfnDomain) {
const vpcOptions = Stack.of(node).resolve(node.vpcOptions);
if (vpcOptions === undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const subnetIds = Stack.of(node).resolve(vpcOptions.subnetIds);
if (subnetIds === undefined || subnetIds.length === 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/opensearch/OpenSearchNoUnsignedOrAnonymousAccess.ts b/src/rules/opensearch/OpenSearchNoUnsignedOrAnonymousAccess.ts
index c8f332ea00..827f5a6f70 100644
--- a/src/rules/opensearch/OpenSearchNoUnsignedOrAnonymousAccess.ts
+++ b/src/rules/opensearch/OpenSearchNoUnsignedOrAnonymousAccess.ts
@@ -6,21 +6,22 @@ import { parse } from 'path';
import { CfnDomain as LegacyCfnDomain } from '@aws-cdk/aws-elasticsearch';
import { CfnDomain } from '@aws-cdk/aws-opensearchservice';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* OpenSearch Service domains do not allow for unsigned requests or anonymous access
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof LegacyCfnDomain || node instanceof CfnDomain) {
const accessPolicies = Stack.of(node).resolve(node.accessPolicies);
if (accessPolicies == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const statements = accessPolicies?.Statement;
if (statements == undefined || statements.length == 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
for (const statement of statements) {
if (statement.Effect == 'Allow') {
@@ -28,12 +29,14 @@ export default Object.defineProperty(
? JSON.stringify(statement.Principal)
: '';
if (awsString.includes('*')) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/opensearch/OpenSearchNodeToNodeEncryption.ts b/src/rules/opensearch/OpenSearchNodeToNodeEncryption.ts
index 0e763f8eae..4895ef2776 100644
--- a/src/rules/opensearch/OpenSearchNodeToNodeEncryption.ts
+++ b/src/rules/opensearch/OpenSearchNodeToNodeEncryption.ts
@@ -6,14 +6,14 @@ import { parse } from 'path';
import { CfnDomain as LegacyCfnDomain } from '@aws-cdk/aws-elasticsearch';
import { CfnDomain } from '@aws-cdk/aws-opensearchservice';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* OpenSearch Service domains are node-to-node encrypted
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof LegacyCfnDomain || node instanceof CfnDomain) {
const encryptedNodeToNode = Stack.of(node).resolve(
node.nodeToNodeEncryptionOptions
@@ -21,13 +21,15 @@ export default Object.defineProperty(
if (encryptedNodeToNode != undefined) {
const enabled = resolveIfPrimitive(node, encryptedNodeToNode.enabled);
if (enabled !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
} else {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/opensearch/OpenSearchSlowLogsToCloudWatch.ts b/src/rules/opensearch/OpenSearchSlowLogsToCloudWatch.ts
index 3acd59799a..6911d00426 100644
--- a/src/rules/opensearch/OpenSearchSlowLogsToCloudWatch.ts
+++ b/src/rules/opensearch/OpenSearchSlowLogsToCloudWatch.ts
@@ -6,20 +6,20 @@ import { parse } from 'path';
import { CfnDomain as LegacyCfnDomain } from '@aws-cdk/aws-elasticsearch';
import { CfnDomain } from '@aws-cdk/aws-opensearchservice';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* OpenSearch Service domains minimally publish SEARCH_SLOW_LOGS and INDEX_SLOW_LOGS to CloudWatch Logs
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof LegacyCfnDomain || node instanceof CfnDomain) {
const logPublishingOptions = Stack.of(node).resolve(
node.logPublishingOptions
);
if (logPublishingOptions == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const requiredSlowLogs = [
logPublishingOptions?.SEARCH_SLOW_LOGS,
@@ -28,15 +28,17 @@ export default Object.defineProperty(
for (const log of requiredSlowLogs) {
const resolvedLog = Stack.of(node).resolve(log);
if (resolvedLog == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const enabled = resolveIfPrimitive(node, resolvedLog.enabled);
if (!enabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/opensearch/OpenSearchZoneAwareness.ts b/src/rules/opensearch/OpenSearchZoneAwareness.ts
index 59dd7f0852..93f83e21f0 100644
--- a/src/rules/opensearch/OpenSearchZoneAwareness.ts
+++ b/src/rules/opensearch/OpenSearchZoneAwareness.ts
@@ -6,42 +6,45 @@ import { parse } from 'path';
import { CfnDomain as LegacyCfnDomain } from '@aws-cdk/aws-elasticsearch';
import { CfnDomain } from '@aws-cdk/aws-opensearchservice';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* OpenSearch Service domains have Zone Awareness enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof LegacyCfnDomain) {
const elasticsearchClusterConfig = Stack.of(node).resolve(
node.elasticsearchClusterConfig
);
if (elasticsearchClusterConfig == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const zoneAwarenessEnabled = resolveIfPrimitive(
node,
elasticsearchClusterConfig.zoneAwarenessEnabled
);
if (!zoneAwarenessEnabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnDomain) {
const clusterConfig = Stack.of(node).resolve(node.clusterConfig);
if (clusterConfig == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const zoneAwarenessEnabled = resolveIfPrimitive(
node,
clusterConfig.zoneAwarenessEnabled
);
if (!zoneAwarenessEnabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/quicksight/QuicksightSSLConnections.ts b/src/rules/quicksight/QuicksightSSLConnections.ts
index e09a8b4fee..bf4e7a8b7c 100644
--- a/src/rules/quicksight/QuicksightSSLConnections.ts
+++ b/src/rules/quicksight/QuicksightSSLConnections.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDataSource } from '@aws-cdk/aws-quicksight';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Quicksight uses SSL when connecting to a data source
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDataSource) {
const sslProperties = Stack.of(node).resolve(node.sslProperties);
if (sslProperties != undefined) {
const disableSsl = resolveIfPrimitive(node, sslProperties.disableSsl);
if (disableSsl === true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/AuroraMySQLBacktrack.ts b/src/rules/rds/AuroraMySQLBacktrack.ts
index 1c6c144481..fcd1b2f378 100644
--- a/src/rules/rds/AuroraMySQLBacktrack.ts
+++ b/src/rules/rds/AuroraMySQLBacktrack.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster } from '@aws-cdk/aws-rds';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* RDS Aurora serverless clusters have Log Exports enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
const engine = resolveIfPrimitive(node, node.engine).toLowerCase();
const backtrackWindow = resolveIfPrimitive(node, node.backtrackWindow);
if (engine == 'aurora' || engine == 'aurora-mysql') {
if (backtrackWindow == undefined || backtrackWindow == 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/AuroraMySQLLogging.ts b/src/rules/rds/AuroraMySQLLogging.ts
index ea918aa0a5..b9188085d8 100644
--- a/src/rules/rds/AuroraMySQLLogging.ts
+++ b/src/rules/rds/AuroraMySQLLogging.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster } from '@aws-cdk/aws-rds';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* RDS Aurora MySQL serverless clusters have audit, error, general, and slowquery Log Exports enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
const engine = resolveIfPrimitive(node, node.engine).toLowerCase();
const engineMode = resolveIfPrimitive(
@@ -26,16 +26,21 @@ export default Object.defineProperty(
engine.toLowerCase() == 'aurora-mysql')
) {
if (node.enableCloudwatchLogsExports == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const needed = ['audit', 'error', 'general', 'slowquery'];
const exports = node.enableCloudwatchLogsExports.map((i) => {
return i.toLowerCase();
});
- return needed.every((i) => exports.includes(i));
+ const compliant = needed.every((i) => exports.includes(i));
+ if (compliant !== true) {
+ return NagRuleCompliance.NON_COMPLIANT;
+ }
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/AuroraMySQLPostgresIAMAuth.ts b/src/rules/rds/AuroraMySQLPostgresIAMAuth.ts
index 7625ba1296..887c42aeda 100644
--- a/src/rules/rds/AuroraMySQLPostgresIAMAuth.ts
+++ b/src/rules/rds/AuroraMySQLPostgresIAMAuth.ts
@@ -5,30 +5,31 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster } from '@aws-cdk/aws-rds';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* RDS Aurora MySQL/PostgresSQL clusters have IAM Database Authentication enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
if (node.engine.toLowerCase().includes('aurora')) {
if (node.enableIamDatabaseAuthentication == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const iamAuth = resolveIfPrimitive(
node,
node.enableIamDatabaseAuthentication
);
if (iamAuth == false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
-
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/RDSAutomaticMinorVersionUpgradeEnabled.ts b/src/rules/rds/RDSAutomaticMinorVersionUpgradeEnabled.ts
index f12d377fc3..d5821a81db 100644
--- a/src/rules/rds/RDSAutomaticMinorVersionUpgradeEnabled.ts
+++ b/src/rules/rds/RDSAutomaticMinorVersionUpgradeEnabled.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBInstance } from '@aws-cdk/aws-rds';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* RDS DB instances have automatic minor version upgrades enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBInstance) {
const autoMinorVersionUpgrade = resolveIfPrimitive(
node,
node.autoMinorVersionUpgrade
);
if (autoMinorVersionUpgrade === false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/RDSEnhancedMonitoringEnabled.ts b/src/rules/rds/RDSEnhancedMonitoringEnabled.ts
index 935c608fe3..a9296f65d9 100644
--- a/src/rules/rds/RDSEnhancedMonitoringEnabled.ts
+++ b/src/rules/rds/RDSEnhancedMonitoringEnabled.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBInstance } from '@aws-cdk/aws-rds';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* RDS DB instances have enhanced monitoring enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBInstance) {
const enhancedMonitoring = resolveIfPrimitive(
node,
node.monitoringInterval
);
if (enhancedMonitoring == undefined || enhancedMonitoring <= 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/RDSInBackupPlan.ts b/src/rules/rds/RDSInBackupPlan.ts
index 2b556c0d71..5503dc6384 100644
--- a/src/rules/rds/RDSInBackupPlan.ts
+++ b/src/rules/rds/RDSInBackupPlan.ts
@@ -6,7 +6,10 @@ import { parse } from 'path';
import { CfnBackupSelection } from '@aws-cdk/aws-backup';
import { CfnDBInstance } from '@aws-cdk/aws-rds';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* RDS DB Instances are part of AWS Backup plan(s)
@@ -14,7 +17,7 @@ import { resolveResourceFromInstrinsic } from '../../nag-pack';
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBInstance) {
const dbLogicalId = resolveResourceFromInstrinsic(node, node.ref);
let found = false;
@@ -27,10 +30,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/RDSInstanceBackupEnabled.ts b/src/rules/rds/RDSInstanceBackupEnabled.ts
index 511bf0c504..1d69588ff3 100644
--- a/src/rules/rds/RDSInstanceBackupEnabled.ts
+++ b/src/rules/rds/RDSInstanceBackupEnabled.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBInstance } from '@aws-cdk/aws-rds';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* RDS DB instances have backup enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBInstance) {
const backup = resolveIfPrimitive(node, node.backupRetentionPeriod);
if (backup !== undefined && backup <= 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/RDSInstanceDeletionProtectionEnabled.ts b/src/rules/rds/RDSInstanceDeletionProtectionEnabled.ts
index b90ecb2f79..63fda244be 100644
--- a/src/rules/rds/RDSInstanceDeletionProtectionEnabled.ts
+++ b/src/rules/rds/RDSInstanceDeletionProtectionEnabled.ts
@@ -5,26 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster, CfnDBInstance } from '@aws-cdk/aws-rds';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* RDS DB instances and Aurora DB clusters have Deletion Protection enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
if (node.deletionProtection == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const deletionProtection = resolveIfPrimitive(
node,
node.deletionProtection
);
if (deletionProtection == false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
- return true;
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnDBInstance) {
const deletionProtection = resolveIfPrimitive(
node,
@@ -35,11 +35,12 @@ export default Object.defineProperty(
(deletionProtection == false || deletionProtection == undefined) &&
(engine == undefined || !engine.toLowerCase().includes('aurora'))
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
- return true;
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/RDSInstancePublicAccess.ts b/src/rules/rds/RDSInstancePublicAccess.ts
index a0c8764ee1..f66bbceccf 100644
--- a/src/rules/rds/RDSInstancePublicAccess.ts
+++ b/src/rules/rds/RDSInstancePublicAccess.ts
@@ -5,22 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBInstance } from '@aws-cdk/aws-rds';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* RDS DB instances are not publicly accessible
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBInstance) {
const publicAccess = resolveIfPrimitive(node, node.publiclyAccessible);
if (publicAccess !== false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
- return true;
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/RDSLoggingEnabled.ts b/src/rules/rds/RDSLoggingEnabled.ts
index 14d6a14d46..d216762290 100644
--- a/src/rules/rds/RDSLoggingEnabled.ts
+++ b/src/rules/rds/RDSLoggingEnabled.ts
@@ -5,21 +5,21 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBInstance } from '@aws-cdk/aws-rds';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* RDS DB instances are configured to export all possible log types to CloudWatch
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBInstance) {
const dbType = JSON.stringify(resolveIfPrimitive(node, node.engine));
const dbLogs = JSON.stringify(
Stack.of(node).resolve(node.enableCloudwatchLogsExports)
);
if (dbLogs == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
if (dbType.includes('mariadb') || dbType.includes('mysql')) {
@@ -31,12 +31,12 @@ export default Object.defineProperty(
dbLogs.includes('slowquery')
)
)
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
if (dbType.includes('postgres')) {
if (!(dbLogs.includes('postgresql') && dbLogs.includes('upgrade')))
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
if (dbType.includes('oracle')) {
@@ -49,15 +49,17 @@ export default Object.defineProperty(
dbLogs.includes('trace')
)
)
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
if (dbType.includes('sqlserver')) {
if (!(dbLogs.includes('agent') && dbLogs.includes('error')))
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/RDSMultiAZSupport.ts b/src/rules/rds/RDSMultiAZSupport.ts
index a4e5c0ad0d..9cbe1783e5 100644
--- a/src/rules/rds/RDSMultiAZSupport.ts
+++ b/src/rules/rds/RDSMultiAZSupport.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBInstance } from '@aws-cdk/aws-rds';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Non-Aurora RDS DB instances have multi-AZ support enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBInstance) {
const multiAz = resolveIfPrimitive(node, node.multiAz);
const engine = resolveIfPrimitive(node, node.engine);
@@ -20,10 +20,12 @@ export default Object.defineProperty(
!multiAz &&
(engine == undefined || !engine.toLowerCase().includes('aurora'))
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/RDSNonDefaultPort.ts b/src/rules/rds/RDSNonDefaultPort.ts
index 909f86e044..9e71140f40 100644
--- a/src/rules/rds/RDSNonDefaultPort.ts
+++ b/src/rules/rds/RDSNonDefaultPort.ts
@@ -5,17 +5,17 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster, CfnDBInstance } from '@aws-cdk/aws-rds';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* RDS DB instances and Aurora DB clusters do not use the default endpoint ports
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
if (node.port == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const port = resolveIfPrimitive(node, node.port);
const engine = resolveIfPrimitive(node, node.engine).toLowerCase();
@@ -25,41 +25,42 @@ export default Object.defineProperty(
engineMode.toLowerCase() == 'provisioned'
) {
if (engine.includes('aurora') && port == 3306) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
} else if (
(engine == 'aurora' || engine == 'aurora-mysql') &&
port == 3306
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
} else if (engine == 'aurora-postgresql' && port == 5432) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
- return true;
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnDBInstance) {
if (node.engine == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const port = resolveIfPrimitive(node, node.port);
const engine = resolveIfPrimitive(node, node.engine).toLowerCase();
if (port == undefined) {
if (!engine.includes('aurora')) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
} else {
if ((engine == 'mariadb' || engine == 'mysql') && port == 3306) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
} else if (engine == 'postgres' && port == 5432) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
} else if (engine.includes('oracle') && port == 1521) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
} else if (engine.includes('sqlserver') && port == 1433) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
- return true;
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/rds/RDSStorageEncrypted.ts b/src/rules/rds/RDSStorageEncrypted.ts
index 5f44653267..6088dd2da5 100644
--- a/src/rules/rds/RDSStorageEncrypted.ts
+++ b/src/rules/rds/RDSStorageEncrypted.ts
@@ -5,22 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDBCluster, CfnDBInstance } from '@aws-cdk/aws-rds';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* RDS DB instances and Aurora DB clusters have storage encryption enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDBCluster) {
if (node.storageEncrypted == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const encrypted = resolveIfPrimitive(node, node.storageEncrypted);
if (encrypted == false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
} else if (node instanceof CfnDBInstance) {
const encrypted = resolveIfPrimitive(node, node.storageEncrypted);
if (
@@ -28,10 +29,12 @@ export default Object.defineProperty(
(node.engine == undefined ||
!node.engine.toLowerCase().includes('aurora'))
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftBackupEnabled.ts b/src/rules/redshift/RedshiftBackupEnabled.ts
index 797260cc97..bfd71294f1 100644
--- a/src/rules/redshift/RedshiftBackupEnabled.ts
+++ b/src/rules/redshift/RedshiftBackupEnabled.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-redshift';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Redshift clusters have automated snapshots enabled and the retention period is between 1 and 35 days
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const automatedSnapshotRetentionPeriod = resolveIfPrimitive(
node,
@@ -22,10 +22,12 @@ export default Object.defineProperty(
automatedSnapshotRetentionPeriod != undefined &&
automatedSnapshotRetentionPeriod == 0
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftClusterAuditLogging.ts b/src/rules/redshift/RedshiftClusterAuditLogging.ts
index 6fae297e75..a76d015c8b 100644
--- a/src/rules/redshift/RedshiftClusterAuditLogging.ts
+++ b/src/rules/redshift/RedshiftClusterAuditLogging.ts
@@ -5,20 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-redshift';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Redshift clusters have audit logging enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const loggingProperties = Stack.of(node).resolve(node.loggingProperties);
if (loggingProperties == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftClusterConfiguration.ts b/src/rules/redshift/RedshiftClusterConfiguration.ts
index 71a0bfdf39..807cff4ca9 100644
--- a/src/rules/redshift/RedshiftClusterConfiguration.ts
+++ b/src/rules/redshift/RedshiftClusterConfiguration.ts
@@ -5,22 +5,24 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-redshift';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Redshift clusters have encryption and audit logging enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const encrypted = resolveIfPrimitive(node, node.encrypted);
const loggingProperties = Stack.of(node).resolve(node.loggingProperties);
if (!encrypted || loggingProperties == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftClusterEncryptionAtRest.ts b/src/rules/redshift/RedshiftClusterEncryptionAtRest.ts
index 5afa18429d..28fe7275a2 100644
--- a/src/rules/redshift/RedshiftClusterEncryptionAtRest.ts
+++ b/src/rules/redshift/RedshiftClusterEncryptionAtRest.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-redshift';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Redshift clusters have encryption at rest enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
if (node.encrypted == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const encrypted = resolveIfPrimitive(node, node.encrypted);
if (!encrypted) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftClusterInVPC.ts b/src/rules/redshift/RedshiftClusterInVPC.ts
index 3ef4712698..ae91770449 100644
--- a/src/rules/redshift/RedshiftClusterInVPC.ts
+++ b/src/rules/redshift/RedshiftClusterInVPC.ts
@@ -5,22 +5,25 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-redshift';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Redshift clusters are provisioned in a VPC
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
if (
node.clusterSubnetGroupName == undefined ||
node.clusterSubnetGroupName.length == 0
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftClusterMaintenanceSettings.ts b/src/rules/redshift/RedshiftClusterMaintenanceSettings.ts
index e7daeb5a3b..e6b8689543 100644
--- a/src/rules/redshift/RedshiftClusterMaintenanceSettings.ts
+++ b/src/rules/redshift/RedshiftClusterMaintenanceSettings.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-redshift';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Redshift clusters have version upgrades enabled, automated snapshot retention periods enabled, and explicit maintenance windows configured
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const allowVersionUpgrade = resolveIfPrimitive(
node,
@@ -28,10 +28,12 @@ export default Object.defineProperty(
node.preferredMaintenanceWindow == undefined ||
allowVersionUpgrade === false
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftClusterNonDefaultPort.ts b/src/rules/redshift/RedshiftClusterNonDefaultPort.ts
index 33389b2975..1d7a584215 100644
--- a/src/rules/redshift/RedshiftClusterNonDefaultPort.ts
+++ b/src/rules/redshift/RedshiftClusterNonDefaultPort.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-redshift';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Redshift clusters do not use the default endpoint port
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const port = resolveIfPrimitive(node, node.port);
if (port == undefined || port == 5439) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftClusterNonDefaultUsername.ts b/src/rules/redshift/RedshiftClusterNonDefaultUsername.ts
index 0f09832e44..ed5b6e8eb7 100644
--- a/src/rules/redshift/RedshiftClusterNonDefaultUsername.ts
+++ b/src/rules/redshift/RedshiftClusterNonDefaultUsername.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-redshift';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Redshift clusters use custom user names vice the default (awsuser)
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const masterUsername = resolveIfPrimitive(node, node.masterUsername);
if (masterUsername == 'awsuser') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftClusterPublicAccess.ts b/src/rules/redshift/RedshiftClusterPublicAccess.ts
index 92301899d4..705a5eac37 100644
--- a/src/rules/redshift/RedshiftClusterPublicAccess.ts
+++ b/src/rules/redshift/RedshiftClusterPublicAccess.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-redshift';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Redshift clusters do not allow public access
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const publicAccess = resolveIfPrimitive(node, node.publiclyAccessible);
if (publicAccess === true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftClusterUserActivityLogging.ts b/src/rules/redshift/RedshiftClusterUserActivityLogging.ts
index 5c66ef604c..5b3da7c93d 100644
--- a/src/rules/redshift/RedshiftClusterUserActivityLogging.ts
+++ b/src/rules/redshift/RedshiftClusterUserActivityLogging.ts
@@ -5,21 +5,24 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster, CfnClusterParameterGroup } from '@aws-cdk/aws-redshift';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* Redshift clusters have user user activity logging enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const clusterParameterGroupName = resolveResourceFromInstrinsic(
node,
node.clusterParameterGroupName
);
if (clusterParameterGroupName === undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
let found = false;
for (const child of Stack.of(node).node.findAll()) {
@@ -35,10 +38,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftClusterVersionUpgrade.ts b/src/rules/redshift/RedshiftClusterVersionUpgrade.ts
index 4166e6033e..99377b0188 100644
--- a/src/rules/redshift/RedshiftClusterVersionUpgrade.ts
+++ b/src/rules/redshift/RedshiftClusterVersionUpgrade.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-redshift';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Redshift clusters have version upgrade enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const allowVersionUpgrade = resolveIfPrimitive(
node,
node.allowVersionUpgrade
);
if (allowVersionUpgrade === false) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftEnhancedVPCRoutingEnabled.ts b/src/rules/redshift/RedshiftEnhancedVPCRoutingEnabled.ts
index 0852932cfc..6613310eb0 100644
--- a/src/rules/redshift/RedshiftEnhancedVPCRoutingEnabled.ts
+++ b/src/rules/redshift/RedshiftEnhancedVPCRoutingEnabled.ts
@@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster } from '@aws-cdk/aws-redshift';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Redshift clusters have enhanced VPC routing enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const enhancedVpcRouting = resolveIfPrimitive(
node,
node.enhancedVpcRouting
);
if (enhancedVpcRouting !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/redshift/RedshiftRequireTlsSSL.ts b/src/rules/redshift/RedshiftRequireTlsSSL.ts
index d54fb33081..a8bcbbb164 100644
--- a/src/rules/redshift/RedshiftRequireTlsSSL.ts
+++ b/src/rules/redshift/RedshiftRequireTlsSSL.ts
@@ -5,7 +5,10 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnCluster, CfnClusterParameterGroup } from '@aws-cdk/aws-redshift';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* Redshift clusters require TLS/SSL encryption
@@ -13,14 +16,14 @@ import { resolveResourceFromInstrinsic } from '../../nag-pack';
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnCluster) {
const clusterParameterGroupName = resolveResourceFromInstrinsic(
node,
node.clusterParameterGroupName
);
if (clusterParameterGroupName === undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
let found = false;
for (const child of Stack.of(node).node.findAll()) {
@@ -32,10 +35,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/s3/S3BucketDefaultLockEnabled.ts b/src/rules/s3/S3BucketDefaultLockEnabled.ts
index dbb5e4316b..a59f0dc6ec 100644
--- a/src/rules/s3/S3BucketDefaultLockEnabled.ts
+++ b/src/rules/s3/S3BucketDefaultLockEnabled.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnBucket } from '@aws-cdk/aws-s3';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* S3 Buckets have object lock enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnBucket) {
const objectLockEnabled = resolveIfPrimitive(
node,
@@ -27,10 +27,12 @@ export default Object.defineProperty(
resolveIfPrimitive(node, objectLockConfiguration.objectLockEnabled) !==
'Enabled'
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/s3/S3BucketLevelPublicAccessProhibited.ts b/src/rules/s3/S3BucketLevelPublicAccessProhibited.ts
index c6c20ff1d2..215aafb31b 100644
--- a/src/rules/s3/S3BucketLevelPublicAccessProhibited.ts
+++ b/src/rules/s3/S3BucketLevelPublicAccessProhibited.ts
@@ -5,17 +5,17 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnBucket } from '@aws-cdk/aws-s3';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* S3 Buckets prohibit public access through bucket level settings
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnBucket) {
if (node.publicAccessBlockConfiguration == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const publicAccess = Stack.of(node).resolve(
node.publicAccessBlockConfiguration
@@ -42,10 +42,12 @@ export default Object.defineProperty(
ignorePublicAcls !== true ||
restrictPublicBuckets !== true
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/s3/S3BucketLoggingEnabled.ts b/src/rules/s3/S3BucketLoggingEnabled.ts
index c65191910c..7d4e4faa15 100644
--- a/src/rules/s3/S3BucketLoggingEnabled.ts
+++ b/src/rules/s3/S3BucketLoggingEnabled.ts
@@ -5,13 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnBucket } from '@aws-cdk/aws-s3';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* S3 Buckets have server access logs enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnBucket) {
const logging = Stack.of(node).resolve(node.loggingConfiguration);
if (
@@ -19,10 +20,12 @@ export default Object.defineProperty(
(logging.destinationBucketName == undefined &&
logging.logFilePrefix == undefined)
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/s3/S3BucketPublicReadProhibited.ts b/src/rules/s3/S3BucketPublicReadProhibited.ts
index ab93ad417e..d540c7ca00 100644
--- a/src/rules/s3/S3BucketPublicReadProhibited.ts
+++ b/src/rules/s3/S3BucketPublicReadProhibited.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnBucket } from '@aws-cdk/aws-s3';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* S3 Buckets prohibit public read access through their Block Public Access configurations and bucket ACLs
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnBucket) {
const publicAccessBlockConfiguration = Stack.of(node).resolve(
node.publicAccessBlockConfiguration
@@ -24,7 +24,7 @@ export default Object.defineProperty(
publicAccessBlockConfiguration.blockPublicPolicy
) !== true
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const accessControl = resolveIfPrimitive(node, node.accessControl);
const blockPublicAcls = resolveIfPrimitive(
@@ -36,10 +36,12 @@ export default Object.defineProperty(
accessControl === 'PublicReadWrite') &&
blockPublicAcls !== true
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/s3/S3BucketPublicWriteProhibited.ts b/src/rules/s3/S3BucketPublicWriteProhibited.ts
index efdd54bcff..9a569a9fdd 100644
--- a/src/rules/s3/S3BucketPublicWriteProhibited.ts
+++ b/src/rules/s3/S3BucketPublicWriteProhibited.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnBucket } from '@aws-cdk/aws-s3';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* S3 Buckets prohibit public write access through their Block Public Access configurations and bucket ACLs
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnBucket) {
const publicAccessBlockConfiguration = Stack.of(node).resolve(
node.publicAccessBlockConfiguration
@@ -24,7 +24,7 @@ export default Object.defineProperty(
publicAccessBlockConfiguration.blockPublicPolicy
) !== true
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const accessControl = resolveIfPrimitive(node, node.accessControl);
const blockPublicAcls = resolveIfPrimitive(
@@ -32,10 +32,12 @@ export default Object.defineProperty(
publicAccessBlockConfiguration.blockPublicAcls
);
if (accessControl === 'PublicReadWrite' && blockPublicAcls !== true) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/s3/S3BucketReplicationEnabled.ts b/src/rules/s3/S3BucketReplicationEnabled.ts
index 8cd4dd2219..87b43ae7bb 100644
--- a/src/rules/s3/S3BucketReplicationEnabled.ts
+++ b/src/rules/s3/S3BucketReplicationEnabled.ts
@@ -5,17 +5,18 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnBucket } from '@aws-cdk/aws-s3';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* S3 Buckets have replication enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnBucket) {
const replication = Stack.of(node).resolve(node.replicationConfiguration);
if (replication === undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const rules = Stack.of(node).resolve(replication.rules);
let found = false;
@@ -27,10 +28,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/s3/S3BucketServerSideEncryptionEnabled.ts b/src/rules/s3/S3BucketServerSideEncryptionEnabled.ts
index aaa5665708..455bb1bebc 100644
--- a/src/rules/s3/S3BucketServerSideEncryptionEnabled.ts
+++ b/src/rules/s3/S3BucketServerSideEncryptionEnabled.ts
@@ -5,21 +5,21 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnBucket } from '@aws-cdk/aws-s3';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* S3 Buckets have default server-side encryption enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnBucket) {
if (node.bucketEncryption == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const encryption = Stack.of(node).resolve(node.bucketEncryption);
if (encryption.serverSideEncryptionConfiguration == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const sse = Stack.of(node).resolve(
encryption.serverSideEncryptionConfiguration
@@ -29,7 +29,7 @@ export default Object.defineProperty(
rule.serverSideEncryptionByDefault
);
if (defaultEncryption == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const sseAlgorithm = resolveIfPrimitive(
node,
@@ -39,11 +39,13 @@ export default Object.defineProperty(
sseAlgorithm.toLowerCase() != 'aes256' &&
sseAlgorithm.toLowerCase() != 'aws:kms'
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/s3/S3BucketVersioningEnabled.ts b/src/rules/s3/S3BucketVersioningEnabled.ts
index ef5d977adb..d16b328826 100644
--- a/src/rules/s3/S3BucketVersioningEnabled.ts
+++ b/src/rules/s3/S3BucketVersioningEnabled.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnBucket } from '@aws-cdk/aws-s3';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* S3 Buckets have versioningConfiguration enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnBucket) {
const versioningConfiguration = Stack.of(node).resolve(
node.versioningConfiguration
@@ -21,10 +21,12 @@ export default Object.defineProperty(
versioningConfiguration === undefined ||
resolveIfPrimitive(node, versioningConfiguration.status) === 'Suspended'
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/s3/S3DefaultEncryptionKMS.ts b/src/rules/s3/S3DefaultEncryptionKMS.ts
index c5fb114f8c..69e40ff356 100644
--- a/src/rules/s3/S3DefaultEncryptionKMS.ts
+++ b/src/rules/s3/S3DefaultEncryptionKMS.ts
@@ -5,21 +5,21 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnBucket } from '@aws-cdk/aws-s3';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* S3 Buckets are encrypted with a KMS Key by default
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnBucket) {
if (node.bucketEncryption == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const encryption = Stack.of(node).resolve(node.bucketEncryption);
if (encryption.serverSideEncryptionConfiguration == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const sse = Stack.of(node).resolve(
encryption.serverSideEncryptionConfiguration
@@ -29,18 +29,20 @@ export default Object.defineProperty(
rule.serverSideEncryptionByDefault
);
if (defaultEncryption == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const sseAlgorithm = resolveIfPrimitive(
node,
defaultEncryption.sseAlgorithm
);
if (sseAlgorithm.toLowerCase() != 'aws:kms') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/sagemaker/SageMakerEndpointConfigurationKMSKeyConfigured.ts b/src/rules/sagemaker/SageMakerEndpointConfigurationKMSKeyConfigured.ts
index 96792ca5be..64fa89235f 100644
--- a/src/rules/sagemaker/SageMakerEndpointConfigurationKMSKeyConfigured.ts
+++ b/src/rules/sagemaker/SageMakerEndpointConfigurationKMSKeyConfigured.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnEndpointConfig } from '@aws-cdk/aws-sagemaker';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* SageMaker endpoints utilize a KMS key
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnEndpointConfig) {
- //Does this endpoint have a KMS key ID?
const kmsKey = Stack.of(node).resolve(node.kmsKeyId);
if (kmsKey == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/sagemaker/SageMakerNotebookInVPC.ts b/src/rules/sagemaker/SageMakerNotebookInVPC.ts
index 77c068d2a6..1d74929248 100644
--- a/src/rules/sagemaker/SageMakerNotebookInVPC.ts
+++ b/src/rules/sagemaker/SageMakerNotebookInVPC.ts
@@ -5,20 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnNotebookInstance } from '@aws-cdk/aws-sagemaker';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* SageMaker notebook instances are provisioned inside a VPC
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnNotebookInstance) {
const subnetId = Stack.of(node).resolve(node.subnetId);
if (subnetId == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/sagemaker/SageMakerNotebookInstanceKMSKeyConfigured.ts b/src/rules/sagemaker/SageMakerNotebookInstanceKMSKeyConfigured.ts
index c9dc85e300..5bc2608881 100644
--- a/src/rules/sagemaker/SageMakerNotebookInstanceKMSKeyConfigured.ts
+++ b/src/rules/sagemaker/SageMakerNotebookInstanceKMSKeyConfigured.ts
@@ -5,20 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnNotebookInstance } from '@aws-cdk/aws-sagemaker';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* SageMaker notebook instances utilize KMS keys for encryption at rest
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnNotebookInstance) {
const kmsKey = Stack.of(node).resolve(node.kmsKeyId);
if (kmsKey == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/sagemaker/SageMakerNotebookNoDirectInternetAccess.ts b/src/rules/sagemaker/SageMakerNotebookNoDirectInternetAccess.ts
index 2a0dcab355..99b2e8655e 100644
--- a/src/rules/sagemaker/SageMakerNotebookNoDirectInternetAccess.ts
+++ b/src/rules/sagemaker/SageMakerNotebookNoDirectInternetAccess.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnNotebookInstance } from '@aws-cdk/aws-sagemaker';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* SageMaker notebook instances have direct internet access disabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnNotebookInstance) {
const directInternetAccess = resolveIfPrimitive(
node,
@@ -22,10 +22,12 @@ export default Object.defineProperty(
directInternetAccess == undefined ||
directInternetAccess != 'Disabled'
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/secretsmanager/SecretsManagerRotationEnabled.ts b/src/rules/secretsmanager/SecretsManagerRotationEnabled.ts
index 7456b8fcce..de335dfcc6 100644
--- a/src/rules/secretsmanager/SecretsManagerRotationEnabled.ts
+++ b/src/rules/secretsmanager/SecretsManagerRotationEnabled.ts
@@ -9,14 +9,17 @@ import {
CfnSecretTargetAttachment,
} from '@aws-cdk/aws-secretsmanager';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* Secrets have automatic rotation scheduled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnSecret) {
const secretLogicalId = resolveResourceFromInstrinsic(node, node.ref);
const secretTargetAttachmentLogicalIds = Array();
@@ -30,7 +33,7 @@ export default Object.defineProperty(
}
}
if (cfnRotationSchedules.length === 0) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
let found = false;
for (const child of cfnSecretTargetAttachments) {
@@ -55,10 +58,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/secretsmanager/SecretsManagerUsingKMSKey.ts b/src/rules/secretsmanager/SecretsManagerUsingKMSKey.ts
index 2fdc6f8208..8ea2bd7395 100644
--- a/src/rules/secretsmanager/SecretsManagerUsingKMSKey.ts
+++ b/src/rules/secretsmanager/SecretsManagerUsingKMSKey.ts
@@ -5,21 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnSecret } from '@aws-cdk/aws-secretsmanager';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Secrets are encrypted with KMS Customer managed keys
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnSecret) {
const kmsKeyId = resolveIfPrimitive(node, node.kmsKeyId);
if (kmsKeyId === undefined || kmsKeyId === 'aws/secretsmanager') {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/sns/SNSEncryptedKMS.ts b/src/rules/sns/SNSEncryptedKMS.ts
index c2c04f9e0f..0f5fd2e726 100644
--- a/src/rules/sns/SNSEncryptedKMS.ts
+++ b/src/rules/sns/SNSEncryptedKMS.ts
@@ -5,20 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnTopic } from '@aws-cdk/aws-sns';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* SNS topics are encrypted via KMS
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnTopic) {
const topicKey = Stack.of(node).resolve(node.kmsMasterKeyId);
if (topicKey == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/sqs/SQSQueueDLQ.ts b/src/rules/sqs/SQSQueueDLQ.ts
index 06b7ab91c9..a64785c15d 100644
--- a/src/rules/sqs/SQSQueueDLQ.ts
+++ b/src/rules/sqs/SQSQueueDLQ.ts
@@ -5,20 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnQueue } from '@aws-cdk/aws-sqs';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* SQS queues have a dead-letter queue enabled or have a cdk_nag rule suppression indicating they are a dead-letter queue.
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnQueue) {
const redrivePolicy = Stack.of(node).resolve(node.redrivePolicy);
if (redrivePolicy == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/sqs/SQSQueueSSE.ts b/src/rules/sqs/SQSQueueSSE.ts
index eee74ef301..295cd1fbd3 100644
--- a/src/rules/sqs/SQSQueueSSE.ts
+++ b/src/rules/sqs/SQSQueueSSE.ts
@@ -5,20 +5,23 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnQueue } from '@aws-cdk/aws-sqs';
import { CfnResource, Stack } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* SQS queues have server-side encryption enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnQueue) {
const kmsMasterKeyId = Stack.of(node).resolve(node.kmsMasterKeyId);
if (kmsMasterKeyId == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/stepfunctions/StepFunctionStateMachineAllLogsToCloudWatch.ts b/src/rules/stepfunctions/StepFunctionStateMachineAllLogsToCloudWatch.ts
index 0548156f7c..c45291e1a2 100644
--- a/src/rules/stepfunctions/StepFunctionStateMachineAllLogsToCloudWatch.ts
+++ b/src/rules/stepfunctions/StepFunctionStateMachineAllLogsToCloudWatch.ts
@@ -5,27 +5,29 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnStateMachine, LogLevel } from '@aws-cdk/aws-stepfunctions';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Step Function log "ALL" events to CloudWatch Logs
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnStateMachine) {
const loggingConfiguration = Stack.of(node).resolve(
node.loggingConfiguration
);
if (loggingConfiguration == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const level = resolveIfPrimitive(node, loggingConfiguration.level);
if (level == undefined || level != LogLevel.ALL) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/stepfunctions/StepFunctionStateMachineXray.ts b/src/rules/stepfunctions/StepFunctionStateMachineXray.ts
index 97ce9904e6..3f14610511 100644
--- a/src/rules/stepfunctions/StepFunctionStateMachineXray.ts
+++ b/src/rules/stepfunctions/StepFunctionStateMachineXray.ts
@@ -5,27 +5,29 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnStateMachine } from '@aws-cdk/aws-stepfunctions';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Step Function have X-Ray tracing enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnStateMachine) {
const tracingConfiguration = Stack.of(node).resolve(
node.tracingConfiguration
);
if (tracingConfiguration == undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
const enabled = resolveIfPrimitive(node, tracingConfiguration.enabled);
if (!enabled) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/timestream/TimestreamDatabaseCustomerManagedKey.ts b/src/rules/timestream/TimestreamDatabaseCustomerManagedKey.ts
index 03a169b867..2b09503fe7 100644
--- a/src/rules/timestream/TimestreamDatabaseCustomerManagedKey.ts
+++ b/src/rules/timestream/TimestreamDatabaseCustomerManagedKey.ts
@@ -5,19 +5,22 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnDatabase } from '@aws-cdk/aws-timestream';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* Timestream databases use Customer Managed KMS Keys
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnDatabase) {
if (node.kmsKeyId === undefined) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/vpc/VPCDefaultSecurityGroupClosed.ts b/src/rules/vpc/VPCDefaultSecurityGroupClosed.ts
index ba5543f8bd..7d41bd8be6 100644
--- a/src/rules/vpc/VPCDefaultSecurityGroupClosed.ts
+++ b/src/rules/vpc/VPCDefaultSecurityGroupClosed.ts
@@ -5,6 +5,7 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnVPC } from '@aws-cdk/aws-ec2';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* VPCs have their default security group closed
@@ -13,11 +14,12 @@ import { CfnResource } from '@aws-cdk/core';
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnVPC) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/vpc/VPCFlowLogsEnabled.ts b/src/rules/vpc/VPCFlowLogsEnabled.ts
index 7718afa4aa..e674661e71 100644
--- a/src/rules/vpc/VPCFlowLogsEnabled.ts
+++ b/src/rules/vpc/VPCFlowLogsEnabled.ts
@@ -5,14 +5,17 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnVPC, CfnFlowLog } from '@aws-cdk/aws-ec2';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* VPCs have Flow Logs enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnVPC) {
const vpcLogicalId = resolveResourceFromInstrinsic(node, node.ref);
let found = false;
@@ -25,10 +28,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/vpc/VPCNoNACLs.ts b/src/rules/vpc/VPCNoNACLs.ts
index d46de96e61..4ab22c793e 100644
--- a/src/rules/vpc/VPCNoNACLs.ts
+++ b/src/rules/vpc/VPCNoNACLs.ts
@@ -5,17 +5,19 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnNetworkAcl, CfnNetworkAclEntry } from '@aws-cdk/aws-ec2';
import { CfnResource } from '@aws-cdk/core';
+import { NagRuleCompliance } from '../../nag-pack';
/**
* VPCs do not implement network ACLs
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnNetworkAcl || node instanceof CfnNetworkAclEntry) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/vpc/VPCNoUnrestrictedRouteToIGW.ts b/src/rules/vpc/VPCNoUnrestrictedRouteToIGW.ts
index 9b0ba3fe03..6d58b5423e 100644
--- a/src/rules/vpc/VPCNoUnrestrictedRouteToIGW.ts
+++ b/src/rules/vpc/VPCNoUnrestrictedRouteToIGW.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnRoute } from '@aws-cdk/aws-ec2';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Route tables do not have unrestricted routes ('0.0.0.0/0' or '::/0') to IGWs
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnRoute) {
if (node.gatewayId != undefined) {
const destinationCidrBlock = resolveIfPrimitive(
@@ -27,17 +27,19 @@ export default Object.defineProperty(
destinationCidrBlock != undefined &&
destinationCidrBlock.includes('/0')
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
if (
destinationIpv6CidrBlock != undefined &&
destinationIpv6CidrBlock.includes('/0')
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/vpc/VPCSubnetAutoAssignPublicIpDisabled.ts b/src/rules/vpc/VPCSubnetAutoAssignPublicIpDisabled.ts
index a72cf7cbb9..1589116146 100644
--- a/src/rules/vpc/VPCSubnetAutoAssignPublicIpDisabled.ts
+++ b/src/rules/vpc/VPCSubnetAutoAssignPublicIpDisabled.ts
@@ -5,14 +5,14 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnSubnet } from '@aws-cdk/aws-ec2';
import { CfnResource } from '@aws-cdk/core';
-import { resolveIfPrimitive } from '../../nag-pack';
+import { resolveIfPrimitive, NagRuleCompliance } from '../../nag-pack';
/**
* Subnets do not auto-assign public IP addresses
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnSubnet) {
const mapPublicIpOnLaunch = resolveIfPrimitive(
node,
@@ -26,10 +26,12 @@ export default Object.defineProperty(
mapPublicIpOnLaunch === true ||
assignIpv6AddressOnCreation === true
) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/src/rules/waf/WAFv2LoggingEnabled.ts b/src/rules/waf/WAFv2LoggingEnabled.ts
index 53dc7b0ca5..f879ede52a 100644
--- a/src/rules/waf/WAFv2LoggingEnabled.ts
+++ b/src/rules/waf/WAFv2LoggingEnabled.ts
@@ -5,14 +5,17 @@ SPDX-License-Identifier: Apache-2.0
import { parse } from 'path';
import { CfnWebACL, CfnLoggingConfiguration } from '@aws-cdk/aws-wafv2';
import { CfnResource, Stack } from '@aws-cdk/core';
-import { resolveResourceFromInstrinsic } from '../../nag-pack';
+import {
+ resolveResourceFromInstrinsic,
+ NagRuleCompliance,
+} from '../../nag-pack';
/**
* WAFv2 web ACLs have logging enabled
* @param node the CfnResource to check
*/
export default Object.defineProperty(
- (node: CfnResource): boolean => {
+ (node: CfnResource): NagRuleCompliance => {
if (node instanceof CfnWebACL) {
const webAclLogicalId = resolveResourceFromInstrinsic(node, node.ref);
const webAclName = Stack.of(node).resolve(node.name);
@@ -28,10 +31,12 @@ export default Object.defineProperty(
}
}
if (!found) {
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
}
+ return NagRuleCompliance.COMPLIANT;
+ } else {
+ return NagRuleCompliance.NOT_APPLICABLE;
}
- return true;
},
'name',
{ value: parse(__filename).name }
diff --git a/test/Engine.test.ts b/test/Engine.test.ts
index 224cdca98c..317ad49555 100644
--- a/test/Engine.test.ts
+++ b/test/Engine.test.ts
@@ -13,8 +13,9 @@ import {
Vpc,
} from '@aws-cdk/aws-ec2';
import { PolicyStatement, User } from '@aws-cdk/aws-iam';
-import { CfnBucket } from '@aws-cdk/aws-s3';
+import { Bucket, CfnBucket } from '@aws-cdk/aws-s3';
import {
+ App,
Aspects,
CfnParameter,
CfnResource,
@@ -29,9 +30,11 @@ import {
NagPack,
resolveIfPrimitive,
NagPackProps,
+ NagRuleCompliance,
+ IApplyRule,
} from '../src';
-describe('Testing rule suppression system', () => {
+describe('Rule suppression system', () => {
test('Test single rule suppression', () => {
const stack = new Stack();
Aspects.of(stack).add(new AwsSolutionsChecks());
@@ -468,7 +471,7 @@ describe('Testing rule suppression system', () => {
});
});
-describe('Testing rule explanations', () => {
+describe('Rule explanations', () => {
test('Test no explicit explanation', () => {
const stack = new Stack();
Aspects.of(stack).add(new AwsSolutionsChecks());
@@ -519,7 +522,7 @@ describe('Testing rule explanations', () => {
});
});
-describe('Testing rule exception handling', () => {
+describe('Rule exception handling', () => {
const ERROR_MESSAGE = 'oops!';
class BadPack extends NagPack {
constructor(props?: NagPackProps) {
@@ -533,11 +536,11 @@ describe('Testing rule exception handling', () => {
info: 'This is a imporperly made rule.',
explanation: 'This will throw an error',
level: NagMessageLevel.ERROR,
- rule: function (node2: CfnResource): boolean {
+ rule: function (node2: CfnResource): NagRuleCompliance {
if (node2) {
throw Error(ERROR_MESSAGE);
}
- return false;
+ return NagRuleCompliance.NON_COMPLIANT;
},
node: node,
});
@@ -623,3 +626,135 @@ describe('Testing rule exception handling', () => {
}).not.toThrowError();
});
});
+
+describe('Report system', () => {
+ class TestPack extends NagPack {
+ lines = new Array();
+ constructor(props?: NagPackProps) {
+ super(props);
+ this.packName = 'Test';
+ }
+ public visit(node: IConstruct): void {
+ if (node instanceof CfnResource) {
+ const compliances = [
+ NagRuleCompliance.NON_COMPLIANT,
+ NagRuleCompliance.COMPLIANT,
+ NagRuleCompliance.NOT_APPLICABLE,
+ ];
+ compliances.forEach((compliance) => {
+ this.applyRule({
+ ruleSuffixOverride: compliance,
+ info: 'foo.',
+ explanation: 'bar.',
+ level: NagMessageLevel.ERROR,
+ rule: function (node2: CfnResource): NagRuleCompliance {
+ if (node2.cfnResourceType !== 'Error') {
+ return compliance;
+ }
+ throw Error('foobar');
+ },
+ node: node,
+ });
+ });
+ }
+ }
+
+ protected writeToStackComplianceReport(
+ params: IApplyRule,
+ ruleId: string,
+ compliance: NagRuleCompliance.COMPLIANT | NagRuleCompliance.NON_COMPLIANT,
+ explanation: string = ''
+ ): void {
+ this.lines.push(
+ this.createComplianceReportLine(params, ruleId, compliance, explanation)
+ );
+ const fileName = `${this.packName}-${params.node.stack.stackName}-NagReport.csv`;
+ if (!this.reportStacks.includes(fileName)) {
+ this.reportStacks.push(fileName);
+ }
+ }
+ }
+
+ test('Reports are generated for all stacks by default', () => {
+ const app = new App();
+ const stack = new Stack(app, 'Stack1');
+ const stack2 = new Stack(app, 'Stack2');
+ const pack = new TestPack();
+ Aspects.of(app).add(pack);
+ new SecurityGroup(stack, 'rSg', {
+ vpc: new Vpc(stack, 'rVpc'),
+ });
+ new Bucket(stack2, 'rBucket');
+ app.synth();
+ expect(pack.readReportStacks.length).toEqual(2);
+ });
+ test('Compliant and Non-Compliant values are written properly', () => {
+ const app = new App();
+ const stack = new Stack(app, 'Stack1');
+ const pack = new TestPack();
+ Aspects.of(app).add(pack);
+ new CfnResource(stack, 'rResource', { type: 'foo' });
+ app.synth();
+ const expectedOuput = [
+ '"Test-Compliant","Stack1/rResource","Compliant","N/A","Error","foo."\n',
+ '"Test-Non-Compliant","Stack1/rResource","Non-Compliant","N/A","Error","foo."\n',
+ ];
+ expect(pack.lines.sort()).toEqual(expectedOuput.sort());
+ });
+ test('Suppression values are written properly', () => {
+ const app = new App();
+ const stack = new Stack(app, 'Stack1');
+ const pack = new TestPack();
+ Aspects.of(app).add(pack);
+ const resource = new CfnResource(stack, 'rResource', { type: 'foo' });
+ NagSuppressions.addResourceSuppressions(resource, [
+ {
+ id: `${pack.readPackName}-${NagRuleCompliance.NON_COMPLIANT}`,
+ reason: 'lorem ipsum',
+ },
+ ]);
+ app.synth();
+ const expectedOuput = [
+ '"Test-Compliant","Stack1/rResource","Compliant","N/A","Error","foo."\n',
+ '"Test-Non-Compliant","Stack1/rResource","Suppressed","lorem ipsum","Error","foo."\n',
+ ];
+ expect(pack.lines.sort()).toEqual(expectedOuput.sort());
+ });
+ test('Error values are written properly', () => {
+ const app = new App();
+ const stack = new Stack(app, 'Stack1');
+ const pack = new TestPack();
+ Aspects.of(app).add(pack);
+ const resource = new CfnResource(stack, 'rResource', { type: 'Error' });
+ NagSuppressions.addResourceSuppressions(resource, [
+ {
+ id: `${pack.readPackName}-${NagRuleCompliance.NON_COMPLIANT}`,
+ reason: 'lorem ipsum',
+ },
+ ]);
+ app.synth();
+ const expectedOuput = [
+ '"Test-Non-Compliant","Stack1/rResource","UNKNOWN","N/A","Error","foo."\n',
+ '"Test-Compliant","Stack1/rResource","UNKNOWN","N/A","Error","foo."\n',
+ '"Test-N/A","Stack1/rResource","UNKNOWN","N/A","Error","foo."\n',
+ ];
+ expect(pack.lines.sort()).toEqual(expectedOuput.sort());
+ });
+ test('Suppressed error values are escaped and written properly', () => {
+ const app = new App();
+ const stack = new Stack(app, 'Stack1');
+ const pack = new TestPack();
+ Aspects.of(app).add(pack);
+ const resource = new CfnResource(stack, 'rResource', { type: 'Error' });
+ NagSuppressions.addResourceSuppressions(resource, [
+ { id: 'CdkNagValidationFailure', reason: '"quoted "lorem" ipsum"' },
+ ]);
+ app.synth();
+ const expectedOuput = [
+ '"Test-Compliant","Stack1/rResource","Suppressed","""quoted ""lorem"" ipsum""","Error","foo."\n',
+ '"Test-N/A","Stack1/rResource","Suppressed","""quoted ""lorem"" ipsum""","Error","foo."\n',
+ '"Test-Non-Compliant","Stack1/rResource","Suppressed","""quoted ""lorem"" ipsum""","Error","foo."\n',
+ ];
+ expect(pack.lines.sort()).toEqual(expectedOuput.sort());
+ });
+});
diff --git a/test/Packs.test.ts b/test/Packs.test.ts
index ed6d11dadc..bfe7fcaf6d 100644
--- a/test/Packs.test.ts
+++ b/test/Packs.test.ts
@@ -17,7 +17,22 @@ import {
describe('Check NagPack Details', () => {
describe('AwsSolutions', () => {
- const pack = new AwsSolutionsChecks();
+ class AwsSolutionsChecksExtended extends AwsSolutionsChecks {
+ actualWarnings = new Array();
+ actualErrors = new Array();
+ applyRule(params: IApplyRule): void {
+ const ruleSuffix = params.ruleSuffixOverride
+ ? params.ruleSuffixOverride
+ : params.rule.name;
+ const ruleId = `${pack.readPackName}-${ruleSuffix}`;
+ if (params.level === NagMessageLevel.WARN) {
+ this.actualWarnings.push(ruleId);
+ } else {
+ this.actualErrors.push(ruleId);
+ }
+ }
+ }
+ const pack = new AwsSolutionsChecksExtended();
test('Pack Name is correct', () => {
expect(pack.readPackName).toStrictEqual('AwsSolutions');
});
@@ -143,30 +158,32 @@ describe('Check NagPack Details', () => {
'AwsSolutions-SQS3',
'AwsSolutions-VPC7',
];
- const actualWarnings = new Array();
- const actualErrors = new Array();
- jest.spyOn(pack, 'applyRule').mockImplementation((params: IApplyRule) => {
- const ruleSuffix = params.ruleSuffixOverride
- ? params.ruleSuffixOverride
- : params.rule.name;
- const ruleId = `${pack.readPackName}-${ruleSuffix}`;
- if (params.level === NagMessageLevel.WARN) {
- actualWarnings.push(ruleId);
- } else {
- actualErrors.push(ruleId);
- }
- return ruleId;
- });
+ jest.spyOn(pack, 'applyRule');
const stack = new Stack();
Aspects.of(stack).add(pack);
new CfnResource(stack, 'rTestResource', { type: 'foo' });
SynthUtils.synthesize(stack).messages;
- expect(actualWarnings.sort()).toEqual(expectedWarnings.sort());
- expect(actualErrors.sort()).toEqual(expectedErrors.sort());
+ expect(pack.actualWarnings.sort()).toEqual(expectedWarnings.sort());
+ expect(pack.actualErrors.sort()).toEqual(expectedErrors.sort());
});
});
describe('HIPAA-Security', () => {
- const pack = new HIPAASecurityChecks();
+ class HIPAASecurityChecksExtended extends HIPAASecurityChecks {
+ actualWarnings = new Array();
+ actualErrors = new Array();
+ applyRule(params: IApplyRule): void {
+ const ruleSuffix = params.ruleSuffixOverride
+ ? params.ruleSuffixOverride
+ : params.rule.name;
+ const ruleId = `${pack.readPackName}-${ruleSuffix}`;
+ if (params.level === NagMessageLevel.WARN) {
+ this.actualWarnings.push(ruleId);
+ } else {
+ this.actualErrors.push(ruleId);
+ }
+ }
+ }
+ const pack = new HIPAASecurityChecksExtended();
test('Pack Name is correct', () => {
expect(pack.readPackName).toStrictEqual('HIPAA.Security');
});
@@ -261,30 +278,32 @@ describe('Check NagPack Details', () => {
'HIPAA.Security-VPCSubnetAutoAssignPublicIpDisabled',
'HIPAA.Security-WAFv2LoggingEnabled',
];
- const actualWarnings = new Array();
- const actualErrors = new Array();
- jest.spyOn(pack, 'applyRule').mockImplementation((params: IApplyRule) => {
- const ruleSuffix = params.ruleSuffixOverride
- ? params.ruleSuffixOverride
- : params.rule.name;
- const ruleId = `${pack.readPackName}-${ruleSuffix}`;
- if (params.level === NagMessageLevel.WARN) {
- actualWarnings.push(ruleId);
- } else {
- actualErrors.push(ruleId);
- }
- return ruleId;
- });
+ jest.spyOn(pack, 'applyRule');
const stack = new Stack();
Aspects.of(stack).add(pack);
new CfnResource(stack, 'rTestResource', { type: 'foo' });
SynthUtils.synthesize(stack).messages;
- expect(actualWarnings.sort()).toEqual(expectedWarnings.sort());
- expect(actualErrors.sort()).toEqual(expectedErrors.sort());
+ expect(pack.actualWarnings.sort()).toEqual(expectedWarnings.sort());
+ expect(pack.actualErrors.sort()).toEqual(expectedErrors.sort());
});
});
describe('NIST-800-53-R4', () => {
- const pack = new NIST80053R4Checks();
+ class NIST80053R4ChecksExtended extends NIST80053R4Checks {
+ actualWarnings = new Array();
+ actualErrors = new Array();
+ applyRule(params: IApplyRule): void {
+ const ruleSuffix = params.ruleSuffixOverride
+ ? params.ruleSuffixOverride
+ : params.rule.name;
+ const ruleId = `${pack.readPackName}-${ruleSuffix}`;
+ if (params.level === NagMessageLevel.WARN) {
+ this.actualWarnings.push(ruleId);
+ } else {
+ this.actualErrors.push(ruleId);
+ }
+ }
+ }
+ const pack = new NIST80053R4ChecksExtended();
test('Pack Name is correct', () => {
expect(pack.readPackName).toStrictEqual('NIST.800.53.R4');
});
@@ -359,30 +378,32 @@ describe('Check NagPack Details', () => {
'NIST.800.53.R4-VPCFlowLogsEnabled',
'NIST.800.53.R4-WAFv2LoggingEnabled',
];
- const actualWarnings = new Array();
- const actualErrors = new Array();
- jest.spyOn(pack, 'applyRule').mockImplementation((params: IApplyRule) => {
- const ruleSuffix = params.ruleSuffixOverride
- ? params.ruleSuffixOverride
- : params.rule.name;
- const ruleId = `${pack.readPackName}-${ruleSuffix}`;
- if (params.level === NagMessageLevel.WARN) {
- actualWarnings.push(ruleId);
- } else {
- actualErrors.push(ruleId);
- }
- return ruleId;
- });
+ jest.spyOn(pack, 'applyRule');
const stack = new Stack();
Aspects.of(stack).add(pack);
new CfnResource(stack, 'rTestResource', { type: 'foo' });
SynthUtils.synthesize(stack).messages;
- expect(actualWarnings.sort()).toEqual(expectedWarnings.sort());
- expect(actualErrors.sort()).toEqual(expectedErrors.sort());
+ expect(pack.actualWarnings.sort()).toEqual(expectedWarnings.sort());
+ expect(pack.actualErrors.sort()).toEqual(expectedErrors.sort());
});
});
describe('NIST-800-53-R5', () => {
- const pack = new NIST80053R5Checks();
+ class NIST80053R5ChecksExtended extends NIST80053R5Checks {
+ actualWarnings = new Array();
+ actualErrors = new Array();
+ applyRule(params: IApplyRule): void {
+ const ruleSuffix = params.ruleSuffixOverride
+ ? params.ruleSuffixOverride
+ : params.rule.name;
+ const ruleId = `${pack.readPackName}-${ruleSuffix}`;
+ if (params.level === NagMessageLevel.WARN) {
+ this.actualWarnings.push(ruleId);
+ } else {
+ this.actualErrors.push(ruleId);
+ }
+ }
+ }
+ const pack = new NIST80053R5ChecksExtended();
test('Pack Name is correct', () => {
expect(pack.readPackName).toStrictEqual('NIST.800.53.R5');
});
@@ -472,30 +493,32 @@ describe('Check NagPack Details', () => {
'NIST.800.53.R5-VPCSubnetAutoAssignPublicIpDisabled',
'NIST.800.53.R5-WAFv2LoggingEnabled',
];
- const actualWarnings = new Array();
- const actualErrors = new Array();
- jest.spyOn(pack, 'applyRule').mockImplementation((params: IApplyRule) => {
- const ruleSuffix = params.ruleSuffixOverride
- ? params.ruleSuffixOverride
- : params.rule.name;
- const ruleId = `${pack.readPackName}-${ruleSuffix}`;
- if (params.level === NagMessageLevel.WARN) {
- actualWarnings.push(ruleId);
- } else {
- actualErrors.push(ruleId);
- }
- return ruleId;
- });
+ jest.spyOn(pack, 'applyRule');
const stack = new Stack();
Aspects.of(stack).add(pack);
new CfnResource(stack, 'rTestResource', { type: 'foo' });
SynthUtils.synthesize(stack).messages;
- expect(actualWarnings.sort()).toEqual(expectedWarnings.sort());
- expect(actualErrors.sort()).toEqual(expectedErrors.sort());
+ expect(pack.actualWarnings.sort()).toEqual(expectedWarnings.sort());
+ expect(pack.actualErrors.sort()).toEqual(expectedErrors.sort());
});
});
describe('PCI-DSS-3.2.1', () => {
- const pack = new PCIDSS321Checks();
+ class PCIDSS321ChecksExtended extends PCIDSS321Checks {
+ actualWarnings = new Array();
+ actualErrors = new Array();
+ applyRule(params: IApplyRule): void {
+ const ruleSuffix = params.ruleSuffixOverride
+ ? params.ruleSuffixOverride
+ : params.rule.name;
+ const ruleId = `${pack.readPackName}-${ruleSuffix}`;
+ if (params.level === NagMessageLevel.WARN) {
+ this.actualWarnings.push(ruleId);
+ } else {
+ this.actualErrors.push(ruleId);
+ }
+ }
+ }
+ const pack = new PCIDSS321ChecksExtended();
test('Pack Name is correct', () => {
expect(pack.readPackName).toStrictEqual('PCI.DSS.321');
});
@@ -570,26 +593,13 @@ describe('Check NagPack Details', () => {
'PCI.DSS.321-VPCSubnetAutoAssignPublicIpDisabled',
'PCI.DSS.321-WAFv2LoggingEnabled',
];
- const actualWarnings = new Array();
- const actualErrors = new Array();
- jest.spyOn(pack, 'applyRule').mockImplementation((params: IApplyRule) => {
- const ruleSuffix = params.ruleSuffixOverride
- ? params.ruleSuffixOverride
- : params.rule.name;
- const ruleId = `${pack.readPackName}-${ruleSuffix}`;
- if (params.level === NagMessageLevel.WARN) {
- actualWarnings.push(ruleId);
- } else {
- actualErrors.push(ruleId);
- }
- return ruleId;
- });
+ jest.spyOn(pack, 'applyRule');
const stack = new Stack();
Aspects.of(stack).add(pack);
new CfnResource(stack, 'rTestResource', { type: 'foo' });
SynthUtils.synthesize(stack).messages;
- expect(actualWarnings.sort()).toEqual(expectedWarnings.sort());
- expect(actualErrors.sort()).toEqual(expectedErrors.sort());
+ expect(pack.actualWarnings.sort()).toEqual(expectedWarnings.sort());
+ expect(pack.actualErrors.sort()).toEqual(expectedErrors.sort());
});
});
});
diff --git a/yarn.lock b/yarn.lock
index 40d73a7d05..77ea040dff 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5070,12 +5070,7 @@ json-schema-traverse@^1.0.0:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
-json-schema@0.2.3:
- version "0.2.3"
- resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
- integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
-
-json-schema@^0.4.0:
+json-schema@0.2.3, json-schema@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==