CloudFormation中API Gateway代理OpenSearch请求的权限问题排查
问题排查:API Gateway代理OpenSearch时的匿名权限错误
问题描述
通过CloudFormation搭建文档自动索引到OpenSearch的架构:S3存储桶存入文件时触发Lambda函数,Lambda转换数据后通过API Gateway代理请求到OpenSearch。此前直接调用OpenSearch时SigV4签名失败,改用API Gateway代理后签名问题解决,但持续收到权限错误:
User: anonymous is not authorized to perform: es:ESHttpPut because no resource-based policy allows the es:ESHttpPut action
已配置OpenSearch资源策略允许API Gateway角色执行相关操作:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAPIGatewayAccess", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNT_ID:role/ingest-app-APIGatewayRole" }, "Action": [ "es:ESHttpGet", "es:ESHttpPost", "es:ESHttpPut", "es:ESHttpDelete" ], "Resource": "arn:aws:es:REGION:ACCOUNT_ID:domain/ingest-app-domain/*" } ] }
核心问题分析
错误提示显示请求以匿名身份发送到OpenSearch,说明API Gateway未使用指定的IAM角色对请求进行SigV4签名,导致OpenSearch无法识别请求身份。结合CloudFormation模板,主要问题点如下:
- API Gateway的HTTP_PROXY集成未启用SigV4认证,即使配置了Credentials也不会自动签名
- 根路径方法(GatewayRootMethod)未配置Credentials,若有请求走根路径会直接匿名访问
- OpenSearch资源策略的Resource范围可能存在匹配问题
修复步骤
1. 为API Gateway集成添加SigV4签名配置
修改CloudFormation模板中API Gateway的方法集成,启用AWS_IAM认证并指定角色,确保请求被正确签名:
更新GatewayProxyMethod
GatewayProxyMethod: Type: AWS::ApiGateway::Method Properties: ResourceId: !Ref GatewayProxy RestApiId: !Ref Gateway HttpMethod: ANY AuthorizationType: NONE RequestParameters: method.request.path.proxy: true Integration: IntegrationHttpMethod: "ANY" Type: HTTP_PROXY Uri: !Sub "${OpenSearchDomainEndpoint}/{proxy}" RequestParameters: integration.request.path.proxy: "method.request.path.proxy" Credentials: !GetAtt APIGatewayRole.Arn # 新增SigV4相关配置 AuthType: AWS_IAM IntegrationCredentials: !GetAtt APIGatewayRole.Arn ConnectionType: INTERNET PassthroughBehavior: WHEN_NO_MATCH
更新GatewayRootMethod
GatewayRootMethod: Type: AWS::ApiGateway::Method Properties: ResourceId: !GetAtt Gateway.RootResourceId RestApiId: !Ref Gateway HttpMethod: ANY AuthorizationType: NONE Integration: IntegrationHttpMethod: "ANY" Type: "HTTP_PROXY" Uri: !Sub "${OpenSearchDomainEndpoint}/" # 新增Credentials和SigV4配置 Credentials: !GetAtt APIGatewayRole.Arn AuthType: AWS_IAM IntegrationCredentials: !GetAtt APIGatewayRole.Arn ConnectionType: INTERNET PassthroughBehavior: WHEN_NO_MATCH
2. 修正OpenSearch资源策略
调整Resource范围,确保覆盖所有子路径(去掉末尾的/避免匹配问题),并验证Principal ARN与实际IAM角色完全一致:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAPIGatewayAccess", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:role/ingest-app-APIGatewayRole" }, "Action": [ "es:ESHttpGet", "es:ESHttpPost", "es:ESHttpPut", "es:ESHttpDelete" ], "Resource": "arn:aws:es:us-east-1:123456789012:domain/ingest-app-domain*" } ] }
3. 重新部署API Gateway
确保CloudFormation模板更新后完成部署,验证prod阶段关联了最新的Deployment。可通过API Gateway控制台确认部署状态。
验证方法
- 查看API Gateway的CloudWatch访问日志(GatewayLogGroup),检查
context.identity.caller字段是否显示APIGatewayRole的ARN,确认身份已正确传递 - 手动调用API Gateway端点发送PUT请求,验证是否返回成功响应
- 检查OpenSearch的访问日志,确认请求来源为API Gateway角色
内容的提问来源于stack exchange,提问作者Tom Cardoso
相关产品推荐
相关产品推荐

