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:
- 创建一个IAM角色,信任策略设置为允许
cognito-idp.amazonaws.com扮演该角色:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "cognito-idp.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } - 给这个角色附加权限策略,允许调用目标Lambda函数:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:your-region:your-account-id:function:your-lambda-name" } ] } - 在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
相关产品推荐
相关产品推荐

