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

AWS Lambda调用AddPermission遇PolicyLengthExceededException问题求助

解决Lambda AddPermission触发PolicyLengthExceededException的问题

我之前处理过类似的Lambda权限策略超限问题,很清楚你碰到的这个坑,咱们一步步来拆解原因和解决办法:

问题原因

Lambda的资源策略有严格的大小限制(最多20480字符),每次调用AddPermission API都会往Lambda的资源策略里追加一条新的Statement。你代码里用customerId拼接生成唯一的StatementId,意味着每个客户都会新增一条独立的权限语句——随着客户数量增加,策略里的语句会越来越多,最终超过字符限制触发PolicyLengthExceededException。

解决方案

1. 合并权限语句,避免重复添加

不要给每个客户单独创建权限条目,而是用通配符或条件匹配批量覆盖合法的Cognito用户池来源:

  • 如果你的用户池ARN有统一的命名规则(比如包含特定前缀/后缀),可以直接用通配符简化SourceArn:
    actionString := "lambda:InvokeFunction"
    principalString := "cognito-idp.amazonaws.com"
    // 用通配符匹配符合规则的所有用户池
    sourceArn := "arn:aws:cognito-idp:your-region:your-account-id:userpool/*-prefix-*"
    // 使用固定的StatementId,避免重复添加
    statementIdString := "CognitoPostConfirmationInvokeAll"
    addPermissionInput := &lambda.AddPermissionInput{
        Action:        aws.String(actionString),
        FunctionName:  aws.String(lambdaFunctionName),
        Principal:     aws.String(principalString),
        SourceArn:     aws.String(sourceArn),
        StatementId:   aws.String(statementIdString),
    }
    
  • 如果需要更精细的控制,可以用Condition字段(Go SDK对应lambda.AddPermissionInput.Condition),比如匹配用户池ARN的特定模式:
    import "github.com/aws/aws-sdk-go-v2/aws"
    
    // 构建Condition,只允许指定前缀的用户池调用
    condition := map[string]map[string]string{
        "StringLike": {
            "lambda:SourceArn": "arn:aws:cognito-idp:your-region:your-account-id:userpool/customer-*",
        },
    }
    
    addPermissionInput := &lambda.AddPermissionInput{
        Action:        aws.String(actionString),
        FunctionName:  aws.String(lambdaFunctionName),
        Principal:     aws.String(principalString),
        // 结合Condition实现批量匹配
        SourceArn:     aws.String("arn:aws:cognito-idp:your-region:your-account-id:userpool/"),
        StatementId:   aws.String("CognitoPostConfirmationConditional"),
        Condition:     condition,
    }
    

2. 改用IAM角色控制访问(更推荐的长期方案)

绕过Lambda资源策略的限制,用IAM角色来授权Cognito调用Lambda:

  1. 创建一个IAM角色,信任策略设置为允许cognito-idp.amazonaws.com扮演该角色:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Service": "cognito-idp.amazonaws.com"
          },
          "Action": "sts:AssumeRole"
        }
      ]
    }
    
  2. 给这个角色附加权限策略,允许调用目标Lambda函数:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "lambda:InvokeFunction",
          "Resource": "arn:aws:lambda:your-region:your-account-id:function:your-lambda-name"
        }
      ]
    }
    
  3. 在Cognito用户池的Post Confirmation触发器配置里,指定这个IAM角色的ARN——这样Cognito会通过角色来调用Lambda,不再需要给Lambda添加大量的资源策略条目。

3. 清理冗余的权限语句

如果已经积累了很多旧的权限条目,可以调用RemovePermission API删除不再需要的Statement,临时降低策略大小:

// 示例:删除特定StatementId的权限
removePermissionInput := &lambda.RemovePermissionInput{
    FunctionName: aws.String(lambdaFunctionName),
    StatementId:  aws.String("cognitoaddpermission-old-customer-id"),
}
_, err := lambdaSessionClient.RemovePermission(removePermissionInput)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:47:01