コンテンツにスキップ

SSM Block Public Sharing

検証日: 2026-05-17 / リージョン: ap-northeast-1

カスタム SCP の説明

背景: SSM ドキュメントのパブリック共有と Block Public Sharing 設定

AWS Systems Manager(SSM)ドキュメントは、ssm:ModifyDocumentPermission API を使って他の AWS アカウントと共有できる。共有先に all を指定すると、世界中の任意の AWS アカウントから参照できるパブリック共有状態となる。SSM ドキュメントには Lambda 関数の値や API トークン等の機密情報が含まれていることがあり、誤ってパブリック共有された場合の影響は大きい。

これを防ぐため、SSM はアカウント・リージョン単位で Block Public Sharing(以下 BPA)という設定を提供している。BPA を有効化すると、ssm:ModifyDocumentPermissionall を指定する操作が API レベルで拒否され、新規のパブリック共有を防げる。

BPA 設定は SSM の Service Setting として管理されており、設定 ID は /ssm/documents/console/public-sharing-permission、設定値は Enable(パブリック共有を許可、つまり BPA 無効)または Disable(パブリック共有をブロック、つまり BPA 有効)の 2 値を取る(公式ドキュメント)。

設定値の名前と意味が反転している点に注意が必要。詳細は SSM.7 を参照。

Security Hub CSPM SSM.7 との関係

Security Hub CSPM の SSM.7 は、このアカウント・リージョン単位の BPA 設定が有効か(Disable になっているか)をチェックするコントロールである。AWS のデフォルトでは BPA は無効(Enable)であり、SSM.7 は新規アカウントで FAILED となる。

このカスタム SCP の役割

組織として「BPA を有効化した状態を維持したい」場合、メンバーアカウントの管理者が誤って(または意図的に)BPA を無効化する操作(update-service-setting --setting-value Enable)を防ぐ必要がある。Control Tower の標準予防コントロールには SSM BPA 設定変更を制御するものが存在しないため、カスタム SCP で対応する。

本記事のカスタム SCP は、ssm:UpdateServiceSetting API を SSM BPA 設定の ARN(servicesetting/ssm/documents/console/public-sharing-permission)に対して Deny する。これにより、メンバーアカウント側で SSM BPA 設定が変更(無効化)されることを防げる。

適用順序の注意

SSM.7 はデフォルトで FAILED(BPA 無効)の状態で開始するため、本 SCP を適用する前に各アカウント・各 Region で update-service-setting --setting-value Disable を実行して BPA を有効化しておく必要がある。

SCP を先に適用してしまうと、update-service-setting 自体が Deny されるため、BPA を有効化することができなくなる(FAILED のまま固定される)。本検証はこの「BPA 有効化 → SCP 適用」の正しい順序を前提とする。

SCP の内容

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenySSMDocumentPublicSharingChanges",
      "Effect": "Deny",
      "Action": [
        "ssm:UpdateServiceSetting"
      ],
      "Resource": "arn:aws:ssm:*:*:servicesetting/ssm/documents/console/public-sharing-permission"
    }
  ]
}

Resource で SSM Block Public Sharing 設定の ARN(servicesetting/ssm/documents/console/public-sharing-permission)に絞り込んでいるため、他の ssm:UpdateServiceSetting 操作(Parameter Store の高スループットモード切り替え等)には影響しない。

検証環境

検証環境の構成図

本記事のコマンドは、--profile 指定がない場合は Workload アカウントで実行する。Master アカウントでの操作には --profile Master を指定する。事前に export AWS_PROFILE=Workload でデフォルトを設定しておくと便利。

検証の流れ

    flowchart LR
    A[1. 事前準備<br>BPA 有効化<br>SSM.7 PASSED 確認] --> B[2. SCP 適用前<br>BPA 設定変更が成功]
    B --> C[3. BPA 再有効化]
    C --> D[4. SCP 作成]
    D --> E[5. OU にアタッチ]
    E --> F[6. BPA 設定変更が<br>Deny されることを確認]
    F --> G[7. 別の SSM 設定変更が<br>影響を受けないことを確認]
    G --> H[8. SCP デタッチ]
    H --> I[9. BPA 設定変更が再び成功<br>SSM.7 FAILED 復帰確認]
    I --> J[10. クリーンアップ]
  

