NeptuneデータベースインスタンスでのCMKでの暗号化について

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。
今回は、Amazon NeptuneデータベースインスタンスがAWS所有キーで暗号化されており、カスタマー管理キー (CMK) 以上のレベルで暗号化されていない状態について、そのリスクと対策を解説します。

リスク
Amazon Neptuneは、高速で信頼性が高く、フルマネージド型のグラフデータベースサービスです。ソーシャルネットワーク、レコメンデーションエンジン、不正検出などのグラフアプリケーションの構築と実行を容易にします。Neptuneは、デフォルトで保管時の暗号化をサポートしていますが、その際にAWSが所有するKMSキー(AWS owned key)が使用されます。コンプライアンスの基準に応じてKMSカスタマー管理キー(CMK)での暗号化を行うようにしましょう。
修復方法
Amazon Neptuneデータベースインスタンスの暗号化をKMSカスタマー管理キー(CMK)で有効にする方法は、AWSコンソールまたはTerraformで行えます。CloudHSMキーを使用する場合は、先にAWS CloudHSMクラスターとそれに統合されたKMSキーを作成する必要があります。
AWSコンソールでの修復手順
AWSコンソールを使用して、Amazon Neptuneデータベースインスタンスの作成時にKMS CMKで暗号化を有効にします。
前提:
- Neptuneデータベースを暗号化するためのAWS KMS カスタマー管理キー (CMK) が既に存在すること。
- CMKのキーポリシーには、Neptuneサービス (
rds.amazonaws.com
) がキーを使用するための適切な権限(kms:Encrypt
,kms:Decrypt
など)が付与されている必要があります。
- CMKのキーポリシーには、Neptuneサービス (
- Amazon Neptuneサービスへ移動: AWSコンソールにログインし、Amazon Neptune サービスを開きます。
- データベースの作成: 左側のナビゲーションペインで「データベース」を選択し、「データベースを作成」をクリックします。
- エンジンオプションと設定の選択:
- エンジンタイプ:
Neptune
を選択します。 - バージョン: 希望するNeptuneのバージョンを選択します。
- データベースインスタンスの識別子: 一意のクラスター識別子とインスタンス識別子を設定します。
- エンジンタイプ:
- ストレージと暗号化の設定:
- 「ストレージ」セクションまでスクロールします。
- 「暗号化」セクションで、「暗号化を有効にする」にチェックが入っていることを確認します。
- 「KMS キー」のドロップダウンメニューから、「カスタマー管理キー (CMK)」を選択します。
- 表示されるドロップダウンリストから、使用したい既存のKMS CMKを選択します。
- もし適切なCMKがリストに表示されない場合は、正しいIAM権限があるか、またはCMKが作成されているか確認してください。

- その他の設定(接続、セキュリティ、バックアップなど)を構成します。
- データベースの作成: 設定内容を確認し、「データベースの作成」をクリックしてデータベースクラスターをプロビジョニングします。
これで、Amazon Neptuneデータベースインスタンスに保存されるデータは、指定したKMS CMKを使用して保管時に暗号化されるようになります。既存のインスタンスの暗号化キーを変更することはできないため、既存のインスタンスをCMKで暗号化したい場合は、新しいクラスターにデータを移行する必要があります。
Terraformでの修復手順
TerraformでAmazon Neptuneデータベースインスタンスの暗号化をKMSカスタマー管理キー(CMK)で有効にするには、aws_neptune_cluster
リソースの kms_key_arn
パラメータを設定します。
# (例) Neptuneデータベース暗号化用のKMSカスタマー管理キー (CMK)
resource "aws_kms_key" "neptune_cmk" {
description = "KMS key for Neptune database encryption"
deletion_window_in_days = 10 # キーの削除をスケジュールするまでの日数
enable_key_rotation = true # キーの自動ローテーションを有効にする
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Sid = "Enable IAM User Permissions",
Effect = "Allow",
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" # アカウントルートユーザーにアクセス許可
},
Action = "kms:*",
Resource = "*"
},
{
Sid = "Allow Neptune Service to use the key"
Effect = "Allow",
Principal = {
Service = "rds.amazonaws.com" # NeptuneはRDSサービスプリンシパルを使用
},
Action = [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
Resource = "*"
}
]
})
tags = {
Name = "Neptune_CMK"
}
}
# (前提) VPC, サブネットグループ, セキュリティグループ
# NeptuneクラスターをデプロイするVPC, サブネットグループ, セキュリティグループを定義します
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "subnet_a" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "${data.aws_region.current.name}a"
}
resource "aws_subnet" "subnet_b" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "${data.aws_region.current.name}b"
}
resource "aws_neptune_subnet_group" "neptune_subnet_group" {
name = "my-neptune-subnet-group"
subnet_ids = [aws_subnet.subnet_a.id, aws_subnet.subnet_b.id]
}
resource "aws_security_group" "neptune_sg" {
name = "neptune-security-group"
description = "Security group for Neptune cluster"
vpc_id = aws_vpc.main.id
# Neptuneへのインバウンド接続を許可 (デフォルトポート 8182)
ingress {
from_port = 8182
to_port = 8182
protocol = "tcp"
cidr_blocks = [aws_vpc.main.cidr_block] # VPC内部からのアクセスを許可
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# Amazon Neptuneデータベースクラスター
resource "aws_neptune_cluster" "my_encrypted_neptune_cluster" {
cluster_identifier = "my-secure-neptune-cluster"
engine = "neptune"
engine_version = "1.2.0.0" # 利用可能なエンジンバージョンを指定
final_snapshot_identifier = "my-secure-neptune-final-snapshot"
skip_final_snapshot = false
db_subnet_group_name = aws_neptune_subnet_group.neptune_subnet_group.name
vpc_security_group_ids = [aws_security_group.neptune_sg.id]
port = 8182
# 暗号化を有効にし、KMS CMKを指定
storage_encrypted = true
kms_key_arn = aws_kms_key.neptune_cmk.arn
tags = {
Name = "MySecureNeptuneCluster"
Environment = "Production"
}
}
# Neptuneデータベースインスタンス (クラスターに紐付け)
resource "aws_neptune_cluster_instance" "my_neptune_instance" {
cluster_identifier = aws_neptune_cluster.my_encrypted_neptune_cluster.cluster_identifier
engine = "neptune"
instance_class = "db.t3.medium" # または db.r5.large など
publicly_accessible = false
apply_immediately = true
tags = {
Name = "MySecureNeptuneInstance"
}
}
# 現在のAWSアカウント情報とリージョンを取得
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
最後に
この記事では、Amazon NeptuneデータベースインスタンスのデータをKMSカスタマー管理キー(CMK)以上で暗号化することの重要性について解説しました。この設定は、グラフデータとそのストレージを保護し、厳格なセキュリティおよびコンプライアンス要件を満たすために不可欠です。CMKやCloudHSMキーを使用することで、鍵管理の制御を強化し、機密データの露出リスクを大幅に軽減できます。 貴社のNeptuneデータベースインスタンスは、カスタマー管理キー以上のレベルで暗号化されていますか?この機会にぜひ設定を確認・強化してみてください。 こちらの内容の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。運用が非常にラクに出来る製品になっていますのでぜひ興味がある方はお問い合わせお待ちしております。
最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。