1.1.0 • Published 2 years ago

@enfo/aws-cdkompliance v1.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

Introduction

Compliant resource Constructs and tagging using the CDK. The compliant Constructs make it easier to reduce your number of Security Hub security findings. If you are using CloudFormation rather than the CDK you can check the unit tests on the source repository to get an idea of what you need to fix.

The tagging part of this package is tied to Enfo and its customers. Enfo is a Managed Service Provider for AWS. You can of course use the package without being a customer, but the tags might have no effect depending on your AWS organization setup.

Installation

The package should be installed as a dependency.

npm install @enfo/aws-cdkompliance --save

Compliant resource Constructs

In Security Hub you can find a list of security findings. We refer to resources with such findings as non-compliant. This package exposes compliant Constructs which are extensions of CDK Constructs. They have been modified to throw errors during CDK synthesis should you try to use a poorly set Construct property. Most Constructs require no input from you and will be compliant by default.

When possible the default Props used to create the Construct are exposed as well.

Application Load Balancer

The following features are available for Application Load Balancer.

  • ApplicationLoadBalancer, compliant Application Load Balancer Construct. Will throw if non-compliant properties are passed
  • defaultApplicationLoadBalancerProps, the ApplicationLoadBalancerProps used to make the Application Load Balancer compliant

The following Security Hub findings are managed by the ApplicationLoadBalancer Construct.

Application Load Balancer creation example.

import { ApplicationLoadBalancer, Bucket } from '@enfo/aws-cdkompliance'
import { Stack } from 'aws-cdk-lib'
import { Vpc } from 'aws-cdk-lib/aws-ec2'

const stack = new Stack(undefined, 'Stack', { env: { region: 'eu-west-1' } } )
const vpc = new Vpc(stack, 'VPC')
const bucket = new Bucket(stack, 'Bucket')
const alb = new ApplicationLoadBalancer(stack, 'ALB', { vpc })
alb.logAccessLogs(bucket)

CloudFront

The following features are available for CloudFront.

  • Distribution, compliant CloudFront Distribution Construct. Will throw if non-compliant properties are passed
  • defaultDistributionProps, the DistributionProps used to make the distribution compliant

The following Security Hub findings are managed by the Distribution Construct.

CloudFront Distribution creation example.

import { Distribution } from '@enfo/aws-cdkompliance'
import { ViewerProtocolPolicy } from 'aws-cdk-lib/aws-cloudfront'
import { HttpOrigin } from 'aws-cdk-lib/aws-cloudfront-origins'
import { CfnWebACL } from 'aws-cdk-lib/aws-wafv2'
import { Stack } from 'aws-cdk-lib'

const stack = new Stack()
const webAcl = new CfnWebACL(stack, 'WebACL', {
  scope: 'CLOUDFRONT',
  defaultAction: { allow: {} },
  visibilityConfig: {
    cloudWatchMetricsEnabled: false,
    metricName: 'metricName',
    sampledRequestsEnabled: false,
  }
})

new Distribution(stack, 'Distribution', {
  defaultBehavior: {
    origin: new HttpOrigin('example.com'),
    viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS
  },
  webAclId: webAcl.attrId
})

DynamoDB

The following features are available for DynamoDB.

  • Table, Construct defaulting to using BillingMode.PAY_PER_REQUEST and point in time recovery enabled

The following Security Hub findings are managed by the Table Construct.

Table creation example without billingMode specified. Will default to PAY_PER_REQUEST. The Table will not be tagged to suppress warnings. The same will happen if billingMode is set to PAY_PER_REQUEST.

import { Table } from '@enfo/aws-cdkompliance'
import { Stack } from 'aws-cdk-lib'
import { AttributeType, BillingMode } from 'aws-cdk-lib/aws-dynamodb'

const stack = new Stack()
new Table(stack, 'Table', {
  partitionKey: {
    name: 'pk',
    type: AttributeType.STRING
  }
})

KMS

The following features are available for KMS.

  • Key, compliant KMS Key Construct. Will throw if non-compliant properties are passed
  • defaultKeyProps, the KeyProps used to enforce compliance if you don't supply your own

