Skip to content

SCP(Service Control Policy)設計書


1. 目的・スコープ

目的

SCPにより、Organization全体にガードレール(大枠の制限)を適用し、セキュリティサービスの保護・リージョン制限・データ保護等を構造的に強制する。

スコープ

  • 本設計書はSCP①〜④の詳細設計、delegation policy、評価ルール、運用ルールを定義する
  • OU構造・アカウント配置についてはOU・アカウント設計書を参照

2. SCP評価の基本ルール

採用する戦略: Deny-list(拒否リスト)

Deny-list戦略:
  ・FullAWSAccessで全サービスを許可した上で、危険な操作だけをDenyする
  ・新しいAWSサービスが追加された場合、自動的に利用可能(運用負荷が低い)

Allow-list戦略(採用しない):
  ・許可するサービスを明示的にリストする
  ・新しいAWSサービスはデフォルトでブロックされる
  ・全サービスを把握・更新するコストが高い
  ・管理者の誤設定で一度に崩壊するリスク

Allowの評価ルール

アカウントに対してあるアクションが「許可」されるためには、
Root → OU → アカウント の全階層でAllowが必要。

  Root: FullAWSAccess(Allow *) ← 必須。外すと全アカウントが使えなくなる

  OU: FullAWSAccessが継承される

  アカウント: FullAWSAccessが継承される

  → どこか1つでもAllowが欠けると、そのアクションは拒否される

  ⚠️ FullAWSAccessは絶対に外さないこと。
     外す場合は代わりのAllowポリシーを必ず先にアタッチする。

Denyの評価ルール

Root → OU → アカウント のどこか1つでもDenyがあれば、そのアクションは拒否される。
他の階層でAllowしていてもDenyが優先される。

例:
  Root: Deny organizations:LeaveOrganization
  OU: (何もなし)
  アカウント: (何もなし)
  → 全メンバーアカウントで LeaveOrganization が拒否される

  Root: (何もなし)
  Production OU: Deny s3:DeleteAccountPublicAccessBlock(削除のみブロック)
  アカウント: (何もなし)
  → Production OU配下のアカウントのみで拒否される

SCPの制限事項

SCPで制限できないもの:
  ・マネジメントアカウント(703480710002)の操作 → SCPは効かない
  ・サービスリンクロールの操作
  ・一部のAWSサービス(Lightsail DNS、Mechanical Turk等)

SCPのサイズ上限:
  ・1つのSCPにつき最大10,240文字(空白含む)
  ・1つのOU/アカウントに最大10個のSCPをアタッチ可能

SCPの適用範囲:
  ・IAMユーザー、IAMロールに対して適用される
  ・SCPはアクセスを「付与」しない。あくまで「上限」を設定するだけ
  ・実際のアクセス権はIAMポリシーで付与する必要がある(多層防御)

3. 既存SCPの分析

現在適用されているSCP

SCP適用先種別
FullAWSAccessRootAWS管理ポリシー
ECAM_Partnerled_base_policy_20241022RootMZ作成のカスタムポリシー

ECAM_Partnerled_base_policy の内容

SidEffect対象アクション目的
billandorgblockDenyce:, tax:, purchase-orders:*, organizations:LeaveOrganization請求/コスト操作の制限 + Organization離脱防止。ただしrootユーザーは除外されている
CURDeleteBlockDenycur:DeleteReportDefinitionCURレポート削除禁止
roleblockDenysts:AssumeRole, iam:RoleMZサポートロール(mz_support1/2)の改変保護
AssumeRoleDenysts:AssumeRoleMZサポートロールへのAssumeRoleをMZ特定アカウントからのみに制限
SupportblockDenysupport:*AWSサポートアクセスをMZサポートロールに限定

新規SCPとの競合確認

【競合なし】
  ・新規SCPは全てDeny文。既存SCPのDeny文と対象アクションが重複しない
  ・既存SCPのbillandorgblock にLeaveOrganization Denyがあるが、
    rootが除外されている → SCP③で補完する(競合ではなく補完)