結果

  • SCP 適用前は、メンバーアカウントの管理者が update-service-setting で SSM Block Public Sharing 設定を変更できることを確認できた
  • BPA 有効化後、Security Hub SSM.7 が PASSED になることを確認できた(検証の前提条件成立)
  • SCP 適用後、メンバーアカウントの管理者が SSM Block Public Sharing 設定を変更しようとすると AccessDeniedException で拒否されることを確認できた。エラーメッセージに explicit deny in a service control policy が含まれることから、SCP による拒否であることを確認できた
  • SCP の Resource で SSM Block Public Sharing 設定の ARN に絞り込んでいるため、他の ssm:UpdateServiceSetting 操作(Parameter Store の高スループットモード切り替え等)には影響しないことを確認できた
  • SCP デタッチ後は再び BPA 設定を変更できることを確認できた。Enable に戻した後 SSM.7 が FAILED に戻ることも確認した(検証中に SCP 以外の要因で SSM.7 が変動していないことの裏取り)

1. 事前準備(BPA 有効化)

SCP を適用する前に、Workload アカウントで SSM Block Public Sharing を有効化(Disable に設定)する。これを忘れると、SCP 適用後に有効化できなくなる。

現状確認

aws ssm get-service-setting \
  --setting-id /ssm/documents/console/public-sharing-permission \
  --query 'ServiceSetting.{SettingValue:SettingValue,Status:Status}' \
  --region ap-northeast-1
{
    "SettingValue": "Enable",
    "Status": "Default"
}

Enable の場合、Block Public Sharing は無効(パブリック共有を許可している状態)。Status は初期状態では Default、過去に手動変更された環境では Customized になる。いずれの場合も SettingValue: Enable であれば本検証の前提条件を満たす。

BPA を有効化(Disable に設定)

aws ssm update-service-setting \
  --setting-id /ssm/documents/console/public-sharing-permission \
  --setting-value Disable \
  --region ap-northeast-1
(出力なし)

設定値を確認

aws ssm get-service-setting \
  --setting-id /ssm/documents/console/public-sharing-permission \
  --query 'ServiceSetting.{SettingValue:SettingValue,Status:Status}' \
  --region ap-northeast-1
{
    "SettingValue": "Disable",
    "Status": "Customized"
}

SettingValue: DisableStatus: Customized であれば Block Public Sharing が有効化された状態。

Security Hub SSM.7 finding 確認(PASSED であること)

本検証の前提として「BPA 有効化済み = SSM.7 PASSED」が成立していることを確認する。Config ルールを手動トリガーして即座に評価させる。

まず Config ルール名のサフィックスを確認する。

aws configservice describe-config-rules \
  --query 'ConfigRules[?contains(ConfigRuleName,`ssm-automation-block-public-sharing`)].ConfigRuleName' \
  --output text \
  --region ap-northeast-1
securityhub-ssm-automation-block-public-sharing-<サフィックス>
aws configservice start-config-rules-evaluation \
  --config-rule-names securityhub-ssm-automation-block-public-sharing-<サフィックス> \
  --region ap-northeast-1
(出力なし)

1〜2 分待ってから評価結果を確認する。ResourceId はアカウント ID(数字のみ)のため、JMESPath フィルタではシングルクォートで囲む。

sleep 90
aws configservice get-compliance-details-by-config-rule \
  --config-rule-name securityhub-ssm-automation-block-public-sharing-<サフィックス> \
  --query "EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId=='<アカウント ID>'].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType,ResultRecordedTime:ResultRecordedTime}" \
  --region ap-northeast-1
[
    {
        "ResourceId": "<アカウント ID>",
        "ComplianceType": "COMPLIANT",
        "ResultRecordedTime": "<評価時刻>"
    }
]

Security Hub への反映を待ってから finding を確認する。

sleep 120
aws securityhub get-findings \
  --filters '{
    "ComplianceSecurityControlId": [{"Comparison": "EQUALS", "Value": "SSM.7"}],
    "AwsAccountId": [{"Comparison": "EQUALS", "Value": "<アカウント ID>"}],
    "ResourceId": [{"Comparison": "EQUALS", "Value": "AWS::::Account:<アカウント ID>"}],
    "RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}]
  }' \
  --query 'Findings[].{Status:Compliance.Status,ResourceId:Resources[0].Id,UpdatedAt:UpdatedAt}' \
  --region ap-northeast-1
[
    {
        "Status": "PASSED",
        "ResourceId": "AWS::::Account:<アカウント ID>",
        "UpdatedAt": "<更新時刻>"
    }
]

SSM.7 が PASSED であることを確認できた。古い finding が残っている場合は複数件返ることがあるが、最新の UpdatedAt のものが現在の状態を示す。これで検証の前提条件が成立した。

2. SCP 適用前のベースライン確認

メンバーアカウントの管理者として、BPA 設定が変更可能であることを確認する。一度 Enable に戻して、再度 Disable に設定し直す。

