Amazon Web Services ブログ
AWS Cloud Development Kit と cdk-nag でアプリケーションのセキュリティとコンプライアンスを管理する
この記事は Arun Donti によって寄稿された Manage application security and compliance with the AWS Cloud Development Kit and cdk-nag (記事公開日: 2022 年 5 月 25 日) を翻訳したものです。
Infrastructure as Code (IaC) は、クラウド・アプリケーションの重要な要素です。開発者は、様々な静的解析 (SAST) ツールを利用して、セキュリティやコンプライアンスの問題を特定し、アプリケーションを本番環境にリリースする前に、これらの問題を早期に軽減することができます。さらに、静的解析ツールは、開発者がセキュリティレビュー中にコンプライアンスを検証するために役立つレポートメカニズムを提供してくれます。
cdk-nag
は、AWS Cloud Development Kit (AWS CDK) アプリケーションに直接統合し、静的解析ツールと同様の検出およびレポートメカニズムを提供します。
本投稿では、AWS CDK アプリケーションに cdk-nag を統合して、継続的なフィードバックを提供し、アプリケーションをベストプラクティスな形に整えていく方法を紹介します。
cdk-nag の概要
cdk-nag
(cfn_nag により影響) は、与えられたスコープ内のコンストラクトの状態が、与えられたルール群に準拠しているかどうかを検証します。さらに、cdk-nag は、ルール抑制とコンプライアンスレポートシステムを提供します。cdk-nag は、AWS CDK Aspects を拡張することにより、コンストラクトを検証します。もし、AWS CDK Aspects の仕組みについての詳細に興味がある場合、この投稿をチェックしてみてください。
cdk-nag
には、アプリケーションを検証するためのいくつかのルールセット(NagPacks)が含まれています。この投稿の時点では、cdk-nagは、AWS Solutions、HIPAA Security、NIST 800-53 rev 4、NIST 800-53 rev 5、およびPCI DSS 3.2.1 のNagPacks を含んでいます。あなたは、異なる NagPacks を選択し、与えられたスコープに必要なものだけを適用することができます。
cdk-nag のルールは、警告
またはエラー
のいずれかを指定できます。警告
とエラー
の両方は、コンソールおよびコンプライアンスレポートに表示されます。抑制されていないエラー
のみが、cdk deploy コマンドによるアプリケーションのデプロイを防いでくれます。
どのルールが各 NagPacks に実装されているかは、GitHub リポジトリの Rules Documentation で確認することができます。
手順
本手順では、最小限の AWS CDK v2 アプリケーションをセットアップし、アプリケーションに NagPack を適用する方法、ルールを抑制する方法、調査結果のレポートを表示する方法について説明します。 cdk-nag は Python 、 TypeScript 、 Java、 .NET による AWS CDKアプリケーションをサポートしていますが、本手順ではTypeScriptを使用します。
前提
本手順では、以下の前提条件を満たしている必要があります。
- AWS CDK をローカルにインストールし、使用した経験があること。
ベースとなる AWS CDK アプリケーションの作成
このセクションでは、Amazon Simple Storage Service (Amazon S3) のバケットを使った、シンプルな AWS CDK v2 アプリケーションを作成します。もし、AWS CDK の使用に慣れていない場合は、オープンソースの GitHub リポジトリを参照し、AWS CDK のインストールとセットアップの方法を学習することをおすすめします。
- 以下のコマンドを実行し、AWS CDK アプリケーションを作成します。
mkdir CdkTest
cd CdkTest
cdk init app --language typescript
lib/cdk_test-stack.ts
を、以下の内容に置き換えます。
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Bucket } from 'aws-cdk-lib/aws-s3';
export class CdkTestStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const bucket = new Bucket(this, 'Bucket')
}
}
- 以下のコマンドを実行して、依存関係のインストール、および、サンプルアプリケーションの合成を行います。
npm install
npx cdk synth
ターミナルコンソールの画面と cdk.out/CdkTestStack.template.json
の両方に、S3 バケットを持つ AWS CloudFormation テンプレートが表示されます。
アプリケーションに NagPack を適用する
このセクションでは、cdk-nag をインストールし、AwsSolutions NagPack をアプリケーションに含め、結果を表示します。
- 以下のコマンドを実行し、AWS CDK アプリケーションを作成します。
npm install cdk-nag
bin/cdk_test.ts
を、以下の内容に置き換えます。
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { CdkTestStack } from '../lib/cdk_test-stack';
import { AwsSolutionsChecks } from 'cdk-nag'
import { Aspects } from 'aws-cdk-lib';
const app = new cdk.App();
// Add the cdk-nag AwsSolutions Pack with extra verbose logging enabled.
Aspects.of(app).add(new AwsSolutionsChecks({ verbose: true }))
new CdkTestStack(app, 'CdkTestStack', {});
- 以下のコマンドを実行して出力結果を表示し、コンプライアンスレポートを作成します。
npx cdk synth
出力結果は、以下のようになるはずです(注:SSEはServer-side encryptionの略です)。
[Error at /CdkTestStack/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 /CdkTestStack/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 /CdkTestStack/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 /CdkTestStack/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
AwsSolutions NagPack をアプリケーションに適用すると、コンソールに複数のエラー
(AwsSolutions-S1
、 AwsSolutions-S2
、 AwsSolutions-S3
、 AwsSolutions-S10
)が表示されます。さらに、cdk.out/AwsSolutions-CdkTestStack-NagReport.csv
にも、同様にエラー内容が出力されます。
Rule ID,Resource ID,Compliance,Exception Reason,Rule Level,Rule Info
"AwsSolutions-S1","CdkTestStack/Bucket/Resource","Non-Compliant","N/A","Error","The S3 Bucket has server access logs disabled."
"AwsSolutions-S2","CdkTestStack/Bucket/Resource","Non-Compliant","N/A","Error","The S3 Bucket does not have public access restricted and blocked."
"AwsSolutions-S3","CdkTestStack/Bucket/Resource","Non-Compliant","N/A","Error","The S3 Bucket does not default encryption enabled."
"AwsSolutions-S5","CdkTestStack/Bucket/Resource","Compliant","N/A","Error","The S3 static website bucket either has an open world bucket policy or does not use a CloudFront Origin Access Identity (OAI) in the bucket policy for limited getObject and/or putObject permissions."
"AwsSolutions-S10","CdkTestStack/Bucket/Resource","Non-Compliant","N/A","Error","The S3 Bucket does not require requests to use SSL."
エラーの修正と抑制
ここでは、AwsSolutions-S10 エラー
の修復、Stack
レベルの AwsSolutions-S1
エラーの抑制、Resource
レベルの AwsSolutions-S2
エラーの抑制、AwsSolutions-S3
エラーの修復を行わず、結果を表示します。
lib/cdk_test-stack.ts
を、以下の内容に置き換えます。
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Bucket } from 'aws-cdk-lib/aws-s3';
import { NagSuppressions } from 'cdk-nag'
export class CdkTestStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// The local scope 'this' is the Stack.
NagSuppressions.addStackSuppressions(this, [
{
id: 'AwsSolutions-S1',
reason: 'Demonstrate a stack level suppression.'
},
])
// Remediating AwsSolutions-S10 by enforcing SSL on the bucket.
const bucket = new Bucket(this, 'Bucket', { enforceSSL: true })
NagSuppressions.addResourceSuppressions(bucket, [
{
id: 'AwsSolutions-S2',
reason: 'Demonstrate a resource level suppression.'
},
])
}
}
cdk synth
コマンドを再度実行します。
npx cdk synth
以下のように出力されるはずです。
[Error at /CdkTestStack/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.
Found errors
cdk.out/AwsSolutions-CdkTestStack-NagReport.csv
には、ルールの準拠、非準拠、抑制の詳細が記載されています。
Rule ID,Resource ID,Compliance,Exception Reason,Rule Level,Rule Info
"AwsSolutions-S1","CdkTestStack/Bucket/Resource","Suppressed","Demonstrate a stack level suppression.","Error","The S3 Bucket has server access logs disabled."
"AwsSolutions-S2","CdkTestStack/Bucket/Resource","Suppressed","Demonstrate a resource level suppression.","Error","The S3 Bucket does not have public access restricted and blocked."
"AwsSolutions-S3","CdkTestStack/Bucket/Resource","Non-Compliant","N/A","Error","The S3 Bucket does not default encryption enabled."
"AwsSolutions-S5","CdkTestStack/Bucket/Resource","Compliant","N/A","Error","The S3 static website bucket either has an open world bucket policy or does not use a CloudFront Origin Access Identity (OAI) in the bucket policy for limited getObject and/or putObject permissions."
"AwsSolutions-S10","CdkTestStack/Bucket/Resource","Compliant","N/A","Error","The S3 Bucket does not require requests to use SSL."
さらに、結果として出力された cdk.out/CdkTestStack.template.json
には、cdk-nag
の抑制データが含まれていることに注目してください。抑制データがリソースに含まれるため、アプリケーションに適用されなかったルールの透明性が確保されます。
{
"Metadata": {
"cdk_nag": {
"rules_to_suppress": [
{
"id": "AwsSolutions-S1",
"reason": "Demonstrate a stack level suppression."
}
]
}
},
"Resources": {
"BucketDEB6E181": {
"Type": "AWS::S3::Bucket",
"UpdateReplacePolicy": "Retain",
"DeletionPolicy": "Retain",
"Metadata": {
"aws:cdk:path": "CdkTestStack/Bucket/Resource",
"cdk_nag": {
"rules_to_suppress": [
{
"id": "AwsSolutions-S2",
"reason": "Demonstrate a resource level suppression."
}
]
}
}
},
...
},
...
}
手順の振り返り
このセクションでは、アプリケーションに NagPack
を適用する方法、警告
とエラー
を修正/抑制する方法、およびコンプライアンスレポートを確認する方法を学びました。レポートと抑制システムは、組織内の開発チームとセキュリティチームが協力して、潜在的なセキュリティ/コンプライアンス問題を特定し、軽減するためのメカニズムを提供します。セキュリティは、開発者が自分のアプリケーションに適用すべき NagPacks を選択することができます。そして、開発者はフィードバックを得ながら、問題を迅速に修正することができます。セキュリティはコンプライアンスを検証するために、レポートを使用することができます。さらに、開発者とセキュリティ担当は、抑制化を使用して、従わないと判断した例外的なルールを、透過的に文書化するために、相互に協力することができます。
高度な使用法と追加情報
このセクションでは、cdk-nag
を使用するためのいくつかの高度なオプションについて、簡単に説明します。
AWS CDK Assertions Library を使用した単体テスト
AWS CDK Assertion Library のアノテーションサブモジュールは、アプリケーションのユニットテストに NagPack を統合することで、AWS 認証情報なしで cdk-nag
の警告
とエラー
をチェックすることができます。AWS CDK アサーションモジュールの詳細については、この投稿をお読みください。以下は、TypeScript の AWS CDK アプリケーションとユニットテスト用の Jest でのアサーションを使用する例です。
import { Annotations, Match } from 'aws-cdk-lib/assertions';
import { App, Aspects, Stack } from 'aws-cdk-lib';
import { AwsSolutionsChecks } from 'cdk-nag';
import { CdkTestStack } from '../lib/cdk_test-stack';
describe('cdk-nag AwsSolutions Pack', () => {
let stack: Stack;
let app: App;
// In this case we can use beforeAll() over beforeEach() since our tests
// do not modify the state of the application
beforeAll(() => {
// GIVEN
app = new App();
stack = new CdkTestStack(app, 'test');
// WHEN
Aspects.of(stack).add(new AwsSolutionsChecks());
});
// THEN
test('No unsuppressed Warnings', () => {
const warnings = Annotations.fromStack(stack).findWarning(
'*',
Match.stringLikeRegexp('AwsSolutions-.*')
);
expect(warnings).toHaveLength(0);
});
test('No unsuppressed Errors', () => {
const errors = Annotations.fromStack(stack).findError(
'*',
Match.stringLikeRegexp('AwsSolutions-.*')
);
expect(errors).toHaveLength(0);
});
});
さらに、多くのテストフレームワークは Watch
機能を備えています。これは、プロジェクト内のファイルが変更されたときに、すべてのテストを再実行するバックグラウンド処理で、高速なフィードバックが得られます。例えば、JavaScript/Typescript で AWS CDK を記述した場合、Jest CLI の watch コマンドを使用することができます。Jest watch はファイルの変更を検出すると、変更されたファイルに関連するユニットテストの実行を試みます。この仕組みを利用して、AWS CDK アプリケーションに変更を加える際に、cdk-nag 関連のテストを自動的に実行することができます。
CDK Watch
本番環境ではない環境で開発する場合、高速なフィードバックを得るために AWS CDK Watchを NagPack と一緒に使うことを検討してください。AWS CDK Watch は、ファイルに変更を保存するたびに、コードの合成を試みてから変更をデプロイします。 Aspects はコードの合成中に実行されます。したがって、アプリケーションに適用された NagPack は、保存時にも実行されます。手順の内容と同様に、すべての未対応エラー
はデプロイを防止し、すべてのメッセージはコンソールに出力され、すべてのコンプライアンスレポートが生成されます。 AWS CDK Watch の詳細については、こちらの投稿をご覧ください。
まとめ
本投稿では、AWS CDK アプリケーションで cdk-nag
を使用する方法を学びました。あなたのアプリケーションで cdk-nag
を使用する方法の詳細については、 GitHub Repository の README をチェックしてください。独自のルールや NagPacks を作成する方法を学びたい場合は、開発者向けドキュメントをチェックしてください。このリポジトリはオープンソースであり、コミュニティの貢献とフィードバックを歓迎します。
翻訳はプロフェッショナルサービスの水流が担当しました。原文はこちらです。