【注意点】
  ・FullAWSAccessはRootに適用されたまま残す(外さない)
  ・既存SCPのSupportblockにより、FDからAWSサポートに問い合わせ不可(既存の制約)

4. Delegation Policy

目的

SCP管理をfd-security-tooling(860801568046)に委任し、マネジメントアカウントへのログインなしでSCPを管理できるようにする。

設定場所

マネジメントアカウント(703480710002)で手動設定(1回限り)。

JSON定義

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DelegateSCPManagementReadOnly",
      "Effect": "Allow",
      "Principal": {
        "AWS": "860801568046"
      },
      "Action": [
        "organizations:DescribeOrganization",
        "organizations:ListAccounts",
        "organizations:ListRoots",
        "organizations:ListOrganizationalUnitsForParent",
        "organizations:ListAccountsForParent",
        "organizations:ListChildren",
        "organizations:ListParents",
        "organizations:DescribeOrganizationalUnit",
        "organizations:DescribeAccount",
        "organizations:DescribeEffectivePolicy",
        "organizations:ListDelegatedAdministrators",
        "organizations:ListDelegatedServicesForAccount",
        "organizations:DescribePolicy",
        "organizations:ListPolicies",
        "organizations:ListPoliciesForTarget",
        "organizations:ListTargetsForPolicy",
        "organizations:ListTagsForResource"
      ],
      "Resource": "*"
    },
    {
      "Sid": "DelegateSCPManagementPolicyActions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "860801568046"
      },
      "Action": [
        "organizations:CreatePolicy",
        "organizations:UpdatePolicy",
        "organizations:DeletePolicy",
        "organizations:AttachPolicy",
        "organizations:DetachPolicy",
        "organizations:TagResource",
        "organizations:UntagResource"
      ],
      "Resource": [
        "arn:aws:organizations::703480710002:root/o-ukenxj5eo4/r-8z8v",
        "arn:aws:organizations::703480710002:ou/o-ukenxj5eo4/*",
        "arn:aws:organizations::703480710002:account/o-ukenxj5eo4/*",
        "arn:aws:organizations::703480710002:policy/o-ukenxj5eo4/service_control_policy/*"
      ],
      "Condition": {
        "StringLikeIfExists": {
          "organizations:PolicyType": "SERVICE_CONTROL_POLICY"
        }
      }
    }
  ]
}

Statementを2つに分離している理由: 読み取り系アクション(Describe*, List*)は organizations:PolicyType Conditionキーをサポートしていないため、Conditionなし・Resource: "*" で定義する必要がある。書き込み系アクション(Create/Update/Delete/Attach/Detach/Tag/Untag)のみCondition付きで制限する。

アクション選定理由

カテゴリアクション用途
読み取り(ReadOnly Statement)DescribeOrganization, ListAccounts, ListRoots, ListChildren, ListOrganizationalUnitsForParent, ListAccountsForParent, ListParents, DescribeOrganizationalUnit, DescribeAccount, DescribeEffectivePolicy, ListDelegatedAdministrators, ListDelegatedServicesForAccount, DescribePolicy, ListPolicies, ListPoliciesForTarget, ListTargetsForPolicy, ListTagsForResourceTerraformがplan時にOrganizationの構造・SCP設定・委任状況を読み取るために必要。Conditionキー非対応のためResource: "*"で定義
SCP操作(PolicyActions Statement)CreatePolicy, UpdatePolicy, DeletePolicy, AttachPolicy, DetachPolicy, TagResource, UntagResourceSCPの作成・変更・削除・適用・解除・タグ操作。Condition付きでSCPのみに制限

意図的に除外したアクション

アクション除外理由
EnablePolicyType / DisablePolicyTypeSCPの有効化/無効化はマネジメントアカウントで手動で行うべき
DescribeHandshake / ListHandshakes系アカウント招待操作。SCP管理に不要
CreateAccountStatus系アカウント作成操作。SCP管理に不要