While we do not enforce alias on KeyProps we do recommend that you set it.

Key creation example

import { Key } from '@enfo/aws-cdkompliance'
import { Stack } from 'aws-cdk-lib'

const stack = new Stack()
new Key(stack, 'Key', { alias: 'my-key' })

Lambda

The following features are available for Lambda.

  • Function, compliant Lambda Function Construct

The following Security Hub findings are managed by the Function Construct.

Function creation example

import { Function } from '@enfo/aws-cdkompliance'
import { Code, Runtime } from 'aws-cdk-lib/aws-lambda'
import { Stack } from 'aws-cdk-lib'

const stack = new Stack()
new Function(stack, 'Function', {
  runtime: Runtime.NODEJS_16_X,
  handler: 'handler',
  code: Code.fromInline('myCode')
})

Lambda NodeJS

The following features are available for Lambda NodeJS.

  • NodejsFunction, compliant NodeJS Lambda NodejsFunction Construct

The following Security Hub findings are managed by the NodejsFunction Construct.

NodejsFunction creation example

import { NodejsFunction } from '@enfo/aws-cdkompliance'
import { Stack } from 'aws-cdk-lib'

const stack = new Stack()
new NodejsFunction(stack, 'Function', {
  handler: 'handler',
  entry: path.join(__dirname, '../src/hello-world.ts')
})

Logs

The following features are available for Logs.

  • LogGroup, compliant Log Group Key Construct. Will throw if non-compliant properties are passed
  • defaultLogGroupProps, the LogGroupProps used to enforce compliance if you don't supply your own

LogGroup creation example

import { LogGroup } from '@enfo/aws-cdkompliance'
import { Stack } from 'aws-cdk-lib'

const stack = new Stack()
new LogGroup(stack, 'LogGroup')

RDS

The following features are available for RDS

  • DatabaseCluster, compliant DatabaseCluster Construct
  • defaultDatabaseClusterProps, the DatabaseClusterProps used to make the DatabaseCluster compliant
  • defaultInstanceProps, the InstanceProps used to make the DatabaseCluster compliant
  • DatabaseEnvironment, to indicate the how a DatabaseInstance will be used
  • DatabaseInstance, compliant DatabaseInstance Construct
  • defaultDatabaseInstanceProps, the DatabaseInstanceProps used to make the DatabaseInstance compliant

The following Security Hub findings are managed by the DatabaseCluster Construct.

DatabaseCluster creation example.

import { DatabaseCluster } from '@enfo/aws-cdkompliance'
import { Stack } from 'aws-cdk-lib'
import { Vpc } from 'aws-cdk-lib/aws-ec2'
import { AuroraPostgresEngineVersion, DatabaseClusterEngine } from 'aws-cdk-lib/aws-rds'

const stack = new Stack()
const vpc = new Vpc(stack, 'VPC')
new DatabaseCluster(stack, 'DatabaseCluster', {
  engine: DatabaseClusterEngine.auroraPostgres({ version: AuroraPostgresEngineVersion.VER_13_4 }),
  instanceProps: {
    vpc
  }
})

The following Security Hub findings are managed by the DatabaseInstance Construct.

Note that DatabaseInstance defaults to MultiAZ, and you need to set environment: NOT_PRODUCTION to be able to set MultiAZ to false.

DatabaseInstance creation example.

import { DatabaseEnvironment, DatabaseInstance } from '@enfo/aws-cdkompliance'
import { Stack } from 'aws-cdk-lib'
import { Vpc } from 'aws-cdk-lib/aws-ec2'
import { DatabaseInstanceEngine, PostgresEngineVersion } from 'aws-cdk-lib/aws-rds'

const stack = new Stack()
const vpc = new Vpc(stack, 'VPC')
new DatabaseInstance(stack, 'Database', {
  vpc,
  engine: DatabaseInstanceEngine.postgres({ version: PostgresEngineVersion.VER_13_4 }),
  environment: DatabaseEnvironment.NOT_PRODUCTION,
  multiAz: false
})

S3

The following features are available for S3.

  • Bucket, compliant S3 Bucket Construct
  • defaultBucketProps, the BucketProps used to enforce compliance if you don't supply your own