Enable に変更

aws ssm update-service-setting \
  --setting-id /ssm/documents/console/public-sharing-permission \
  --setting-value Enable \
  --region ap-northeast-1
(出力なし)

設定値を確認

aws ssm get-service-setting \
  --setting-id /ssm/documents/console/public-sharing-permission \
  --query 'ServiceSetting.{SettingValue:SettingValue,Status:Status}' \
  --region ap-northeast-1
{
    "SettingValue": "Enable",
    "Status": "Customized"
}

SCP 適用前は変更が成功する。

3. BPA 再有効化

SCP 適用後に BPA を有効化できなくなるため、ここで再度 Disable に戻す。

aws ssm update-service-setting \
  --setting-id /ssm/documents/console/public-sharing-permission \
  --setting-value Disable \
  --region ap-northeast-1
(出力なし)
aws ssm get-service-setting \
  --setting-id /ssm/documents/console/public-sharing-permission \
  --query 'ServiceSetting.{SettingValue:SettingValue,Status:Status}' \
  --region ap-northeast-1
{
    "SettingValue": "Disable",
    "Status": "Customized"
}

4. カスタム SCP 作成

Master アカウントで SCP を作成する。

ポリシー JSON ファイル作成

cat > /tmp/scp-ssm-block-public-sharing.json <<'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenySSMDocumentPublicSharingChanges",
      "Effect": "Deny",
      "Action": [
        "ssm:UpdateServiceSetting"
      ],
      "Resource": "arn:aws:ssm:*:*:servicesetting/ssm/documents/console/public-sharing-permission"
    }
  ]
}
EOF

SCP 作成

aws organizations create-policy \
  --name DenySSMBlockPublicSharingChanges \
  --description "Deny changes to SSM Block Public Sharing setting" \
  --type SERVICE_CONTROL_POLICY \
  --content file:///tmp/scp-ssm-block-public-sharing.json \
  --query 'Policy.PolicySummary.{Id:Id,Name:Name,Type:Type}' \
  --profile Master
{
    "Id": "<ポリシー ID>",
    "Name": "DenySSMBlockPublicSharingChanges",
    "Type": "SERVICE_CONTROL_POLICY"
}

5. OU にアタッチ

Workload アカウントが所属する OU に SCP をアタッチする。

aws organizations attach-policy \
  --policy-id <ポリシー ID> \
  --target-id <OU ID> \
  --profile Master
(出力なし)

アタッチを確認

aws organizations list-policies-for-target \
  --target-id <OU ID> \
  --filter SERVICE_CONTROL_POLICY \
  --query 'Policies[?Name==`DenySSMBlockPublicSharingChanges`]' \
  --profile Master
[
    {
        "Id": "<ポリシー ID>",
        "Arn": "arn:aws:organizations::<Master アカウント ID>:policy/o-<組織 ID>/service_control_policy/<ポリシー ID>",
        "Name": "DenySSMBlockPublicSharingChanges",
        "Description": "Deny changes to SSM Block Public Sharing setting",
        "Type": "SERVICE_CONTROL_POLICY",
        "AwsManaged": false
    }
]

SCP の適用には数秒〜数十秒のラグがある。

6. BPA 設定変更が Deny されることを確認

Workload アカウントから BPA 設定を変更しようとして、Deny されることを確認する。

Enable に戻そうとする → Deny

aws ssm update-service-setting \
  --setting-id /ssm/documents/console/public-sharing-permission \
  --setting-value Enable \
  --region ap-northeast-1 2>&1
An error occurred (AccessDeniedException) when calling the UpdateServiceSetting operation: User: arn:aws:sts::<Workload アカウント ID>:assumed-role/<ロール名>/<セッション名> is not authorized to perform: ssm:UpdateServiceSetting on resource: arn:aws:ssm:ap-northeast-1:<Workload アカウント ID>:servicesetting/ssm/documents/console/public-sharing-permission with an explicit deny in a service control policy: arn:aws:organizations::<Master アカウント ID>:policy/o-<組織 ID>/service_control_policy/<ポリシー ID>

explicit deny in a service control policy というメッセージが含まれることから、SCP による拒否であることを確認できる。

設定値が変わっていないことを確認

aws ssm get-service-setting \
  --setting-id /ssm/documents/console/public-sharing-permission \
  --query 'ServiceSetting.{SettingValue:SettingValue,Status:Status}' \
  --region ap-northeast-1
{
    "SettingValue": "Disable",
    "Status": "Customized"
}

設定値は Disable のまま維持されている。

7. 別の SSM 設定変更が影響を受けないことを確認