Conditionの制限

"organizations:PolicyType": "SERVICE_CONTROL_POLICY"

→ SCPのみに限定。RCP, Tag Policy, Backup Policy等は操作不可。
→ 将来RCP等も委任する場合はこのConditionにPolicyTypeを追加する。

設定手順

1. マネジメントアカウント(703480710002)でAWSコンソールにログイン
2. AWS Organizationsコンソール → 「設定」
3. 「Delegated administrator for AWS Organizations」セクション → 「Delegate」
4. 上記JSONを貼り付け → 「Create policy」

確認:
  fd-security-toolingから以下を実行して既存SCPが表示されること:
  aws organizations list-policies --filter SERVICE_CONTROL_POLICY --profile fd-security --region us-east-1

5. SCP詳細設計

SCP適用マトリクス

SCP適用先影響範囲
FullAWSAccess(既存)Root全アカウント
ECAM_Partnerled_base_policy(既存)Root全アカウント
SCP① セキュリティ保護Root全アカウント
SCP③ LeaveOrg禁止Root全アカウント
SCP② リージョン制限Infrastructure, Production, Non-Production, SandboxSecurity OU以外の全アカウント
SCP④ 本番データ保護Production本番アカウントのみ

Rootに適用するSCP(①③)はMZ管理アカウントにも影響する。適用前にMZとコミュニケーションを取ること。

SCP①: セキュリティサービス保護 + rootアクセスキー作成禁止

適用先: Root(全メンバーアカウント)
目的: セキュリティサービスの無効化防止、メンバーアカウントのrootアクセスキー作成禁止
json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyDisableSecurityServices",
      "Effect": "Deny",
      "Action": [
        "cloudtrail:StopLogging",
        "cloudtrail:DeleteTrail",
        "guardduty:DeleteDetector",
        "guardduty:DisassociateFromAdministratorAccount",
        "securityhub:DisableSecurityHub",
        "config:StopConfigurationRecorder",
        "config:DeleteConfigurationRecorder",
        "config:DeleteDeliveryChannel",
        "inspector2:Disable",
        "access-analyzer:DeleteAnalyzer",
        "macie2:DisableMacie",
        "detective:DeleteGraph"
      ],
      "Resource": "*"
    },
    {
      "Sid": "DenyRootAccessKeys",
      "Effect": "Deny",
      "Action": [
        "iam:CreateAccessKey",
        "iam:UpdateAccessKey"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "aws:PrincipalArn": "arn:aws:iam::*:root"
        }
      }
    }
  ]
}
影響分析:
  ・CloudTrail/GuardDuty/Security Hub/Config/Inspector/Access Analyzer/Macie/Detective
    の削除・停止・無効化が全メンバーアカウントで不可になる
  ・メンバーアカウントのrootユーザーがアクセスキーを作成できなくなる
  ・通常のワークロード操作(EC2, S3, ECS等)には影響なし

  ⚠️ cloudtrail:DeleteTrail を含むため、個別CloudTrailの削除時は
     SCPを一時的にデタッチしてから実施すること(Phase 3-4参照)

既存SCPとの競合: なし

SCP②: リージョン制限

