You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用CDK同时添加SNS Topic默认策略与自定义策略?

问题:在AWS CDK中创建SNS Topic时,如何同时保留默认访问策略并添加自定义策略?

我通过CDK创建了一个SNS Topic,并附加了自定义策略语句:

const snsTopic = new Topic(this, 'SnsTopic');
const snsTopicPolicyStatement = new PolicyStatement({
  effect: Effect.ALLOW,
  actions: ['SNS:Publish'],
  principals: [
    new ArnPrincipal('arn:xxx'),
    new ArnPrincipal('arn:xxx'),
  ],
  resources: ['SNS_TOPIC_ARN'],
});
snsTopicPolicyStatement.sid = 'publishStatementId';
snsTopic.addToResourcePolicy(snsTopicPolicyStatement);

但此时该主题仅拥有这条自定义策略;而如果仅创建Topic不附加任何自定义策略,它会自动生成如下默认访问策略:

{
  "Version": "2008-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "__default_statement_ID",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "SNS:GetTopicAttributes",
        "SNS:SetTopicAttributes",
        "SNS:AddPermission",
        "SNS:RemovePermission",
        "SNS:DeleteTopic",
        "SNS:Subscribe",
        "SNS:ListSubscriptionsByTopic",
        "SNS:Publish"
      ],
      "Resource": "arn:xxx",
      "Condition": {
        "StringEquals": {
          "AWS:SourceOwner": "xxx"
        }
      }
    }
  ]
}

请问如何同时为该SNS Topic添加默认访问策略与自定义策略?


解决方案

AWS CDK中,当调用addToResourcePolicy添加自定义策略语句时,默认的资源策略不会自动保留,因此需要手动构建默认策略的语句并添加到Topic中,再追加自定义策略。

具体实现代码

import { Topic, PolicyStatement, Effect, ArnPrincipal, AnyPrincipal } from 'aws-cdk-lib/aws-sns';
import { Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class SnsTopicStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const snsTopic = new Topic(this, 'SnsTopic');
    const topicArn = snsTopic.topicArn;
    const accountId = this.account;

    // 构建与默认策略一致的语句
    const defaultPolicyStmt = new PolicyStatement({
      effect: Effect.ALLOW,
      actions: [
        'SNS:GetTopicAttributes',
        'SNS:SetTopicAttributes',
        'SNS:AddPermission',
        'SNS:RemovePermission',
        'SNS:DeleteTopic',
        'SNS:Subscribe',
        'SNS:ListSubscriptionsByTopic',
        'SNS:Publish'
      ],
      principals: [new AnyPrincipal()], // 对应原默认策略的"AWS": "*"
      resources: [topicArn],
      conditions: {
        StringEquals: {
          'AWS:SourceOwner': accountId
        }
      }
    });
    defaultPolicyStmt.sid = '__default_statement_ID';

    // 添加默认策略语句
    snsTopic.addToResourcePolicy(defaultPolicyStmt);

    // 添加自定义发布策略
    const customPublishStmt = new PolicyStatement({
      effect: Effect.ALLOW,
      actions: ['SNS:Publish'],
      principals: [
        new ArnPrincipal('arn:xxx'),
        new ArnPrincipal('arn:xxx'),
      ],
      resources: [topicArn],
    });
    customPublishStmt.sid = 'publishStatementId';
    snsTopic.addToResourcePolicy(customPublishStmt);
  }
}

说明

  1. 手动构建默认策略的PolicyStatement,完全匹配自动生成的默认策略内容,包括权限动作、主体范围、条件限制等。
  2. 先将默认策略语句添加到Topic的资源策略中,再添加自定义的策略语句。
  3. 最终生成的SNS Topic资源策略会同时包含默认语句和自定义语句,既保留了账号内主体对Topic的完整管理权限,又允许指定的外部主体执行发布操作。

内容的提问来源于stack exchange,提问作者Liumx31

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:15:33