SCP の Resource で SSM Block Public Sharing 設定の ARN に絞り込んでいるため、他の ssm:UpdateServiceSetting 操作には影響しないことを確認する。Parameter Store の高スループットモード設定(/ssm/parameter-store/high-throughput-enabled)を例に試す。

現状確認

aws ssm get-service-setting \
  --setting-id /ssm/parameter-store/high-throughput-enabled \
  --query 'ServiceSetting.{SettingValue:SettingValue,Status:Status}' \
  --region ap-northeast-1
{
    "SettingValue": "false",
    "Status": "Default"
}

true に変更(SCP に阻まれず成功するはず)

aws ssm update-service-setting \
  --setting-id /ssm/parameter-store/high-throughput-enabled \
  --setting-value true \
  --region ap-northeast-1
(出力なし)

設定値を確認

aws ssm get-service-setting \
  --setting-id /ssm/parameter-store/high-throughput-enabled \
  --query 'ServiceSetting.{SettingValue:SettingValue,Status:Status}' \
  --region ap-northeast-1
{
    "SettingValue": "true",
    "Status": "Customized"
}

SCP の対象外であるため変更が成功する。

元に戻す

aws ssm update-service-setting \
  --setting-id /ssm/parameter-store/high-throughput-enabled \
  --setting-value false \
  --region ap-northeast-1
(出力なし)

8. SCP デタッチ

aws organizations detach-policy \
  --policy-id <ポリシー ID> \
  --target-id <OU ID> \
  --profile Master
(出力なし)

9. BPA 設定変更が再び成功することを確認

aws ssm update-service-setting \
  --setting-id /ssm/documents/console/public-sharing-permission \
  --setting-value Enable \
  --region ap-northeast-1
(出力なし)
aws ssm get-service-setting \
  --setting-id /ssm/documents/console/public-sharing-permission \
  --query 'ServiceSetting.{SettingValue:SettingValue,Status:Status}' \
  --region ap-northeast-1
{
    "SettingValue": "Enable",
    "Status": "Customized"
}

SCP デタッチ後は再び設定変更ができる。SCP のデタッチには数分のラグがある場合があるため、Deny が続く場合は数分待ってから再試行する。

Security Hub SSM.7 finding 確認(FAILED に戻ること)

Enable(BPA 無効)に戻したので、SSM.7 は FAILED に戻るはず。これを確認することで、検証中に SCP 以外の何かが SSM.7 の評価に影響していないことの証明になる。

aws configservice start-config-rules-evaluation \
  --config-rule-names securityhub-ssm-automation-block-public-sharing-<サフィックス> \
  --region ap-northeast-1
(出力なし)
sleep 90
aws configservice get-compliance-details-by-config-rule \
  --config-rule-name securityhub-ssm-automation-block-public-sharing-<サフィックス> \
  --query "EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId=='<アカウント ID>'].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType,ResultRecordedTime:ResultRecordedTime}" \
  --region ap-northeast-1
[
    {
        "ResourceId": "<アカウント ID>",
        "ComplianceType": "NON_COMPLIANT",
        "ResultRecordedTime": "<評価時刻>"
    }
]
sleep 120
aws securityhub get-findings \
  --filters '{
    "ComplianceSecurityControlId": [{"Comparison": "EQUALS", "Value": "SSM.7"}],
    "AwsAccountId": [{"Comparison": "EQUALS", "Value": "<アカウント ID>"}],
    "ResourceId": [{"Comparison": "EQUALS", "Value": "AWS::::Account:<アカウント ID>"}],
    "RecordState": [{"Comparison": "EQUALS", "Value": "ACTIVE"}]
  }' \
  --query 'Findings[].{Status:Compliance.Status,ResourceId:Resources[0].Id,UpdatedAt:UpdatedAt}' \
  --region ap-northeast-1
[
    {
        "Status": "FAILED",
        "ResourceId": "AWS::::Account:<アカウント ID>",
        "UpdatedAt": "<更新時刻>"
    }
]

SSM.7 が FAILED に戻った。SCP の効果が解除され、想定通りの状態になっていることを確認できた。

10. クリーンアップ

SCP 削除

aws organizations delete-policy \
  --policy-id <ポリシー ID> \
  --profile Master
(出力なし)

BPA 設定を Disable に戻す(任意)

検証で Enable に変更した SSM Block Public Sharing 設定を、本番環境で運用するつもりであれば Disable に戻しておく。

aws ssm update-service-setting \
  --setting-id /ssm/documents/console/public-sharing-permission \
  --setting-value Disable \
  --region ap-northeast-1
(出力なし)

Amazonアソシエイトリンク