適用先: Infrastructure, Production, Non-Production, Sandbox
目的: 許可リージョン以外でのリソース作成を禁止(攻撃の爆発半径を限定)
Security OUには適用しない(セキュリティサービスが複数リージョンで動作するため)
json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyNonApprovedRegions",
      "Effect": "Deny",
      "NotAction": [
        "a4b:*",
        "acm:*",
        "aws-marketplace-management:*",
        "aws-marketplace:*",
        "aws-portal:*",
        "bedrock:*",
        "bedrock-agentcore:*",
        "budgets:*",
        "ce:*",
        "cloudfront:*",
        "cur:*",
        "globalaccelerator:*",
        "health:*",
        "iam:*",
        "importexport:*",
        "kms:*",
        "networkmanager:*",
        "organizations:*",
        "pricing:*",
        "route53:*",
        "route53domains:*",
        "s3:GetAccountPublicAccessBlock",
        "s3:GetBucketLocation",
        "s3:GetBucketPolicyStatus",
        "s3:GetBucketPublicAccessBlock",
        "s3:ListAllMyBuckets",
        "s3:PutAccountPublicAccessBlock",
        "s3:PutBucketPublicAccessBlock",
        "shield:*",
        "sts:*",
        "support:*",
        "trustedadvisor:*",
        "waf-regional:*",
        "waf:*",
        "wafv2:*",
        "wellarchitected:*"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": [
            "ap-northeast-1",
            "us-east-1",
            "us-west-2",
            "ap-northeast-3"
          ]
        }
      }
    }
  ]
}
許可リージョンの根拠(Terraform provider.tfから確認):
  ・ap-northeast-1(東京): メインリージョン
  ・us-east-1(バージニア): CloudFront, ACM, WAF(Global)等で必要
  ・us-west-2(オレゴン): bastion-retool-oregonが存在(production, amazon-connect, infra-dev)
  ・ap-northeast-3(大阪): providerで定義あり(develop, infra-dev)

NotAction(除外)の根拠:
  ・AWS公式推奨リスト(https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples_general.html)に準拠
  ・IAM, STS, Organizations: グローバルサービス(リージョンに依存しない)
  ・Support, Budgets, Health, CE, CUR, Pricing, Trusted Advisor: グローバルサービス
  ・CloudFront, Route53, WAF, Shield, Global Accelerator: エッジサービス
  ・KMS, ACM: リージョナルだがグローバル操作を含む
  ・S3の一部: アカウントレベル設定・バケット一覧等のグローバル操作
  ・Network Manager, Well-Architected, Import/Export: グローバルサービス
  ・Chatbot(Amazon Q Developer in chat): グローバルサービス(エンドポイントはus-west-2)
    NotActionに含めないと、chatbot:CreateSlackChannelConfiguration等の
    新規作成・変更APIがSCPでブロックされる。
    既存のChatbot設定はSCP適用前に作成済みのため稼働に影響なし
    (通知の受信・Slack送信はAWSサービス内部処理であり、ユーザーのAPI呼び出しではないため)
    参考: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_aws_deny-requested-region.html
  ・Bedrock: クロスリージョン推論プロファイル(下記参照)

Bedrock除外の理由:
  ・Bedrockのクロスリージョン推論プロファイル(us.プレフィックス)は、AWSが内部的に
    複数リージョン(us-east-1, us-east-2, us-west-2等)にリクエストをルーティングする。
    許可リージョン外へルーティングされるとSCPでDenyされ障害が発生する。
    (実績: 2026-06-09 eligibility-verification-serviceのOCR障害。Issue #13110)
  ・Geographicプロファイル(us.等)の宛先リージョンは現時点では固定だが、
    Globalプロファイルでは将来リージョンが追加される可能性がある。
    また、利用するAPIアクション(Converse, InvokeModel等)も増える可能性がある。
  ・Bedrockのリージョン制限をSCPで行うと、アプリ側でのモデルID変更をinfra側で検知できない。
    モデル・リージョンの制御はIAMポリシー側で行う方が適切。
  ・各サービスのIAMポリシーで利用可能なモデル(anthropic.*)・アクション(InvokeModel等)は既に制限されている。
  ・bedrock-agentcore(AgentCore Runtime)も今後クロスリージョンで動作する可能性があるため合わせて除外する。
  ・コスト高騰防止はSCPではなく、Bedrockのコストモニタリング・アラートで対応する(今後の検討課題)。

影響分析:
  ・許可リージョン以外でのEC2起動、RDS作成等が拒否される
  ・既存リソースには影響なし(SCPはAPIコールを制限する)
  ・グローバルサービスは除外されているため影響なし
  ・Bedrockは除外されているが、IAMポリシーで制御されている

既存環境の利用状況確認:
  ・ap-northeast-1(東京): メインリージョン。ほぼ全リソース → 許可済み ✅
  ・us-east-1(バージニア): WAF(CloudFront用)、メンテナンスページ、ACM → 許可済み ✅
  ・us-west-2(オレゴン): VPC、Bastion(Retool)、Macie、VPC Flow Logs → 許可済み ✅
  ・ap-northeast-3(大阪): develop/infra-devで使用 → 許可済み ✅
  ・グローバルサービス(IAM, CloudFront, Route53, WAF, S3一部): NotActionで除外済み ✅
  ・Bedrock: クロスリージョン推論で許可リージョン外にルーティングされるため除外 ✅
  → 既存の全リージョン・全サービスが許可リストまたは除外リストに含まれており影響なし

既存SCPとの競合: なし

SCP③: Organization離脱禁止

適用先: Root(全メンバーアカウント)
目的: メンバーアカウントのOrganization離脱を防止
既存SCPのbillandorgblockではrootユーザーが除外されているため、無条件Denyで補完
json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyLeaveOrganization",
      "Effect": "Deny",
      "Action": "organizations:LeaveOrganization",
      "Resource": "*"
    }
  ]
}
影響分析:
  ・全メンバーアカウント(rootユーザー含む)でOrganization離脱が不可になる
  ・正当な理由でアカウントを離脱させる場合はマネジメントアカウントから実施
    (SCPはマネジメントアカウントに効かない)
  ・通常のワークロード操作には影響なし