The following Security Hub findings are managed by the Bucket Construct.

Bucket creation example

import { Bucket } from '@enfo/aws-cdkompliance'
import { Stack } from 'aws-cdk-lib'

const stack = new Stack()
new Bucket(stack, 'MyBucket', { bucketName: 'my-bucket' })

SNS

The following features are available for SNS. SNS requires a KMS Key Construct to be compliant.

  • Topic, compliant SNS Topic Construct. Will throw if non-compliant properties are passed

The following Security Hub findings are managed by the Topic Construct.

Topic creation example

import { Key, Topic } from '@enfo/aws-cdkompliance'
import { Stack } from 'aws-cdk-lib'

const stack = new Stack()
new Topic(stack, 'Topic', {
  masterKey: new Key(stack, 'Key')
})

SQS

The following features are available for SQS.

  • Queue, compliant SQS Queue Construct. Will throw if non-compliant properties are passed
  • defaultQueueProps, the QueueProps used to make the queue compliant

The following Security Hub findings are managed by the Queue Construct.

Queue creation example.

import { Queue } from '@enfo/aws-cdkompliance'
import { Stack } from 'aws-cdk-lib'

const stack = new Stack()
new Queue(stack, 'Queue', { queueName: 'my-queue' })

Tagging

This section largely caters to Enfo customers. If you are not an Enfo customer you can still achieve the functionality described for enableBackups.

enableBackups

If you are an Enfo customer you can enable backups of databases using tags. This can easily be achieved by using the function enableBackups. This function can be applied on a Resource, Stack or App level.

If you are not an Enfo customer can achieve backups by reading this AWS guide.

Enabling backups of a single resource.

import { enableBackups, Table } from '@enfo/aws-cdkompliance'
import { Stack } from 'aws-cdk-lib'
import { AttributeType } from 'aws-cdk-lib/aws-dynamodb'

const stack = new Stack()
const myTable = new Table(stack, 'Table', { 
  partitionKey: {
    name: 'pk',
    type: AttributeType.STRING
  }
})
enableBackups(myTable)

Enable backups of an entire stack.

import { enableBackups } from '@enfo/aws-cdkompliance'
import { Stack } from 'aws-cdk-lib'

const stack = new Stack()
enableBackups(stack)

Enable backups of an entire app.

import { enableBackups } from '@enfo/aws-cdkompliance'
import { App } from 'aws-cdk-lib'

const app = new App()
enableBackups(app)

Where backups are stored can be controlled via the second parameter, backupPlan. It defaults to STANDARD which creates backups in the region in which the resource exists.

import { enableBackups, BackupPlan } from '@enfo/aws-cdkompliance'
import { App } from 'aws-cdk-lib'

const app = new App()
enableBackups(app, BackupPlan.STOCKHOLM)

exemptBucketFromBlockPublicAutoFix

Buckets in an AWS account managed by Enfo will automatically have [S3.1] S3 Block Public Access setting should be enabled fixed. If you do no want this to happen you can use this tagging function to exempt the bucket.

import { exemptBucketFromBlockPublicAutoFix } from '@enfo/aws-cdkompliance'
import { Bucket } from 'aws-cdk-lib/aws-s3'
import { Stack } from 'aws-cdk-lib'

const stack = new Stack()
const bucket = new Bucket(stack)
exemptBucketFromBlockPublicAutoFix(bucket)

exemptBucketFromSslAutoFix

Buckets in an AWS account managed by Enfo will automatically have [S3.4] S3 buckets should have server-side encryption enabled fixed. If you do no want this to happen you can use this tagging function to exempt the bucket.

import { exemptBucketFromSslAutoFix } from '@enfo/aws-cdkompliance'
import { Bucket } from 'aws-cdk-lib/aws-s3'
import { Stack } from 'aws-cdk-lib'

const stack = new Stack()
const bucket = new Bucket(stack)
exemptBucketFromSslAutoFix(bucket)
1.1.0

2 years ago

1.0.0

2 years ago

0.1.0

2 years ago

0.0.1

2 years ago