Validate CDK Application
CDK4J enables developers to define cloud infrastructure using Java code. As with any infrastructure-as-code approach, it is essential to verify that the provisioned infrastructure complies with security standards and best practices. To achieve this, we leverage the cdk4j-compliancy tool, designed to enforce security and compliance policies effectively.
What is cdk4j-compliancy?
cdk4j-compliancy is a comprehensive module that performs automated security and compliance checks on AWS CDK code and the generated CloudFormation templates. Its purpose is to help ensure that your infrastructure adheres to established security best practices and compliance standards.
By integrating cdk4j-compliancy into your project, you gain the ability to detect a wide range of common security and compliance issues, such as overly permissive IAM policies, missing access logging, and unintentionally public S3 buckets. Additionally, it identifies frequent mistakes that may introduce security vulnerabilities, including the use of plaintext passwords and default security groups.
One of the key benefits of cdk4j-compliancy is its ability to surface issues early in the development lifecycle. This enables you to identify and address potential security risks locally during your infrastructure-as-code development, ensuring a more secure and compliant deployment.
Adding cdk4j-compliancy to Maven build
Integrating cdk4j-compliancy into your AWS CDK project is straightforward. To get started, add cdk4j-compliancy as a dependency in your pom.xml file.
<dependency>
<groupId>org.datapith</groupId>
<artifactId>cdk4j-compliancy</artifactId>
<version>${cdk4j.version}</version>
</dependency>Once the dependency has been added, you must explicitly enable cdk4j-compliancy as shown below:
App app = App.Builder.create().build();
...
Compliancy compliancy = Compliancy.Builder.create(app)
.withRulePacks(RulePack.AWS)
.build();
compliancy.validate(app.synth());cdk4j-compliancy operates using rule packs that define sets of compliance and security rules. The currently supported rule packs include:
AWSHIPAANIST_REV4NIST_REV5PCI_DSS
You can enable one or more of these rule packs based on your specific compliance requirements.
Let’s examine a practical example of how to apply cdk4j-compliancy to a simple CDK application.
public class Cdk4jCompliancyDemoApp {
public static void main(final String[] args) {
App app = new App();
new Cdk4jComplianceDemoStack(app, "Cdk4jCompliancyDemoStack", StackProps.builder().build());
Compliancy compliancy = Compliancy.Builder.create(app)
.withRulePacks(RulePack.AWS)
.build();
compliancy.validate(app.synth());
}
}In the code snippet above, the AWS rule pack has been enabled for the entire CDK application scope.
Next, let’s review an example stack to observe how cdk4j-compliancy evaluates it. The following stack is a straightforward example that includes an S3 bucket.
public class Cdk4jComplianceDemoStack extends Stack {
public CdkNonCompliantStack(final Construct scope, final String id, final StackProps props) {
super(scope, id, props);
Bucket.Builder.create(this, "DemoBucket")
.bucketName("unit-test-bucket")
.build();
}
}When you run Cdk4jCompliancyDemoApp, it will invoke cdk4j-compliancy, which automatically scans your resources for security and compliance issues. Upon completion, cdk4j-compliancy will either indicate a successful validation or return an error message accompanied by a clear, easy-to-understand list of violations. The following messages illustrate the output generated after running cdk4j-compliancy.
Exception in thread "main" java.lang.RuntimeException: Compliancy errors:
[/Cdk4jCompliancyDemoStack/DemoBucket/Resource] AwsSolutions-S1: The S3 Bucket has server access logs disabled.
[/Cdk4jCompliancyDemoStack/DemoBucket/Resource] AwsSolutions-S10: The S3 Bucket or bucket policy does not require requests to use SSL.cdk4j-compliancy has identified several issues and provides guidance on how to enhance your infrastructure.
The specific messages generated depend on the selected rule pack. For example, switching to the HIPAA rule pack may produce some overlapping messages as well as additional compliance-related warnings.
Exception in thread "main" java.lang.RuntimeException: Compliancy errors:
[/Cdk4jCompliancyDemoStack/DemoBucket/Resource] HIPAA.Security-S3BucketLoggingEnabled: The S3 Bucket does not have server access logs enabled - (Control IDs: 164.308(a)(3)(ii)(A), 164.312(b)).
[/Cdk4jCompliancyDemoStack/DemoBucket/Resource] HIPAA.Security-S3BucketPublicReadProhibited: The S3 Bucket does not prohibit public read access through its Block Public Access configurations and bucket ACLs - (Control IDs: 164.308(a)(3)(i), 164.308(a)(4)(ii)(A), 164.308(a)(4)(ii)(C), 164.312(a)(1), 164.312(e)(1)).
[/Cdk4jCompliancyDemoStack/DemoBucket/Resource] HIPAA.Security-S3BucketPublicWriteProhibited: The S3 Bucket does not prohibit public write access through its Block Public Access configurations and bucket ACLs - (Control IDs: 164.308(a)(3)(i), 164.308(a)(4)(ii)(A), 164.308(a)(4)(ii)(C), 164.312(a)(1), 164.312(e)(1)).
[/Cdk4jCompliancyDemoStack/DemoBucket/Resource] HIPAA.Security-S3BucketReplicationEnabled: The S3 Bucket does not have replication enabled - (Control IDs: 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.308(a)(7)(ii)(B)).
[/Cdk4jCompliancyDemoStack/DemoBucket/Resource] HIPAA.Security-S3BucketSSLRequestsOnly: The S3 Bucket or bucket policy does not require requests to use SSL - (Control IDs: 164.312(a)(2)(iv), 164.312(c)(2), 164.312(e)(1), 164.312(e)(2)(i), 164.312(e)(2)(ii)).
[/Cdk4jCompliancyDemoStack/DemoBucket/Resource] HIPAA.Security-S3BucketVersioningEnabled: The S3 Bucket does not have versioning enabled - (Control IDs: 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.308(a)(7)(ii)(B), 164.312(c)(1), 164.312(c)(2)).
[/Cdk4jCompliancyDemoStack/DemoBucket/Resource] HIPAA.Security-S3DefaultEncryptionKMS: The S3 Bucket is not encrypted with a KMS Key by default - (Control IDs: 164.312(a)(2)(iv), 164.312(e)(2)(ii)).Suppressing Findings
Occasionally, cdk4j-compliancy may flag configurations that are intentional, such as a public S3 bucket for a static website or a broadly permissive security group for a specific use case. In such instances, you can suppress these findings by providing a justification as follows:
public class Cdk4jCompliancyDemoApp {
public static void main(final String[] args) {
App app = new App();
new Cdk4jComplianceDemoStack(app, "Cdk4jCompliancyDemoStack", StackProps.builder().build());
Suppress.Builder.create(app).withRuleId("AwsSolutions-S1").reason("Suspend finding for demo").build();
Compliancy compliancy = Compliancy.Builder.create(app)
.withRulePacks(RulePack.AWS)
.build();
compliancy.validate(app.synth());
}
}In the example above, the rule AwsSolutions-S1 is suppressed for the entire application. After running cdk4j-compliancy, the error related to disabled logging will no longer appear in the output.
Exception in thread "main" java.lang.RuntimeException: ValidationError: Validation failed with the following errors:
[] Error at Cdk4jCompliancyDemoStack.DemoBucket: AwsSolutions-S10 - The S3 Bucket or bucket policy does not require requests to use SSL.