cdk-nagを導入してみた

## はじめに


### 背景・目的

- 私が参画しているクラウドマイグレーションプロジェクトでは、CDKを用いてAWS環境構築を行っています。
- セキュリティと開発効率とを両立するために、発見的統制に重きをおいたガードレール戦略を採用しています。(主要開発メンバ向け権限について、セキュリティ及びガバナンス上許容できない操作はIAM権限で拒否しつつ、それ以外の操作については比較的自由度を持たせています。)
- `Security Hubアラート対応工数軽減`及び`Security Hubによる発見的統制の補助`を目的として、cdk-nagを用いたデプロイ前のセキュリティチェックを導入してみました。
- 本記事では、cdk-nagの概要・運用方法・導入後の所感について説明します。

### 対象読者

- CloudFormationやCDK等のIaCツールを用いたAWS環境構築経験がある方
- AWS環境構築時のセキュリティ担保方法に関心がある方

## cdk-nagの概要

- cdk-nagは、CDKでのAWS資源デプロイ前にセキュリティルールへの準拠状況をチェックできるツールです。
- 2024年4月時点では、5種類のルールが用意されています。
    - AWS Solutions
    - HIPAA Security
    - NIST 800-53 rev 4
    - NIST 800-53 rev 5
    - PCI DSS 3.2.1
- 用意されたルールに加えて、カスタムルールの作成も可能です。

### 利用方法

- cdk-nag をインストールします。

```bash
# cdk-nagのインストール
npm i cdk-nag
```

- CDKアプリに cdk-nag を適用します。

```tsx
// import
import { AwsSolutionsChecks } from "cdk-nag";
import { Aspects } from "aws-cdk-lib";

// AWS Solutionsルールでのチェックを記載
Aspects.of(app).add(new AwsSolutionsChecks({ verbose: true }));
```

- セキュリティルールに非準拠の資源が存在する状態でcdk コマンドを実行すると、コンソール及び`cdk.out/AwsSolutions-StackName-NagReport.csv`にエラーレポートが表示されます。

```
[Error at /StorageStack/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 /StorageStack/Bucket/Resource] AwsSolutions-S10: The S3 Bucket or bucket policy 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
```

### 修正・抑制方法

- セキュリティルール準拠するよう、指摘対象資源を設定変更することで、cdkコマンド実行時のエラーが解消されます。
- 設定変更が不可能な場合、理由を明記したうえでエラーを抑制することもできます。

```tsx
import { NagSuppressions } from "cdk-nag";

const bucket = new s3.Bucket(this, "Bucket", {
  // Remediating AwsSolutions-S10
  enforceSSL: true,
});
// Suppressing AwsSolutions-S1
NagSuppressions.addResourceSuppressions(bucket, [
  {
    id: "AwsSolutions-S1",
    reason: "Lorem ipsum dolor sit amet",
  },
]);
```

- スタック単位でエラーを抑制することも可能です。

```tsx
// スタック単位でSuppressionを設定
NagSuppressions.addStackSuppressions(storageStack, [
  {
    id: "AwsSolutions-S1",
    reason: "Lorem ipsum dolor sit amet"
  }
])
```

## 運用方法

私が参画しているプロジェクトでは、`セキュリティと開発効率の両立が重要である`・`cdk-nagはSecurity Hubの補助ツールであり、最終的にはSecurity Hubで発見的統制を効かせられれば良い`との思想に基づき、cdk-nagの運用方法を決定しました。

### ルール選択

- cdk-nagはSecurity Hubの補助ツールであることを考慮し、対象ルールは`AWS Solutions`に限定しました。(且つ、カスタムルールの実装も行っていません。)
- なお、クライアントの業界上、`HIPAA`や`PCI DSS`はそもそも考慮対象外でした。

### 抑制戦略

- 開発効率及びcdk-nagはSecurity Hubの補助ツールであることを考慮し、中央集権的な管理ではなく、各開発者にcdk-nag抑制対応を委ねました。そのうえで、CDKコード及びエラーレポートに対するレビューを実施しました。
- レビュー実施後、Security Hub側のコントロールも抑制済みに変更しました。(且つ、Security Hub設定変更権限はレビュワーに限定しています。)

## cdk-nag採用の所感
- 導入時の期待通り、cdk-nagはデプロイ前のセキュリティチェックツールとして機能し、Security Hubによる発見的統制の補助の役目を果たしてくれました。
- 加えて、修正・抑制対応を通じて、AWSセキュリティ設定に対する各開発者の理解が深まった印象があります。
- ただし、正直なところ、工数減少効果は実感できませんでした。(Security Hub対応工数が減少したものの、cdk-nag側の対応工数が増加したため。)

## 参考資料
- [cdklabs/cdk-nag](https://github.com/cdklabs/cdk-nag)
- [AWS Cloud Development Kit と cdk-nag でアプリケーションのセキュリティとコンプライアンスを管理する](https://aws.amazon.com/jp/blogs/news/manage-application-security-and-compliance-with-the-aws-cloud-development-kit-and-cdk-nag/)


## 注意事項
- 本記事は万全を期して作成していますが、お気づきの点がありましたら、ご連絡よろしくお願いします。
- なお、本記事の内容を利用した結果及び影響について、筆者は一切の責任を負いませんので、予めご了承ください。