- AWS
AWS OrganizationsのSCPの書き方|例文とテンプレート
SCP(サービスコントロールポリシー)は、AWS Organizations のメンバーアカウントで「使ってよい操作の上限」を決めるポリシーです。 IAM ポリシーと同じ JSON で書きますが、権限を与えることはなく、絞るだけです。ふつうは既定の FullAWSAccess(全部許可)を残したまま、「Deny」で禁止したいことを書き足す形(拒否リスト)で使います。
| 目的 | 書き方の要点 |
|---|---|
| 使うリージョンを絞る | Deny + NotAction(グローバルサービスを除外)+ aws:RequestedRegion |
| ルートユーザーを使わせない | Deny "*" + aws:PrincipalArn が arn:aws:iam::*:root |
| CloudTrail・GuardDuty・Config を止めさせない | 停止・削除の操作を Deny |
| 組織から抜けさせない | organizations:LeaveOrganization を Deny |
| 管理用のロールだけは例外 | Condition の ArnNotLike + aws:PrincipalARN |
| 使うサービスだけを許す(許可リスト) | FullAWSAccess を外し、Allow に使うサービスを並べる |
確認環境:AWS CLI 1.46.1(Linux)。AWS には接続せず、moto 5.2.4 のサーバーモードで、組織の作成、SCP の有効化、OU とアカウントの作成、この記事の SCP の create-policy・attach-policy・detach-policy(FullAWSAccess を外して許可リストに替える)を動かしました。例文の操作名は botocore のサービス定義にある API 名と突き合わせ、JSON の文字数も数えています。moto はサイズや構文の制約、評価そのものを再現しないため、SCP の効き方・上限・評価の順番は AWS のドキュメントに基づいています(確認日 2026年10月13日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「AWS OrganizationsのSCPの書き方|例文とテンプレート」
SCP の基本
| 項目 | 内容(ドキュメント) |
|---|---|
| 効く相手 | メンバーアカウントの全ユーザー・全ロール(ルートユーザーも) |
| 効かない相手 | 管理アカウント、サービスリンクロール、組織の外のユーザー・ロール |
| 権限を与えるか | 与えない。最大の権限を決めるフィルター。実際の許可は IAM ポリシーで |
| 継承 | ルート → OU → アカウントの道すじの全部の段で Allow が要る。Deny はどの段でも効く |
| 既定 | SCP を有効にすると、ルート・OU・アカウントすべてに FullAWSAccess が付く |
管理アカウントには SCP が効きません。 管理アカウントで作業を減らし、ワークロードはメンバーアカウントに置く構成にすると、SCP で守れる範囲が広がります。
目的別の例文
1. リージョンを東京・大阪に絞る(グローバルサービスを除外)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyOutsideTokyoOsaka",
"Effect": "Deny",
"NotAction": [
"a4b:*", "acm:*", "aws-marketplace-management:*", "aws-marketplace:*", "aws-portal:*",
"budgets:*", "ce:*", "chime:*", "cloudfront:*", "config:*", "cur:*", "directconnect:*",
"ec2:DescribeRegions", "ec2:DescribeTransitGateways", "ec2:DescribeVpnGateways",
"fms:*", "globalaccelerator:*", "health:*", "iam:*", "importexport:*", "kms:*",
"mobileanalytics:*", "networkmanager:*", "organizations:*", "pricing:*",
"route53:*", "route53domains:*", "route53-recovery-cluster:*",
"route53-recovery-control-config:*", "route53-recovery-readiness:*",
"s3:GetAccountPublic*", "s3:ListAllMyBuckets", "s3:ListMultiRegionAccessPoints",
"s3:PutAccountPublic*", "shield:*", "sts:*", "support:*", "trustedadvisor:*",
"waf-regional:*", "waf:*", "wafv2:*", "wellarchitected:*"
],
"Resource": "*",
"Condition": {
"StringNotEquals": { "aws:RequestedRegion": ["ap-northeast-1", "ap-northeast-3"] },
"ArnNotLike": { "aws:PrincipalARN": ["arn:aws:iam::*:role/OrganizationAccountAccessRole"] }
}
}
]
}
NotAction の一覧は、ドキュメントの例をそのまま使い、リージョンを東京(ap-northeast-1)と大阪(ap-northeast-3)にしています。「NotAction に無い操作を、東京・大阪以外で行ったら拒否」という意味です。
| 除外する理由 | 主なサービス(ドキュメントの例から) |
|---|---|
| エンドポイントが us-east-1 にあるグローバルサービス | iam・organizations・route53・cloudfront・globalaccelerator・shield・waf |
| 請求・サポート | aws-portal・budgets・ce・cur・pricing・support・trustedadvisor |
| STS(既定のグローバルエンドポイント) | sts。リージョンのエンドポイントだけを使うなら外せる |
| CloudFront が us-east-1 で使う | acm・kms(CloudFront 用の証明書と鍵) |
| リージョンをまたぐ一覧 | s3:ListAllMyBuckets・ec2:DescribeRegions など |
ドキュメントでは、この一覧はすべてのグローバルサービスを含むとは限らないとされ、自分の組織で使うものに合わせて直すよう書かれています。IAM の「アクセスアドバイザー」で、実際に使っているサービスを確かめられます。リージョンのコードは、関連記事「AWSリージョン一覧とコード早見表|東京・大阪のAZも」で扱っています。
2. ルートユーザーの操作を禁止する
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyRootUser",
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringLike": { "aws:PrincipalArn": "arn:aws:iam::*:root" }
}
}
]
}
SCP はメンバーアカウントのルートユーザーにも効きます。ただし、ドキュメントでは、ルートユーザーでのエンタープライズサポートの申し込みなど、SCP で止められない作業が挙げられています。管理アカウントのルートユーザーには効きません。
3. CloudTrail・GuardDuty・Config を止めさせない
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ProtectCloudTrail",
"Effect": "Deny",
"Action": [
"cloudtrail:StopLogging",
"cloudtrail:DeleteTrail",
"cloudtrail:UpdateTrail",
"cloudtrail:PutEventSelectors"
],
"Resource": "*",
"Condition": {
"ArnNotLike": { "aws:PrincipalARN": "arn:aws:iam::*:role/SecurityAdmin" }
}
},
{
"Sid": "ProtectGuardDuty",
"Effect": "Deny",
"Action": [
"guardduty:DeleteDetector",
"guardduty:UpdateDetector",
"guardduty:DisassociateFromMasterAccount",
"guardduty:DisassociateFromAdministratorAccount",
"guardduty:StopMonitoringMembers",
"guardduty:DeleteMembers",
"guardduty:DisassociateMembers"
],
"Resource": "*",
"Condition": {
"ArnNotLike": { "aws:PrincipalARN": "arn:aws:iam::*:role/SecurityAdmin" }
}
},
{
"Sid": "ProtectConfig",
"Effect": "Deny",
"Action": [
"config:StopConfigurationRecorder",
"config:DeleteConfigurationRecorder",
"config:DeleteDeliveryChannel"
],
"Resource": "*",
"Condition": {
"ArnNotLike": { "aws:PrincipalARN": "arn:aws:iam::*:role/SecurityAdmin" }
}
},
{
"Sid": "DenyLeaveOrganization",
"Effect": "Deny",
"Action": "organizations:LeaveOrganization",
"Resource": "*"
}
]
}
ここで使った操作名は、botocore のサービス定義(CloudTrail・GuardDuty・Config・Organizations)に API として載っていることを確かめました。UpdateTrail・UpdateDetector も止めるのは、ログの出力先を変えたり、検出を無効にしたりする設定変更を防ぐためです。CloudTrail の証跡の作り方は、関連記事「CloudTrailで誰が操作したか調べる|lookup-eventsとAthena」で扱っています。
4. 基盤のロールを変えさせない・IAM ユーザーを作らせない(特定ロールを除外)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ProtectBaselineRoles",
"Effect": "Deny",
"Action": [
"iam:AttachRolePolicy", "iam:DeleteRole", "iam:DeleteRolePermissionsBoundary",
"iam:DeleteRolePolicy", "iam:DetachRolePolicy", "iam:PutRolePermissionsBoundary",
"iam:PutRolePolicy", "iam:UpdateAssumeRolePolicy", "iam:UpdateRole",
"iam:UpdateRoleDescription"
],
"Resource": ["arn:aws:iam::*:role/SecurityAdmin", "arn:aws:iam::*:role/OrganizationAccountAccessRole"],
"Condition": {
"ArnNotLike": { "aws:PrincipalARN": "arn:aws:iam::*:role/OrganizationAccountAccessRole" }
}
},
{
"Sid": "DenyIamUserAccessKeys",
"Effect": "Deny",
"Action": ["iam:CreateUser", "iam:CreateAccessKey", "iam:CreateLoginProfile"],
"Resource": "*",
"Condition": {
"ArnNotLike": { "aws:PrincipalARN": "arn:aws:iam::*:role/OrganizationAccountAccessRole" }
}
}
]
}
1つ目の文の操作の一覧は、ドキュメントの「特定の管理ロールを除いて、IAM ロールの変更を防ぐ」例と同じです。2つ目は、IAM Identity Center に寄せて、アクセスキーを持つ IAM ユーザーを作らせない例です。
特定のロールを除外する条件の書き方
| 書き方 | 意味 | 注意 |
|---|---|---|
"ArnNotLike": {"aws:PrincipalARN": "arn:aws:iam::*:role/SecurityAdmin"} |
そのロール以外を拒否 | * でアカウント ID を問わない |
"ArnNotLike": {"aws:PrincipalARN": "arn:aws:iam::*:role/aws-reserved/sso.amazonaws.com/*/AWSReservedSSO_AdministratorAccess_*"} |
Identity Center の許可セットのロールを除外 | 許可セットのロールはパスと末尾の文字列が付く |
"StringNotEquals": {"aws:PrincipalAccount": "111122223333"} |
特定のアカウント以外を拒否 | — |
"Bool": {"aws:ViaAWSService": "false"} を足す |
AWS のサービスが代わりに呼ぶ操作は除く | サービス経由の呼び出しまで止めないため |
Deny の文の中の条件は「すべて満たしたら拒否」です(同じ文に条件を2つ書くと AND)。上の例 1 なら「東京・大阪以外」かつ「除外ロール以外」のときに拒否します。条件演算子と条件キーは、関連記事「IAMポリシーConditionの書き方|条件演算子と条件キー一覧」で扱っています。
構文の制約
| 項目 | 内容(ドキュメント) |
|---|---|
| ポリシーの最大サイズ | SCP は 10,240 文字(RCP は 5,120 文字)。空白・改行も数える |
| 1つの対象(ルート・OU・アカウント)に付けられる数 | SCP は 10 個(RCP は 5 個) |
| 組織で作れる SCP の数 | 10,000 |
| OU の深さ | ルートの下に 5 段まで |
| 使える要素 | Version・Statement・Sid・Effect・Action・NotAction・Resource・NotResource・Condition |
| 使えない要素 | Principal・NotPrincipal(だれかは Condition の aws:PrincipalArn などで書く) |
Allow の文の Resource |
"*" だけ。ARN を書けるのは Deny の文 |
Version |
"2012-10-17" が必須 |
この記事の例文の文字数を数えました。見やすく整形した状態と、空白を除いた状態です。
| 例文 | 整形 | 空白を除く |
|---|---|---|
| 1. リージョン制限 | 1,238 文字 | 1,012 文字 |
| 2. ルートユーザーの禁止 | 258 文字 | 175 文字 |
| 3. CloudTrail・GuardDuty・Config の保護 | 1,459 文字 | 1,047 文字 |
| 4. 基盤ロールの保護 | 989 文字 | 784 文字 |
サイズが上限に近づいたら、引用符の外の空白と改行を消す方法がドキュメントで案内されています。
jq -c . deny-regions.json > deny-regions.min.json # 空白を除いた1行の JSON
1つの SCP に詰め込めないときは、目的ごとに SCP を分け(1つの対象に 10 個まで)、OU の段ごとに付け分けます。
SCP を付ける前に、IAM Access Analyzer でチェックできます。 validate-policy の --policy-type に SERVICE_CONTROL_POLICY を指定できることを、botocore のサービス定義で確かめました。
aws accessanalyzer validate-policy --policy-type SERVICE_CONTROL_POLICY \
--policy-document file://deny-regions.json \
--query 'findings[].[findingType,issueCode,findingDetails]' --output table
IAM ポリシーとの評価の順番(RCP・境界も含めて)
同じアカウントの中のリクエストでの、評価の順番です(IAM ユーザーガイドの評価ロジック)。
flowchart TD
A[リクエスト] --> B{どこかに当てはまる<br/>明示的な Deny?<br/>SCP・RCP・リソースベース・<br/>アイデンティティベース・境界・セッション}
B -- ある --> X[拒否]
B -- ない --> C{RCP が許可?<br/>※RCP が無ければ次へ}
C -- 許可なし --> X
C -- 許可 --> D{SCP が許可?<br/>ルート・OU・アカウントの全段で Allow}
D -- 許可なし --> X
D -- 許可 --> E{リソースベースのポリシーが許可?}
E -- 許可 --> Y[許可<br/>※主体の種類による]
E -- 許可なし --> F{アイデンティティベースの<br/>ポリシーが許可?}
F -- 許可なし --> X
F -- 許可 --> G{アクセス許可の境界が許可?<br/>※無ければ次へ}
G -- 許可なし --> X
G -- 許可 --> H{セッションポリシーが許可?<br/>※無ければ許可}
H -- 許可なし --> X
H -- 許可 --> Y2[許可]
| ポリシー | 何を決めるか | 付ける先 |
|---|---|---|
| SCP | アカウントの主体(ユーザー・ロール)ができることの上限 | ルート・OU・アカウント |
| RCP(リソースコントロールポリシー) | アカウントのリソースに対してできることの上限 | ルート・OU・アカウント |
| アイデンティティベース | 主体に権限を与える | IAM ユーザー・グループ・ロール |
| アクセス許可の境界 | 主体の権限の上限 | IAM ユーザー・ロール |
| リソースベース | リソースへの権限を与える | S3 バケットなど |
SCP で許されていても、IAM ポリシーで許されていなければ使えません。 逆に、IAM の AdministratorAccess を付けても、SCP で拒否されている操作はできません。SCP で拒否されたときのエラー文は、IAM ユーザーガイドでは次の形です。
User: arn:aws:iam::123456789012:user/John is not authorized to perform: codecommit:ListRepositories
with an explicit deny in a service control policy: arn:aws:organizations::777788889999:policy/o-exampleorgid/service_control_policy/p-examplepolicyid123
User: arn:aws:iam::123456789012:user/John is not authorized to perform: codecommit:ListRepositories
because no service control policy allows the codecommit:ListRepositories action
1つ目は SCP の Deny に当たった、2つ目はどの段かで SCP の Allow が無い(許可リストに入っていない)ときです。AccessDenied の切り分けは、関連記事「AWS AccessDeniedの原因と対処|エラー文別の切り分け表」で扱っています。
FullAWSAccess を外したときの挙動
| 状態 | 結果(ドキュメント) |
|---|---|
FullAWSAccess を付けたまま Deny の SCP を足す |
拒否したもの以外は使える(拒否リスト) |
ある OU から FullAWSAccess を外し、代わりの Allow も無い |
その OU の下のアカウントは、すべての操作ができなくなる |
FullAWSAccess を外し、使うサービスだけの Allow を付ける |
書いたサービスだけ使える(許可リスト)。新しいサービスは足すまで使えない |
ルートで許可リスト、OU で FullAWSAccess |
ルートの許可リストが上限。下の段で広げることはできない |
許可リストの例です。Allow の文の Resource は "*" だけ書けます。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowOnlyTheseServices",
"Effect": "Allow",
"Action": [
"ec2:*", "elasticloadbalancing:*", "autoscaling:*", "s3:*", "rds:*", "lambda:*",
"logs:*", "cloudwatch:*", "iam:*", "sts:*", "kms:*", "ssm:*", "cloudtrail:*",
"config:*", "guardduty:*", "sso:*", "organizations:Describe*", "organizations:List*",
"support:*", "health:*"
],
"Resource": "*"
}
]
}
付ける順番は「許可リストを付ける → FullAWSAccess を外す」です。 先に外すと、その間アカウントは何もできなくなります。moto でも、この順で OU の SCP が deny-regions・deny-root・protect-security・protect-role・allow-list の5つ(FullAWSAccess なし)になりました。
CLI で作って付ける
# 組織で SCP を有効にする(管理アカウントで)
ROOT_ID=$(aws organizations list-roots --query 'Roots[0].Id' --output text)
aws organizations enable-policy-type --root-id $ROOT_ID --policy-type SERVICE_CONTROL_POLICY
# 作る
POLICY_ID=$(aws organizations create-policy \
--name deny-regions --type SERVICE_CONTROL_POLICY \
--description "Deny outside ap-northeast-1/3" \
--content file://deny-regions.json \
--query Policy.PolicySummary.Id --output text)
# まずテスト用の OU に付ける
aws organizations attach-policy --policy-id $POLICY_ID --target-id ou-xxxx-xxxxxxxx
# どの SCP が付いているか
aws organizations list-policies-for-target --target-id ou-xxxx-xxxxxxxx \
--filter SERVICE_CONTROL_POLICY --query 'Policies[].[Name,Id,AwsManaged]' --output text
# 中身を直す
aws organizations update-policy --policy-id $POLICY_ID --content file://deny-regions.json
# 外す
aws organizations detach-policy --policy-id $POLICY_ID --target-id ou-xxxx-xxxxxxxx
moto で、OU に4つの SCP を付けたあとの list-policies-for-target の結果です。FullAWSAccess は AWS 管理(True)として最初から付いていました。
FullAWSAccess p-FullAWSAccess True
deny-regions p-yr581j7p False
deny-root p-8a9hungf False
protect-security p-dngoar2w False
protect-role p-ppdqz2q8 False
いきなりルートに付けず、テスト用の OU とアカウントで確かめてから、範囲を広げることがドキュメントで勧められています。
よくある質問
Q. 管理アカウントでリージョン制限が効きません。 A. SCP は管理アカウントのユーザー・ロールには効きません。管理アカウントでの操作は、IAM ポリシーで絞ります。
Q. SCP で特定の IAM ロールに権限を与えられますか。
A. できません。SCP は上限を決めるだけです。Principal も書けません。権限は各アカウントの IAM ポリシーで与えます。
Q. リージョン制限を入れたら、IAM やサポートの画面が使えなくなりました。
A. NotAction にそのサービスが入っていない可能性があります。グローバルサービスは us-east-1 として扱われるため、除外の一覧に入れます。エラー文の with an explicit deny in a service control policy で、SCP が原因かを見分けられます。
Q. サービスリンクロールの操作も止まりますか。 A. 止まりません。ドキュメントでは、SCP はサービスリンクロールに効かないとされています。
Q. RCP と SCP はどちらを使いますか。 A. 「アカウントの中の人が何をできるか」は SCP、「アカウントのリソースに、組織の外も含めて誰が何をできるか」は RCP です。たとえば、組織の外からの S3 へのアクセスを止めたいときは RCP を使います。
まとめ
- SCP は権限を与えず、上限を決める。
FullAWSAccessを残してDenyを足す拒否リストが基本 - リージョン制限は
Deny+NotAction(グローバルサービス)+aws:RequestedRegion - 例外のロールは
ArnNotLike+aws:PrincipalARN。Principal要素は使えない - 上限は 1 つ 10,240 文字・1 つの対象に 10 個。
AllowのResourceは"*"だけ - 評価は 明示的な Deny → RCP → SCP → リソースベース → IAM → 境界 → セッション
- 管理アカウントとサービスリンクロールには効かない。
FullAWSAccessを代わり無しで外すと、その下は何もできない
参考・出典
確認日はいずれも 2026年10月13日です。
- AWS Organizations ユーザーガイド「サービスコントロールポリシーの例」:https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/orgs_manage_policies_scps_examples.html
- AWS Organizations User Guide「General examples」:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples_general.html
- AWS Organizations User Guide「Service control policies (SCPs)」:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html
- AWS Organizations User Guide「SCP syntax」:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_reference_scp-syntax.html
- AWS Organizations User Guide「SCP evaluation」:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_evaluation.html
- AWS Organizations User Guide「Quotas and service limits for AWS Organizations」:https://docs.aws.amazon.com/organizations/latest/userguide/orgs_reference_limits.html
- IAM User Guide「Determining whether a request is allowed or denied within an account」:https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic_policy-eval-denyallow.html
- IAM User Guide「Troubleshoot access denied error messages」:https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_access-denied.html
- aws-samples「service-control-policy-examples」:https://github.com/aws-samples/service-control-policy-examples
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「AWS OrganizationsのSCPの書き方|例文とテンプレート」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。