既存SCPとの競合:
  ・billandorgblockにもLeaveOrganization Denyがあるが、rootが除外されている
  ・本SCPはrootも含めて無条件Deny → 既存SCPを補完する関係(競合ではない)

SCP④: 本番データ保護

適用先: Production OU(本番アカウントのみ)
目的: Tier-1(医療情報)を含む本番データの保護
3省2ガイドライン「技術的安全管理措置」に対応
json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyDeleteS3AccountPublicAccessBlock",
      "Effect": "Deny",
      "Action": [
        "s3:DeleteAccountPublicAccessBlock"
      ],
      "Resource": "*"
    },
    {
      "Sid": "DenyRDSPublicSnapshot",
      "Effect": "Deny",
      "Action": [
        "rds:ModifyDBSnapshotAttribute",
        "rds:ModifyDBClusterSnapshotAttribute"
      ],
      "Resource": "*"
    },
    {
      "Sid": "DenyEBSPublicSnapshot",
      "Effect": "Deny",
      "Action": "ec2:ModifySnapshotAttribute",
      "Resource": "*"
    },
    {
      "Sid": "DenyPublicAMI",
      "Effect": "Deny",
      "Action": "ec2:ModifyImageAttribute",
      "Resource": "*"
    }
  ]
}
影響分析:
  ・S3 アカウントレベルの Public Access Block の削除(Delete)が不可
  ・Public Access Block の有効化・設定変更(Put)は可能
    → 新規アカウントで Terraform apply が可能
  ・⚠️ Put で全フラグを false に設定するケースは SCP で防げない
    (S3 Control に該当する Condition キーが存在しないため)
    → CloudTrail(PutAccountPublicAccessBlock イベント)と GuardDuty で補完監視
  ・バケットレベルの PutBucketPublicAccessBlock は制限しない
    (アカウントレベルの設定が優先されるため、バケット単位で false にしてもパブリック公開は不可)
  ・前提: 各アカウントでアカウントレベルの Public Access Block が true に設定済みであること
    (Terraform の aws_s3_account_public_access_block で管理)
  ・RDS/Auroraスナップショットのパブリック共有が不可
  ・EBSスナップショットのパブリック共有が不可
  ・AMIのパブリック共有が不可
  ・通常のS3操作(Put/Get/Delete等)には影響なし
  ・既存リソースの稼働には影響なし

既存SCPとの競合: なし

