跨账号S3访问:Account-A Lambda如何通过IAM用户权限访问Account-B存储桶
让我来一步步解答你的这两个问题,都是Lambda和S3权限访问的常见场景:
问题1:当IAM用户拥有S3存储桶访问权限时,如何从Lambda函数进行访问?
首先明确:Lambda函数不应该直接使用IAM用户的长期凭证(比如Access Key/Secret Key),这是违反AWS安全最佳实践的,长期凭证泄露风险极高。正确的做法是利用Lambda的执行角色来获取访问权限,具体步骤如下:
配置Lambda执行角色的权限
- 如果你已经有一个具备S3访问权限的IAM用户,可以把该用户的权限策略复制出来,附加到Lambda的执行角色上;或者直接给执行角色创建一个新的权限策略,包含你需要的S3操作(比如
s3:GetObject、s3:ListBucket等),资源指定为目标S3桶或对象ARN。 - 同时确保这个执行角色的信任策略允许Lambda服务承担它,信任策略大致如下:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
- 如果你已经有一个具备S3访问权限的IAM用户,可以把该用户的权限策略复制出来,附加到Lambda的执行角色上;或者直接给执行角色创建一个新的权限策略,包含你需要的S3操作(比如
在Lambda代码中无需手动指定凭证
AWS SDK(比如Python的boto3、Java的AWS SDK等)会自动从Lambda的运行环境中获取执行角色的临时凭证,你只需要正常初始化S3客户端即可。举个Python的简单示例:import boto3 # 自动获取执行角色的临时凭证,无需手动配置 s3_client = boto3.client('s3') def lambda_handler(event, context): # 示例:读取目标桶中的某个对象 try: response = s3_client.get_object(Bucket="your-target-bucket", Key="example-file.txt") file_content = response['Body'].read().decode('utf-8') return {"statusCode": 200, "body": f"File content: {file_content}"} except Exception as e: return {"statusCode": 500, "body": str(e)}
划重点:除非万不得已,绝对不要把IAM用户的凭证硬编码到代码里,哪怕存在配置文件也不行——临时凭证会自动轮换,安全性远高于长期凭证。
问题2:跨账号场景:Account-A的Lambda访问Account-B的S3桶,是否需要指定IAM用户凭证?
答案是不需要,而且强烈不推荐使用IAM用户凭证。有两种更安全、更合规的替代方案:
方案1:通过S3桶策略+Lambda执行角色实现跨账号访问
这是最直接的方案,适用于只需要访问S3桶的场景:
- 在Account-A中配置Lambda执行角色:给执行角色添加权限策略,允许访问Account-B的目标S3桶,示例策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:GetObject", "s3:ListBucket"], "Resource": [ "arn:aws:s3:::account-b-target-bucket", "arn:aws:s3:::account-b-target-bucket/*" ] } ] } - 在Account-B中配置S3桶策略:添加一条允许Account-A的Lambda执行角色访问该桶的语句,示例:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNT-A-ID:role/your-lambda-execution-role-name" }, "Action": ["s3:GetObject", "s3:ListBucket"], "Resource": [ "arn:aws:s3:::account-b-target-bucket", "arn:aws:s3:::account-b-target-bucket/*" ] } ] } - Lambda代码无需额外修改:和问题1中的代码一样,SDK自动获取执行角色的临时凭证即可访问Account-B的S3桶。
方案2:通过跨账号角色假设实现访问
如果需要访问Account-B中的多个服务,或者需要更细粒度的权限控制,可以用STS角色假设:
- 在Account-B中创建一个跨账号角色:该角色需要具备访问目标S3桶的权限,并且信任策略允许Account-A的Lambda执行角色承担它,信任策略示例:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNT-A-ID:role/your-lambda-execution-role-name" }, "Action": "sts:AssumeRole" } ] } - 在Account-A中给Lambda执行角色添加权限:允许执行角色调用
sts:AssumeRole操作,目标为Account-B的那个角色ARN,示例策略:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::ACCOUNT-B-ID:role/your-cross-account-role-name" } ] } - Lambda代码中调用STS获取临时凭证:用获取到的凭证初始化S3客户端,示例Python代码:
import boto3 def lambda_handler(event, context): # 调用STS假设Account-B的角色 sts_client = boto3.client('sts') assumed_role_response = sts_client.assume_role( RoleArn="arn:aws:iam::ACCOUNT-B-ID:role/your-cross-account-role-name", RoleSessionName="CrossAccountS3AccessSession" ) # 用临时凭证初始化S3客户端 temp_credentials = assumed_role_response['Credentials'] s3_client = boto3.client( 's3', aws_access_key_id=temp_credentials['AccessKeyId'], aws_secret_access_key=temp_credentials['SecretAccessKey'], aws_session_token=temp_credentials['SessionToken'] ) # 访问Account-B的S3桶 try: response = s3_client.get_object(Bucket="account-b-target-bucket", Key="example-file.txt") return {"statusCode": 200, "body": "Successfully accessed cross-account S3 object"} except Exception as e: return {"statusCode": 500, "body": str(e)}
再次强调:无论哪种场景,都不要使用IAM用户的长期凭证,角色-based的访问方式不仅更安全,也更易于管理和审计。
内容的提问来源于stack exchange,提问作者hatellla
相关产品推荐
相关产品推荐

