cdklabs/cdk-nag

Annotations and stages

ericzbeard opened this issue · 11 comments

What is the problem?

cdk-nag does not work with Stages. If an app contains a stage, it is not possible to apply cdk-nag at the app, stage, or stack level.

Reproduction Steps

#!/usr/bin/env node

const cdk = require('aws-cdk-lib');
const { Stack, Stage, App } = require('aws-cdk-lib');
const sqs = require('aws-cdk-lib/aws-sqs');
const s3 = require('aws-cdk-lib/aws-s3');
const { AwsSolutionsChecks } = require("cdk-nag")

class MyStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    new sqs.Queue(this, 'Queue', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });

    new s3.Bucket(this, 'Bucket', {})
  }
}

class TestStage extends Stage {
  constructor(scope, id, props) {
    super(scope, id, props);

    const s = new MyStack(this, 'MyStack');

    // This does nothing
    cdk.Aspects.of(s).add(new AwsSolutionsChecks({
      verbose: true
    }))
  }
}

const app = new App();

const myStack = new MyStack(app, 'TestStack')

// This works
cdk.Aspects.of(myStack).add(new AwsSolutionsChecks({
  verbose: true
}))

new TestStage(app, 'TestStage');

What did you expect to happen?

I expect cdk-nag to work if my stacks are in a stage.

What actually happened?

Nothing happens unless you pull the stack up to the app level when you instantiate it.

cdk-nag version

2.5.0

Language

Typescript

Other information

Also, cdk-nag 2.6.0 is broken on NPM. You can't do a default install.

Workaround

I created a file called nag.ts, in which I directly instantiate my stacks at the app level. I synthesize it with the following npm script:

"nag": "cdk synth --app='npx ts-node test/nag.ts'"

Related to: aws/aws-cdk#17805.

Using the example provided, cdk-nag does seem to be 'working' on a cdk synth command. However the Annotations do not render

@ericzbeard can you confirm whether a NagReport was generated in the cdk.out/assembly-TestStage folder? I see a resultant AwsSolutions-TestStage-MyStack-NagReport.csv with the following contents

Rule ID,Resource ID,Compliance,Exception Reason,Rule Level,Rule Info
"AwsSolutions-SQS2","TestStage/MyStack/Queue/Resource","Non-Compliant","N/A","Error","The SQS Queue does not have server-side encryption enabled."
"AwsSolutions-SQS3","TestStage/MyStack/Queue/Resource","Non-Compliant","N/A","Error","The SQS queue does not have a dead-letter queue (DLQ) enabled or have a cdk_nag rule suppression indicating it is a DLQ."
"AwsSolutions-SQS4","TestStage/MyStack/Queue/Resource","Non-Compliant","N/A","Error","The SQS queue does not require requests to use SSL."
"AwsSolutions-S1","TestStage/MyStack/Bucket/Resource","Non-Compliant","N/A","Error","The S3 Bucket has server access logs disabled."
"AwsSolutions-S2","TestStage/MyStack/Bucket/Resource","Non-Compliant","N/A","Error","The S3 Bucket does not have public access restricted and blocked."
"AwsSolutions-S3","TestStage/MyStack/Bucket/Resource","Non-Compliant","N/A","Error","The S3 Bucket does not default encryption enabled."
"AwsSolutions-S10","TestStage/MyStack/Bucket/Resource","Non-Compliant","N/A","Error","The S3 Bucket does not require requests to use SSL."

Like in @joel-aws's issue, Annotations did render and prevent the deployment (since there were Errors) when I ran cdk deploy TestStage/MyStack

donti@DESKTOP-GL4A569:~/test-cdk-project$ cdk deploy TestStage/MyStack
[Error at /TestStage/MyStack/Queue/Resource] AwsSolutions-SQS2: The SQS Queue does not have server-side encryption enabled. Server side encryption adds additional protection of sensitive data delivered as messages to subscribers.

[Error at /TestStage/MyStack/Queue/Resource] AwsSolutions-SQS3: The SQS queue does not have a dead-letter queue (DLQ) enabled or have a cdk_nag rule suppression indicating it is a DLQ. Using a DLQ helps maintain the queue flow and avoid losing data by detecting and mitigating failures and service disruptions on time.

[Error at /TestStage/MyStack/Queue/Resource] AwsSolutions-SQS4: The SQS queue does not require requests to use SSL. Without HTTPS (TLS), a network-based attacker can eavesdrop on network traffic or manipulate it, using an attack such as man-in-the-middle. Allow only encrypted connections over HTTPS (TLS) using the aws:SecureTransport condition in the queue policy to force requests to use SSL.

[Error at /TestStage/MyStack/Bucket/Resource] AwsSolutions-S1: The S3 Bucket has server access logs disabled. The bucket should have server access logging enabled to provide detailed records for the requests that are made to the bucket.

[Error at /TestStage/MyStack/Bucket/Resource] AwsSolutions-S2: The S3 Bucket does not have public access restricted and blocked. The bucket should have public access restricted and blocked to prevent unauthorized access.

[Error at /TestStage/MyStack/Bucket/Resource] AwsSolutions-S3: The S3 Bucket does not default encryption enabled. The bucket should minimally have SSE enabled to help protect data-at-rest.

[Error at /TestStage/MyStack/Bucket/Resource] AwsSolutions-S10: The S3 Bucket does not require requests to use SSL. You can use HTTPS (TLS) to help prevent potential attackers from eavesdropping on or manipulating network traffic using person-in-the-middle or similar attacks. You should allow only encrypted connections over HTTPS (TLS) using the aws:SecureTransport condition on Amazon S3 bucket policies.

Found errors

Annotations also rendered with cdk synth TestStage/MyStack instead of the all encompassing cdk synth command

In the provided example I left in the regular stack-based check under // This works. If you comment that out a cdk synth does not produce errors, which is what I would expect, since the stage does synthesize a template. And it does in fact produce the csv output, so why doesn't it product errors on the console? I would expect to able to include cdk synth in a build command and fail early if there are errors, instead of waiting for deployment. npx cdk synth "TestStage/MyStack" does produce the errors.

This issue is now marked as stale because it hasn't seen activity for a while. Add a comment or it will be closed soon.

Hi @dontirun , I have noticed the same error as @ericzbeard described. Has there been any progress on the item, considering that the issue got marked as stale?

This isn't something that seems to be fixable within this construct.

I believe it's related to this cdk issue

Any fix on this?
We have a large CDK deployment with stages and while we observe that CSV files are generated, it is needed to get correct output and build failure.

I believe the issue is with the implementation of Annotations within the CDK itself (linked issue above), unfortunately not something that can fixed within cdk-nag

Closing since,this is related to the implementation of stages and is an intended behavior. Running cdk synth '**' or cdk synth Stage/* will produce the desired Annotations as mentioned here