変更履歴:
  ・2026-07-13: DenyS3PublicAccess を DenyS3AccountPublicAccessBlock に変更
    - 詳細・経緯・検証結果は「SCP④ DenyS3PublicAccess 修正手順」セクションおよび Issue #15136 を参照
  ・2026-08-19: PutAccountPublicAccessBlock → DeleteAccountPublicAccessBlock に変更(PR #2664)
    - 新規アカウントで Terraform apply 時に Put がブロックされる問題を解消
    - Delete のみブロックし、Put(有効化・変更)は許可する方針に変更
    - Put で全フラグ false にするケースは SCP で防げない妥協点あり(CloudTrail/GuardDuty で補完)

6. 適用順序と検証手順

適用順序

影響が小さいものから順に適用する。

順序SCP適用先理由
1SCP③ LeaveOrg禁止Root全アカウント対象だが、通常操作に影響なし。MZ確認不要
2SCP② リージョン制限各OU(Sandbox OUで検証後)Security OU以外に適用。MZ確認不要
3SCP④ 本番データ保護Production(Sandbox OUで検証後)本番アカウントに影響。ctop担当者と確認後に適用
4SCP① セキュリティ保護Root(Sandbox OUで検証後)Root適用でMZ管理アカウントにも影響。MZへの確認後に適用

検証・段階適用手順(SCP①②④)

本番影響が想定されるSCPは、段階的に適用して安全性を確認する。
また、影響範囲のサービス担当者への共有・問い合わせを行い、問題がないことを確認する。

Step 1: Sandbox OUで検証
  ・Sandbox OUにテスト対象のSCPを適用
  ・fd-infra-devで動作確認
    - 制限対象のアクションが拒否されること
      例(SCP②): 許可リージョン以外でEC2を起動 → 拒否されることを確認
    - 通常操作に影響がないこと
      例: ap-northeast-1でEC2起動、S3操作、ECS操作等が正常に行えること
  ・Sandbox OUのテスト用SCPを削除(元のSCP構成に戻す)

Step 2: Non-Production OUに適用して様子見
  ・Non-Production OU(staging, develop等)にSCPを適用
  ・一定期間(1週間目安)運用し、以下を確認:
    - CloudTrailで意図しないSCP拒否(errorCode: AccessDenied)が発生していないこと
    - 各サービスの正常稼働(Datadog APM/ログ等で確認)
  ・Sandbox OUでは検知できない実サービスへの影響をここで検出する
    (例: Bedrockクロスリージョン推論、サービス間連携等)

Step 3: Production OU / Workloads OU / Rootに適用
  ・Non-Productionでの様子見期間に問題がなければ本番適用

  ※ SCP③(LeaveOrg禁止)は通常操作に影響しないため、
    段階適用なしでRoot直接適用可

確認ツール:
  ・CloudTrail: SCP拒否のイベント(errorCode: AccessDenied)を確認
  ・IAM service last accessed data: 制限対象サービスの利用状況を事前確認
  ・Datadog: サービスのエラー率・レイテンシの異常を監視

教訓(2026-06-09 Bedrock障害 Issue #13110):
  ・SCP②(リージョン制限)をSandbox検証後にProduction OUに直接適用した結果、
    Bedrockクロスリージョン推論がDenyされ障害が発生した。
  ・Sandbox OU(fd-infra-dev)にはeligibility-verification-serviceが存在しないため、
    Sandbox検証では検知できなかった。
  ・Non-Production OUでの段階適用があれば、staging環境で事前に検知できた可能性が高い。

SCP④ DenyS3PublicAccess 修正手順

背景:
  ・SCP④ の DenyS3PublicAccess で使用している Condition キー
    (s3:PublicAccessBlockConfiguration/*)が PutBucketPublicAccessBlock API では
    機能しないことが infra-dev での検証で判明(Issue #15136)
  ・全パラメータ true で呼んでも Deny される(意図した動作ではない)
  ・AWS Managed Services の公式 SCP サンプル(SCP-AMS-018)では
    PutAccountPublicAccessBlock を無条件 Deny する方式を採用
    参考: https://docs.aws.amazon.com/managedservices/latest/userguide/scp-library-compliance.html
  ・アカウントレベルの Public Access Block が true であれば、
    バケットレベルで false にしてもアカウント設定が優先されるため、
    バケットレベルの API を制限する必要がない

修正手順:

  方針: 各環境で PAB(アカウントレベル Public Access Block)→ SCP をセットで適用し、
  検証・様子見してから次の環境に進む。PAB だけ先に全環境入れて SCP を後追いする方式だと、
  SCP の問題が Production で初めて発覚するリスクがあるため、環境ごとにサイクルを回す。

Step 0: SCP④ の DenyS3PublicAccess Statement を一時的に削除 ✅ 完了(PR #2379)
  ・deny_production_data_exposure.json から DenyS3PublicAccess Statement を削除
  ・terraform apply で Production OU に反映
  ・この時点では PutBucketPublicAccessBlock / PutAccountPublicAccessBlock ともに制限なし
  ・目的: Terraform からバケット単位の public_access_block 設定ができない状態を解消
    (CloudFront + WAF 構築 PR #2369 のブロッカー解消)

Step 1: Sandbox OU(infra-dev)で PAB + SCP を検証 ✅ PAB 完了(PR #2426)
  Step 1-1: PAB を追加 ✅ 完了
    - fd-infra-dev(853790572692): common/infra-dev で aws_s3_account_public_access_block を追加
    - CLI で設定済みのため terraform import で state に取り込み済み
  Step 1-2: SCP を Sandbox OU にアタッチして検証
    - deny_production_data_exposure.json に DenyS3AccountPublicAccessBlock を追加
    - 新規 SCP(全 OU 共通)を作成するか、既存 SCP④ に Statement を追加して
      Sandbox OU にもアタッチする
    - 検証内容:
      ・アカウントレベル PAB の変更が SCP で拒否されることを確認
      ・Terraform からバケット単位の public_access_block 設定が可能であることを確認
      ・バケットレベルで false にしてもアカウント設定が優先されることを確認

Step 2: Non-Production OU(staging / develop)で PAB + SCP を適用 + 1週間様子見
  Step 2-1: PAB を追加
    - fd-stg(301608970378): common/staging で aws_s3_account_public_access_block を追加
    - fd-dev(900176301532): common/develop で aws_s3_account_public_access_block を追加
  Step 2-2: SCP を Non-Production OU にアタッチ + 1週間様子見
    - 一定期間(1週間目安)運用し、既存サービスに影響がないことを確認
    - 適用直前に既存バケットの影響調査(観点3・4)を再実施

Step 3: Production OU で PAB + SCP を適用
  Step 3-1: PAB を追加
    - fd-sys(913831226605): common/amazon-connect で aws_s3_account_public_access_block を追加
    - fd-prod(967691968827): common/production で aws_s3_account_public_access_block を追加
  Step 3-2: SCP を Production OU にアタッチ
    - 適用直前に既存バケットの影響調査(観点3・4)を再実施

  ・既存バケットへの影響調査結果(2026-07-17 時点、Issue #15136 コメント参照):
    - 全アカウントでパブリック公開しているバケットはゼロ
    - PAB false のバケット: fd-dev 3件(テスト用)、fd-sys 12件(全て ALB ログ用)
    - PAB 未設定のバケット: fd-infra-dev 7件、fd-dev 19件、fd-sys 26件
      (Serverless Framework デプロイ、CodePipeline、Amplify、Amazon Connect 等)
    - パブリック ACL: 全アカウント 0件
    - パブリックバケットポリシー: 全アカウント 0件(ポリシー自体なし)
    - ALB ログバケットは AWS サービスプリンシパル経由の書き込みのみで PAB の影響なし

Step 0 完了時に削除済み:
  ・テスト用 SCP(test-deny-s3-public-access)は PR #2379 で削除済み

ロールバック手順

SCPが原因でサービス障害が発生した場合:

  1. Gitで前のコミットに戻す(git revert or git checkout)
  2. terraform apply でSCPを前の状態に戻す
  → SCPの変更が即時反映される

7. 運用ルール

SCP変更時の確認

1. 変更内容をPRで提出し、コードレビューを受ける
2. Sandbox OUで事前検証(SCP①②④の場合)
3. Non-Production OUに適用して1週間様子見(本番影響が想定される変更の場合)
4. ctop系に影響がある場合はctop担当者に事前連絡
5. Rootに適用するSCPの場合はMZにも事前連絡
6. Production OU / Workloads OU / Rootに適用(terraform apply)

緊急時の対応

SCPが原因でサービス障害が発生した場合:
  1. Gitで前のコミットに戻す(git revert or git checkout)
  2. terraform apply でSCPを前の状態に戻す
  3. 原因を調査(CloudTrailでAccessDeniedイベントを確認)
  4. SCPを修正して再適用

対応可能な人:
  ・fd-security-toolingへのアクセス権を持つSRE(delegation policy経由)

Terraform管理

SCPはfd-security-toolingのTerraformで管理する。

リソース定義パターン:
  ・aws_organizations_policy: SCP定義
  ・aws_organizations_policy_attachment: SCPのOU/アカウントへの適用

コードの配置:
  fastdoctor-template/common/security-tooling/scp.tf

変更履歴:
  ・Git履歴で「いつ、誰が、何を変更したか」を追跡
  ・コミットメッセージにSCP変更の理由を記録

将来検討するSCP

以下は既存ワークロードへの影響確認が必要なため、段階的に検討・追加する。

ログ・監査保護

SCP目的注意事項
VPC Flow Logs削除禁止フローログの削除を防止。ネットワーク監査の保護
CloudTrail設定変更禁止(拡充)UpdateTrail等の追加制限運用上の設定変更が必要な場合の除外条件を検討

暗号化・鍵管理

SCP目的注意事項
KMS鍵削除禁止 / 30日冷却期間暗号化キーの誤削除防止。医療情報の暗号化に直結Tier-1アカウントで特に重要
EBS/RDS暗号化強制暗号化なしのボリューム/DB作成を禁止既存の暗号化なしリソースの有無を確認
データストレージ暗号化の強制S3, EBS, RDS, DynamoDB等の保存データ暗号化を必須化

データ境界・アクセス制御

SCP目的注意事項
DBのクロスアカウントスナップショット共有拒否RDS/Auroraスナップショットの他アカウントへの共有を禁止OU間のデータ流出防止
DBのパブリック配置拒否RDS/Auroraをパブリックサブネットに配置することを禁止fd-sys(913831226605)の本番DBが既にパブリック配置のためペンディング。移行後に適用検討
異なるOU間のVPCピアリング/VPN拒否OU間の意図しないネットワーク接続を防止既存のVPCピアリング構成を事前確認
S3パブリックアクセス禁止(全OU拡大)Production以外のOUにも DeleteAccountPublicAccessBlock Deny を拡大する場合各アカウントでアカウントレベル Public Access Block を true に事前設定が必要

インスタンス・リソース制限

SCP目的注意事項
本番DBのt系インスタンスタイプ制限Production OUでRDS/Auroraのt系(バースト型)作成を拒否本番はr系/m系を使用すべき。既存インスタンスの確認が必要
IMDSv2強制EC2メタデータをv2に限定Declarative Policyでも対応可能
デフォルトVPC制限デフォルトVPCでのリソース作成を禁止fd-sys(913831226605)がデフォルトVPCを使用中

特権アクセス制御

SCP目的注意事項
rootユーザーMFA強制MFAなしでのrootユーザー操作を拒否MFA管理SaaS導入が前提
rootユーザー操作制限メンバーアカウントのrootの全操作を制限Centralized Root Access導入後は不要

SCPは「APIコール(操作)」を制限するもので、既存リソースには影響しない。ただし新規作成・スケールアウト・障害復旧時に拒否される可能性があるため、既存環境の利用状況を確認してから適用すること。