使用DuckDB通过AWS角色临时凭证访问S3报403错误排查
解决DuckDB使用STS临时凭证访问S3 Parquet文件报403的问题
最直接的修复:补充Session Token配置
临时凭证和IAM用户长期密钥的核心差异之一是临时凭证必须携带Session Token,你的测试代码只配置了access_key_id和secret_access_key,缺少s3_session_token参数,导致DuckDB无法完成身份验证,返回403错误。
修改后的测试代码(从环境变量读取所有凭证参数):
import pandas as pd import duckdb import os # 从环境变量加载临时凭证 access_key = os.getenv('AWS_ACCESS_KEY_ID') secret_key = os.getenv('AWS_SECRET_ACCESS_KEY') session_token = os.getenv('AWS_SESSION_TOKEN') query = f""" INSTALL httpfs; LOAD httpfs; SET s3_region='us-west-2'; SET s3_access_key_id='{access_key}'; SET s3_secret_access_key='{secret_key}'; SET s3_session_token='{session_token}'; SELECT * FROM read_parquet('s3://bucket/folder/file.parquet') """ cursor = duckdb.connect() cursor.execute(query).df()
IAM角色与IAM用户的核心差异(导致问题的关键)
- 凭证构成不同:IAM用户使用长期访问密钥(仅AccessKeyId + SecretAccessKey);IAM角色的临时凭证必须包含三个参数:AccessKeyId、SecretAccessKey、SessionToken,缺少任何一个都会验证失败。
- 生命周期不同:用户密钥长期有效(需手动轮换);角色临时凭证默认1小时过期,最长可设置12小时,自动失效。
- 身份切换逻辑:角色需要通过STS服务的
assume-role操作获取凭证,依赖信任关系验证请求者是否有权扮演该角色;用户密钥直接关联身份,无需额外切换步骤。
额外排查点(若补充Session Token后仍报错)
- 检查角色信任关系:确保执行
assume-role的实体(比如你的测试用IAM用户)被允许扮演目标角色。角色的信任策略中需包含该实体的ARN,示例信任策略:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<account-id>:user/<your-iam-user>" }, "Action": "sts:AssumeRole" } ] } - 验证S3桶策略:如果桶有自定义策略,需确认策略允许目标角色访问。比如在桶策略的
Principal中添加角色ARN,或确保策略的Condition不限制角色的访问:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<account-id>:role/<your-role-name>" }, "Action": ["s3:GetObject", "s3:ListBucket"], "Resource": [ "arn:aws:s3:::bucket", "arn:aws:s3:::bucket/folder/*" ] } ] } - 确认角色权限完整性:虽然你提到角色和用户权限相同,但需再次核对角色是否包含
s3:GetObject、s3:ListBucket(如果需要遍历目录)等必要权限,权限范围需覆盖目标Parquet文件的路径。
内容的提问来源于stack exchange,提问作者A Simple Programmer
相关产品推荐
相关产品推荐

