一部のリソースベースポリシーではSidが必須になります
【9サービス徹底検証】
【9サービス徹底検証】
CloudFormationでSNSトピックポリシーをデプロイしようとしたところ、以下のように怒られました。
Every policy statement must have a unique ID
怒られたトピックポリシーは以下の通りです。どうやら複数のステートメントがあるのにSidを設定していないことで怒られていた模様。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PolicyDocument:
Statement:
- Effect: Allow
Principal:
AWS: "*"
Action:
- SNS:GetTopicAttributes
- SNS:SetTopicAttributes
- SNS:AddPermission
- SNS:RemovePermission
- SNS:DeleteTopic
- SNS:Subscribe
- SNS:ListSubscriptionsByTopic
- SNS:Publish
Resource: !Ref HealthSnsTopic
Condition:
StringEquals:
AWS:SourceOwner: !Sub ${AWS::AccountId}
- Effect: Allow
Principal:
Service: events.amazonaws.com
Action: SNS:Publish
Resource: !Ref HealthSnsTopic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sidを設定するとエラーは解消されました。
めでたしめでたし......あれ、Sidってオプションじゃなかったっけ?
まず、SNSの公式ドキュメントを確認しましたがSidが必須である旨の記載は見つかりませんでした。
IAMドキュメントを確認してみると、
You can provide a Sid (statement ID) as an optional identifier for the policy statement.
と、やっぱり「optional」とあります。
しかし、よくよく読み進めてみると下の方に、
Some AWS services (for example, Amazon SQS or Amazon SNS) might require this element and have uniqueness requirements for it. For service-specific information about writing policies, refer to the documentation for the service you work with.
「SNSやSQSでは必須の場合がある」と記載がありました。具体的にどういう条件で必須になるのかは明記されていません。
元々「単一ステートメント・Sidなし」でデプロイして成功していたものにステートメントを追加しようとしたところでエラーが発生していたため、ステートメント数を調整してSNSトピックポリシーが作成できるか確認しました。
★検証を効率化するためにKiro CLIを活用させてもらっています。
# トピック作成
aws sns create-topic --name test-multi-statement-topic --region ap-northeast-1
# 単一ステートメント(Sidなし)
aws sns set-topic-attributes \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:test-multi-statement-topic \
--attribute-name Policy \
--attribute-value '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"s3.amazonaws.com"},"Action":"SNS:Publish","Resource":"arn:aws:sns:ap-northeast-1:123456789012:test-multi-statement-topic"}]}' \
--region ap-northeast-1
結果:成功
# 複数ステートメント(Sidなし)
aws sns set-topic-attributes \
--topic-arn arn:aws:sns:ap-northeast-1:123456789012:test-multi-statement-topic \
--attribute-name Policy \
--attribute-value '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"s3.amazonaws.com"},"Action":"SNS:Publish","Resource":"arn:aws:sns:ap-northeast-1:123456789012:test-multi-statement-topic"},{"Effect":"Allow","Principal":{"Service":"lambda.amazonaws.com"},"Action":"SNS:Subscribe","Resource":"arn:aws:sns:ap-northeast-1:123456789012:test-multi-statement-topic"}]}' \
--region ap-northeast-1
結果:失敗
An error occurred (InvalidParameter) when calling the SetTopicAttributes operation: Invalid parameter: Every policy statement must have a unique ID
どうやらポリシードキュメント内に複数ステートメントを含む場合のみSidが必須になるようです。
ドキュメントには「SQSやSNS」と並べて書かれていたため、SNSと同様のエラーがSQS作成時にも発生するのか検証しました。
まず、SQSキューを作成し、複数のステートメントを持つポリシーをSidなしで設定してみます。
# キュー作成
aws sqs create-queue --queue-name test-multi-statement-queue --region ap-northeast-1
# 複数ステートメント(Sidなし)のポリシーを設定
aws sqs set-queue-attributes \
--queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/test-multi-statement-queue \
--attributes Policy='{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"sns.amazonaws.com"},"Action":"SQS:SendMessage","Resource":"arn:aws:sqs:ap-northeast-1:123456789012:test-multi-statement-queue"},{"Effect":"Allow","Principal":{"Service":"s3.amazonaws.com"},"Action":"SQS:SendMessage","Resource":"arn:aws:sqs:ap-northeast-1:123456789012:test-multi-statement-queue"}]}' \
--region ap-northeast-1
結果:成功
SQSは複数ステートメントでもSidなしで正常に動作しました。
念のためCloudFormationでも試してみました。
AWSTemplateFormatVersion: '2010-09-09'
Resources:
TestQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: test-cfn-multi-statement-queue
TestQueuePolicy:
Type: AWS::SQS::QueuePolicy
Properties:
Queues:
- !Ref TestQueue
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: sns.amazonaws.com
Action: SQS:SendMessage
Resource: !GetAtt TestQueue.Arn
- Effect: Allow
Principal:
Service: s3.amazonaws.com
Action: SQS:SendMessage
Resource: !GetAtt TestQueue.Arn
結果:CREATE_COMPLETE
CloudFormationでもSidなしで正常にデプロイすることができました。てっきりSQSもSNSと同条件でSidが必須になるものと思っていたため意外です。
興味が湧いたのでその他のAWSサービスのリソースベースポリシーでも調べてみることにしました。
以下のサービスで、複数ステートメント + Sidなしのポリシーが設定できるか検証しました:
aws s3api create-bucket \
--bucket test-sid-validation \
--create-bucket-configuration LocationConstraint=ap-northeast-1 \
--region ap-northeast-1
aws s3api put-bucket-policy \
--bucket test-sid-validation \
--policy '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"s3:GetObject","Resource":"arn:aws:s3:::test-sid-validation/*"},{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"s3:ListBucket","Resource":"arn:aws:s3:::test-sid-validation"}]}' \
--region ap-northeast-1
結果:成功
aws secretsmanager create-secret \
--name test-sid-validation-secret \
--secret-string "test-value" \
--region ap-northeast-1
aws secretsmanager put-resource-policy \
--secret-id test-sid-validation-secret \
--resource-policy '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"secretsmanager:GetSecretValue","Resource":"*"},{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"secretsmanager:DescribeSecret","Resource":"*"}]}' \
--region ap-northeast-1
結果:成功
aws kms create-key \
--description "Test key for Sid validation" \
--region ap-northeast-1
aws kms put-key-policy \
--key-id <key-id> \
--policy-name default \
--policy '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"kms:*","Resource":"*"},{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"kms:Decrypt","Resource":"*"}]}' \
--region ap-northeast-1
結果:成功
aws ecr create-repository \
--repository-name test-sid-validation-repo \
--region ap-northeast-1
aws ecr set-repository-policy \
--repository-name test-sid-validation-repo \
--policy-text '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"ecr:GetDownloadUrlForLayer"},{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"ecr:BatchGetImage"}]}' \
--region ap-northeast-1
結果:成功
aws events create-event-bus \
--name test-sid-validation-bus \
--region ap-northeast-1
aws events put-permission \
--event-bus-name test-sid-validation-bus \
--policy '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"events:PutEvents","Resource":"arn:aws:events:ap-northeast-1:123456789012:event-bus/test-sid-validation-bus"},{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"events:PutRule","Resource":"arn:aws:events:ap-northeast-1:123456789012:event-bus/test-sid-validation-bus"}]}' \
--region ap-northeast-1
結果:エラー
An error occurred (ValidationException) when calling the PutPermission operation: Missing required field Sid
EventBridgeのput-permissionコマンドは、StatementIdパラメータが必須のようです。
aws apigateway create-rest-api \
--name test-sid-validation-api \
--region ap-northeast-1
aws apigateway update-rest-api \
--rest-api-id <api-id> \
--patch-operations op=replace,path=/policy,value='{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":"*","Action":"execute-api:Invoke","Resource":"*"},{"Effect":"Deny","Principal":"*","Action":"execute-api:Invoke","Resource":"*","Condition":{"NotIpAddress":{"aws:SourceIp":"203.0.113.0/24"}}}]}' \
--region ap-northeast-1
結果:成功
aws lambda add-permission \ --function-name test-sid-validation-func \ --statement-id Statement1 \ --action lambda:InvokeFunction \ --principal s3.amazonaws.com \ --region ap-northeast-1 aws lambda add-permission \ --function-name test-sid-validation-func \ --statement-id Statement2 \ --action lambda:InvokeFunction \ --principal sns.amazonaws.com \ --region ap-northeast-1
Lambdaのadd-permissionコマンドもEvent Bridgeと同様に--statement-idパラメータが必須のようです。
| サービス | 複数ステートメント + Sidなし | Sid必須の理由 |
|---|---|---|
| S3 | ✅ 成功 | - |
| SQS | ✅ 成功 | - |
| SNS | ❌ 失敗 | ポリシードキュメント検証で複数ステートメント時に必須 |
| Secrets Manager | ✅ 成功 | - |
| KMS | ✅ 成功 | - |
| ECR | ✅ 成功 | - |
| EventBridge | ❌ 失敗 | APIコマンド仕様(put-permissionでStatementIdパラメータが必須) |
| API Gateway | ✅ 成功 | - |
| Lambda | ❌ 失敗 | APIコマンド仕様(add-permissionでStatementIdパラメータが必須) |
検証の結果、3つのサービスのリソースベースポリシーでSidが必須となる(場合がある)ことが分かりました。また、一口にSid必須といっても種類があります。
1. ポリシードキュメントレベルの検証:SNSのみ
2. APIの仕様:EventBridge、Lambda
SNSは単一ステートメントのポリシーであればポリシードキュメントレベルの検証をクリアできますが、EventBridgeとLambdaはAPIの仕様としてStatementIdパラメータが必須であるため、ステートメント数に関わらずSidが必須になります。
APIの仕様なのでコンソールから設定しようとした場合でも同様です。
①EventBridgeバスポリシー

②Lambdaアクセス許可

リソースベースポリシーにおいてSidの設定が必須になるパターンを確認しましたが、そもそも毎回設定しているならこんなこと気にする必要はありません。Sidがあるとポリシードキュメントの可読性が上がり、保守もしやすくなります。めんどくさがらず毎回設定するのがよいでしょう。
今回の検証ではKiro CLIが非常に役立ちました。気になる仕様について「ちょっと確かめてみて」と自然言語で依頼しただけで、実際にリソースを作って検証~情報の整理~クリーンアップまで爆速でやってくれました。「これって本当にそうなのかな?」「ほかのパターンではどうなんだろう?」を簡単に解決できるのはKiro CLIの強みだと思いました。
IAM JSON policy elements: Sid - AWS Documentation
Example cases for Amazon SNS access control - AWS Documentation
Basic examples of Amazon SQS policies - AWS Documentation
AWS policy application failure for a topic with strange error - Stack Overflow
この記事は2025年11月27日時点の情報に基づいています。