Secrets Manager シークレット
概要
IAM Access Analyzer が Secrets Manager シークレットの外部アクセスをどのように検出するかを検証する。
Secrets Manager シークレットはリソースポリシーにより外部プリンシパルへのアクセスを許可できる。デフォルトではリソースポリシーが存在せず、明示的に設定しない限り外部アクセスは発生しない。リソースポリシーに Principal: "*" を設定するとパブリックアクセスとして検出され、特定の外部アカウントを設定するとクロスアカウントアクセスとして検出される。
Secrets Manager シークレットの外部アクセス制御レイヤー
| レイヤー | Secrets Manager の状況 |
|---|---|
| デフォルト保護 | なし(リソースポリシーがデフォルトで空) |
| 予防(RCP) | CT.SECRETSMANAGER.PV.1(組織外プリンシパルによるアクセスを拒否) |
| Security Hub CSPM | 外部アクセスチェックなし(暗号化チェックのみ) |
| IAM Access Analyzer | パブリック + クロスアカウントの到達可能性を分析 |
結果
- デフォルトのリソースポリシー: Secrets Manager シークレットはデフォルトではリソースポリシーが存在しない。明示的に設定しない限り外部アクセスは発生しない
- パブリックアクセスの検出: リソースポリシーに
Principal: "*"を設定すると、isPublic: trueの finding が生成された - クロスアカウントアクセスの検出: 組織外アカウントをリソースポリシーに設定すると、
isPublic: falseの finding が生成された。principal に組織外アカウント ID が特定された - action の到達可能性分析: ポリシーでは
GetSecretValueとDescribeSecretの両方を許可したが、finding の action はDescribeSecretのみ。デフォルトの AWS マネージド KMS キーではクロスアカウントの復号ができないことから、IAM Access Analyzer がGetSecretValueを到達不可能と判定した可能性がある - 予防コントロール(CT.SECRETSMANAGER.PV.1)との連動: RCP 有効時は組織外からの DescribeSecret がパブリック・クロスアカウントの両方でブロックされた。再スキャン後、
resourceControlPolicyRestrictionがAPPLICABLEに変わった - クリーンアップ: リソースポリシーを削除すると finding は RESOLVED になる
検証環境
本記事のコマンドは、--profile 指定がない場合は Workload アカウントで実行する。IAM Access Analyzer の finding 確認は Audit アカウントで実行する。
検証の流れ
flowchart LR
A[1. 既存 finding の<br>確認] --> B[2. テスト用シークレット<br>作成]
B --> C[3. パブリックアクセス<br>検出の確認]
C --> D[4. クロスアカウント<br>アクセス検出]
D --> E[5. 予防コントロール<br>との連動]
E --> F[6. クリーンアップ]
1. 既存 finding の確認
テスト用シークレットを作成する前に、既存の Secrets Manager finding を確認する。
デフォルトのリソースポリシーの確認
Secrets Manager シークレットはデフォルトではリソースポリシーが存在しない。
aws secretsmanager get-resource-policy \
--secret-id <任意の既存シークレット名>{
"ARN": "arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:<シークレット名>-<サフィックス>",
"Name": "<シークレット名>"
}ResourcePolicy フィールドが返らない場合、リソースポリシーは設定されていない。
既存 finding の確認
aws accessanalyzer list-findings-v2 \
--analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
--filter '{"status": {"eq": ["ACTIVE"]}, "resourceType": {"eq": ["AWS::SecretsManager::Secret"]}}' \
--query 'findings[].{id:id,resource:resource,status:status}' \
--region ap-northeast-1 \
--profile Audit[]2. テスト用シークレットの作成
2 つのテスト用シークレットを作成し、リソースポリシーで外部アクセスを設定する。
パブリックアクセス検証用シークレット
aws secretsmanager create-secret \
--name iaa-sm-public-test \
--secret-string "test-value"{
"Name": "iaa-sm-public-test",
"ARN": "arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-public-test-<サフィックス>"
}リソースポリシーに Principal: "*" を設定する。
aws secretsmanager put-resource-policy \
--secret-id iaa-sm-public-test \
--resource-policy '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPublic",
"Effect": "Allow",
"Principal": "*",
"Action": ["secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret"],
"Resource": "*"
}
]
}'クロスアカウントアクセス検証用シークレット
aws secretsmanager create-secret \
--name iaa-sm-crossaccount-test \
--secret-string "test-value"{
"Name": "iaa-sm-crossaccount-test",
"ARN": "arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-crossaccount-test-<サフィックス>"
}リソースポリシーに組織外アカウントを設定する。
aws secretsmanager put-resource-policy \
--secret-id iaa-sm-crossaccount-test \
--resource-policy '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccount",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::<組織外アカウント ID>:root"},
"Action": ["secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret"],
"Resource": "*"
}
]
}'3. パブリックアクセスの検出
パブリックアクセス検証用シークレット(Principal: "*")の finding を確認する。
aws accessanalyzer list-findings-v2 \
--analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
--filter '{"status": {"eq": ["ACTIVE"]}, "resource": {"contains": ["iaa-sm-public-test"]}}' \
--query 'findings[].{id:id,resource:resource,resourceType:resourceType,status:status}' \
--region ap-northeast-1 \
--profile Audit[
{
"id": "<パブリックシークレット finding ID>",
"resource": "arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-public-test-<サフィックス>",
"resourceType": "AWS::SecretsManager::Secret",
"status": "ACTIVE"
}
]finding の詳細を確認する。
aws accessanalyzer get-finding-v2 \
--analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
--id <パブリックシークレット finding ID> \
--region ap-northeast-1 \
--profile Audit{
"findingDetails": [
{
"externalAccessDetails": {
"action": ["secretsmanager:DescribeSecret"],
"condition": {},
"isPublic": true,
"principal": {"AWS": "*"},
"resourceControlPolicyRestriction": "NOT_APPLICABLE"
}
}
],
"resource": "arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-public-test-<サフィックス>",
"status": "ACTIVE",
"resourceType": "AWS::SecretsManager::Secret",
"findingType": "ExternalAccess",
"resourceOwnerAccount": "<Workload アカウント ID>",
"id": "<パブリックシークレット finding ID>"
}以下を確認する。
isPublicがtrueprincipalが{"AWS": "*"}actionがsecretsmanager:DescribeSecret(GetSecretValueは含まれない)resourceControlPolicyRestrictionがNOT_APPLICABLE
secretsmanager:GetSecretValue も許可しているが、finding の action には secretsmanager:DescribeSecret のみが表示される。シークレットがデフォルトの AWS マネージド KMS キー(aws/secretsmanager)で暗号化されており、このキーはクロスアカウントでの復号に使用できないことから、IAM Access Analyzer が GetSecretValue を到達不可能と判定した可能性がある。組織外アカウントからの実際のアクセス確認
組織外アカウントからパブリックシークレットへの DescribeSecret が成功することを確認する。
aws secretsmanager describe-secret \
--secret-id arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-public-test-<サフィックス> \
--query '{Name:Name,ARN:ARN}' \
--profile <組織外プロファイル> \
--region ap-northeast-1{
"Name": "iaa-sm-public-test",
"ARN": "arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-public-test-<サフィックス>"
}GetSecretValue はデフォルト KMS キーの制約により失敗する。
aws secretsmanager get-secret-value \
--secret-id arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-public-test-<サフィックス> \
--profile <組織外プロファイル> \
--region ap-northeast-1An error occurred (InvalidRequestException) when calling the GetSecretValue operation: You can't access a secret from a different AWS account if you encrypt the secret with the default KMS service key.4. クロスアカウントアクセスの検出
クロスアカウントアクセス検証用シークレットの finding を確認する。
aws accessanalyzer list-findings-v2 \
--analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
--filter '{"status": {"eq": ["ACTIVE"]}, "resource": {"contains": ["iaa-sm-crossaccount-test"]}}' \
--query 'findings[].{id:id,resource:resource,resourceType:resourceType,status:status}' \
--region ap-northeast-1 \
--profile Audit[
{
"id": "<クロスアカウントシークレット finding ID>",
"resource": "arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-crossaccount-test-<サフィックス>",
"resourceType": "AWS::SecretsManager::Secret",
"status": "ACTIVE"
}
]finding の詳細を確認する。
aws accessanalyzer get-finding-v2 \
--analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
--id <クロスアカウントシークレット finding ID> \
--region ap-northeast-1 \
--profile Audit{
"findingDetails": [
{
"externalAccessDetails": {
"action": ["secretsmanager:DescribeSecret"],
"condition": {},
"isPublic": false,
"principal": {"AWS": "<組織外アカウント ID>"},
"resourceControlPolicyRestriction": "NOT_APPLICABLE"
}
}
],
"resource": "arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-crossaccount-test-<サフィックス>",
"status": "ACTIVE",
"resourceType": "AWS::SecretsManager::Secret",
"findingType": "ExternalAccess",
"resourceOwnerAccount": "<Workload アカウント ID>",
"id": "<クロスアカウントシークレット finding ID>"
}以下を確認する。
isPublicがfalseprincipalに組織外アカウント ID が特定されているactionがsecretsmanager:DescribeSecretresourceControlPolicyRestrictionがNOT_APPLICABLE
組織外アカウントからの実際のアクセス確認
組織外アカウントからクロスアカウントシークレットへの DescribeSecret が成功することを確認する。
aws secretsmanager describe-secret \
--secret-id arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-crossaccount-test-<サフィックス> \
--query '{Name:Name,ARN:ARN}' \
--profile <組織外プロファイル> \
--region ap-northeast-1{
"Name": "iaa-sm-crossaccount-test",
"ARN": "arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-crossaccount-test-<サフィックス>"
}5. 予防コントロール(CT.SECRETSMANAGER.PV.1)との連動
CT.SECRETSMANAGER.PV.1 の有効化確認
CT.SECRETSMANAGER.PV.1 が有効であることを確認する。
aws controltower list-enabled-controls \
--target-identifier <対象 OU ARN> \
--query "enabledControls[?controlIdentifier=='arn:aws:controlcatalog:::control/dvhe47fxg5o6lryqrq9g6sxg4'].{controlIdentifier:controlIdentifier,statusSummary:statusSummary}" \
--profile Master[]無効の場合は有効化する。
aws controltower enable-control \
--control-identifier arn:aws:controlcatalog:::control/dvhe47fxg5o6lryqrq9g6sxg4 \
--target-identifier <対象 OU ARN> \
--profile Master{
"operationIdentifier": "<オペレーション ID>"
}組織外アカウントからのアクセス確認
CT.SECRETSMANAGER.PV.1 が有効な状態で、組織外アカウントからクロスアカウントシークレットへの DescribeSecret を試み、RCP によりブロックされることを確認する。
aws secretsmanager describe-secret \
--secret-id arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-crossaccount-test-<サフィックス> \
--profile <組織外プロファイル> \
--region ap-northeast-1An error occurred (AccessDeniedException) when calling the DescribeSecret operation: User: arn:aws:iam::<組織外アカウント ID>:user/<組織外ユーザー名> is not authorized to perform: secretsmanager:DescribeSecret on resource: arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-crossaccount-test-<サフィックス> with an explicit deny in a resource control policyパブリックシークレットへの DescribeSecret も同様にブロックされることを確認する。
aws secretsmanager describe-secret \
--secret-id arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-public-test-<サフィックス> \
--profile <組織外プロファイル> \
--region ap-northeast-1An error occurred (AccessDeniedException) when calling the DescribeSecret operation: User: arn:aws:iam::<組織外アカウント ID>:user/<組織外ユーザー名> is not authorized to perform: secretsmanager:DescribeSecret on resource: arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-public-test-<サフィックス> with an explicit deny in a resource control policyresourceControlPolicyRestriction の確認
リソースの再スキャンを実行して、RCP の反映を確認する。再スキャンにより旧 finding は RESOLVED になり、新しい finding ID で再生成される。
aws accessanalyzer start-resource-scan \
--analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
--resource-arn arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-crossaccount-test-<サフィックス> \
--resource-owner-account <Workload アカウント ID> \
--region ap-northeast-1 \
--profile Audit
(出力なし)パブリックシークレットも再スキャンする。
aws accessanalyzer start-resource-scan \
--analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
--resource-arn arn:aws:secretsmanager:ap-northeast-1:<Workload アカウント ID>:secret:iaa-sm-public-test-<サフィックス> \
--resource-owner-account <Workload アカウント ID> \
--region ap-northeast-1 \
--profile Audit
(出力なし)再スキャン後の finding 一覧を確認する。
aws accessanalyzer list-findings-v2 \
--analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
--filter '{"status": {"eq": ["ACTIVE"]}, "resourceType": {"eq": ["AWS::SecretsManager::Secret"]}}' \
--query 'findings[].{id:id,status:status}' \
--region ap-northeast-1 \
--profile Audit[
{
"id": "<新クロスアカウントシークレット finding ID>",
"status": "ACTIVE"
},
{
"id": "<新パブリックシークレット finding ID>",
"status": "ACTIVE"
}
]finding 詳細を確認し、resourceControlPolicyRestriction が APPLICABLE に変わっていることを確認する。
aws accessanalyzer get-finding-v2 \
--analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
--id <新クロスアカウントシークレット finding ID> \
--region ap-northeast-1 \
--profile Audit{
"findingDetails": [
{
"externalAccessDetails": {
"action": ["secretsmanager:DescribeSecret"],
"isPublic": false,
"principal": {"AWS": "<組織外アカウント ID>"},
"resourceControlPolicyRestriction": "APPLICABLE"
}
}
],
"status": "ACTIVE",
"id": "<新クロスアカウントシークレット finding ID>"
}aws accessanalyzer get-finding-v2 \
--analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
--id <新パブリックシークレット finding ID> \
--region ap-northeast-1 \
--profile Audit{
"findingDetails": [
{
"externalAccessDetails": {
"action": ["secretsmanager:DescribeSecret"],
"isPublic": true,
"principal": {"AWS": "*"},
"resourceControlPolicyRestriction": "APPLICABLE"
}
}
],
"status": "ACTIVE",
"id": "<新パブリックシークレット finding ID>"
}6. クリーンアップ
CT.SECRETSMANAGER.PV.1 の無効化
aws controltower disable-control \
--control-identifier arn:aws:controlcatalog:::control/dvhe47fxg5o6lryqrq9g6sxg4 \
--target-identifier <対象 OU ARN> \
--profile Master{
"operationIdentifier": "<オペレーション ID>"
}リソースポリシーの削除
aws secretsmanager delete-resource-policy \
--secret-id iaa-sm-public-test
(出力なし)aws secretsmanager delete-resource-policy \
--secret-id iaa-sm-crossaccount-test
(出力なし)finding の確認
リソースポリシー削除後、finding が RESOLVED になることを確認する。
aws accessanalyzer list-findings-v2 \
--analyzer-arn arn:aws:access-analyzer:ap-northeast-1:<Audit アカウント ID>:analyzer/org-access-analyzer \
--filter '{"resourceType": {"eq": ["AWS::SecretsManager::Secret"]}}' \
--query 'findings[].{id:id,resource:resource,status:status}' \
--region ap-northeast-1 \
--profile Audit[]テスト用シークレットの削除
aws secretsmanager delete-secret \
--secret-id iaa-sm-public-test \
--force-delete-without-recovery
(出力なし)aws secretsmanager delete-secret \
--secret-id iaa-sm-crossaccount-test \
--force-delete-without-recovery
(出力なし)