AWS STS 临时凭证 S3 访问被拒绝 PutObject
AWS STS Temporary Credentials S3 Access Denied PutObject
我正在关注 How to Use AWS IAM with STS for access to AWS resources - 2nd Watch 博客 post,我的理解是 S3 Bucket Policy Principal 请求临时凭证,一种方法是硬编码该用户的 ID,但 post 尝试一种更优雅的方法来评估 STS 委托用户(当它工作时)。
arn:aws:iam::409812999999999999:policy/fts-assume-role
IAM 用户策略
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "*"
}
]
}
arn:aws:s3:::finding-taylor-swift
s3 存储桶策略
{
"Version": "2012-10-17",
"Id": "Policy1581282599999999999",
"Statement": [
{
"Sid": "Stmt158128999999999999",
"Effect": "Allow",
"Principal": {
"Service": "sts.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::finding-taylor-swift/*"
}
]
}
conor@xyz:~$ aws configure --profile finding-taylor-swift
AWS Access Key ID [****************6QNY]:
AWS Secret Access Key [****************+8kF]:
Default region name [eu-west-2]:
Default output format [text]: json
conor@xyz:~$ aws sts get-session-token --profile finding-taylor-swift
{
"Credentials": {
"SecretAccessKey": "<some text>",
"SessionToken": "<some text>",
"Expiration": "2020-02-11T03:31:50Z",
"AccessKeyId": "<some text>"
}
}
conor@xyz:~$ export AWS_SECRET_ACCESS_KEY=<some text>
conor@xyz:~$ export AWS_SESSION_TOKEN=<some text>
conor@xyz:~$ export AWS_ACCESS_KEY_ID=<some text>
conor@xyz:~$ aws s3 cp dreamstime_xxl_concert_profile_w500_q8.jpg s3://finding-taylor-swift
upload failed: ./dreamstime_xxl_concert_profile_w500_q8.jpg to s3://finding-taylor-swift/dreamstime_xxl_concert_profile_w500_q8.jpg An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
conor@xyz:~$
已按照 Using Temporary Security Credentials with the AWS CLI
中所述设置 AWS CLI
“当您 运行 AWS CLI 命令时,AWS CLI 按特定顺序查找凭证——首先在环境变量中,然后在配置文件中。因此,在您将临时凭证放入环境变量,AWS CLI 默认使用这些凭证。(如果您在命令中指定配置文件参数,AWS CLI 会跳过环境变量。相反,AWS CLI 会查看配置文件,这让您可以覆盖配置文件中的凭证如果需要,可以使用环境变量。)
以下示例展示了如何为临时安全凭证设置环境变量,然后调用 AWS CLI 命令。由于 AWS CLI 命令中不包含配置文件参数,AWS CLI 首先在环境变量中查找凭证,因此使用临时凭证。"
您的方案无需使用 存储桶策略 。存储桶策略应用于 Amazon S3 存储桶,通常用于授予特定于该存储桶的访问权限(例如 public 访问权限)。
使用 IAM 角色
如果您希望向特定 IAM 用户、IAM 组或 IAM 角色提供存储桶访问权限,则应将权限附加到 IAM 实体而不是存储桶。
(对于get-session-token
,见我的回答结尾。)
设置
让我们首先创建一个类似于您所拥有的 IAM 角色。我选择 Create role,然后对于可信实体我 select Another AWS account(因为它将由 IAM 用户承担,而不是服务)。
然后我在 IAM 角色上创建一个内联策略以允许访问存储桶:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket"
}
]
}
(分配 s3:*
权限通常不是一个好主意,因为这会让用户删除内容甚至删除存储桶。尽量将其限制为实际需要的最低权限。)
IAM 角色的信任关系 决定谁可以承担 角色。它可以是一个人,也可以是帐户中的任何人(只要他们被授予调用 AssumeRole
的权限)。就我而言,我会将其分配给整个帐户:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::MY-ACCOUNT-ID:root"
},
"Action": "sts:AssumeRole"
}
]
}
现在有几种不同的方式来承担这个角色...
简单方法:凭证文件中的 IAM 角色
AWS CLI 能够在凭证文件中指定一个 IAM 角色,它会自动为您代入该角色。
参见:Using an IAM Role in the AWS CLI
为了使用它,我在 .aws/config
文件中添加了一个部分:
[profile foo]
role_arn = arn:aws:iam::MY-ACCOUNT-ID:role/MY-ROLE-NAME
source_profile = default
然后我可以简单地使用它:
aws s3 ls s3://my-bucket --profile foo
这成功地让我访问了那个特定的存储桶。
复杂方法:自己担任角色
与其让 AWS CLI 完成所有工作,我还可以自己承担这个角色:
aws sts assume-role --role-arn arn:aws:iam::MY-ACCOUNT-ID:role/MY-ROLE-NAME --role-session-name foo
{
"Credentials": {
"AccessKeyId": "ASIA...",
"SecretAccessKey": "...",
"SessionToken": "...",
"Expiration": "2020-02-11T00:43:30+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "AROA...:foo",
"Arn": "arn:aws:sts::MY-ACCOUNT-ID:assumed-role/MY-ROLE-NAME/foo"
}
}
然后我将此信息附加到 .aws/credentials
文件:
[foo2]
aws_access_key_id = ASIA...
aws_secret_access_key = ...
aws_security_token= ...
是的,您可以使用 aws configure --foo2
将其添加到凭据文件中,但它不会提示输入安全令牌。因此,无论如何您都需要编辑凭据文件以添加该信息。
然后我使用了配置文件:
aws s3 ls s3://my-bucket --profile foo2
它让我成功访问和使用了存储桶。
使用 GetSessionToken
以上示例使用 IAM 角色。这通常用于授予跨帐户访问权限或临时假定更强大的凭据(例如,管理员执行敏感操作)。
您的问题引用了 get-session-token
。这提供了基于用户现有凭据和权限的临时凭据。因此,作为此 API 调用的一部分,他们无法获得额外的权限。
此调用通常用于提供 MFA 令牌或提供用于测试目的的限时凭据。例如,我可以为您提供有效地让您使用我的 IAM 用户的凭据,但仅限于有限的时间。
我正在关注 How to Use AWS IAM with STS for access to AWS resources - 2nd Watch 博客 post,我的理解是 S3 Bucket Policy Principal 请求临时凭证,一种方法是硬编码该用户的 ID,但 post 尝试一种更优雅的方法来评估 STS 委托用户(当它工作时)。
arn:aws:iam::409812999999999999:policy/fts-assume-role
IAM 用户策略
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "*"
}
]
}
arn:aws:s3:::finding-taylor-swift
s3 存储桶策略
{
"Version": "2012-10-17",
"Id": "Policy1581282599999999999",
"Statement": [
{
"Sid": "Stmt158128999999999999",
"Effect": "Allow",
"Principal": {
"Service": "sts.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::finding-taylor-swift/*"
}
]
}
conor@xyz:~$ aws configure --profile finding-taylor-swift
AWS Access Key ID [****************6QNY]:
AWS Secret Access Key [****************+8kF]:
Default region name [eu-west-2]:
Default output format [text]: json
conor@xyz:~$ aws sts get-session-token --profile finding-taylor-swift
{
"Credentials": {
"SecretAccessKey": "<some text>",
"SessionToken": "<some text>",
"Expiration": "2020-02-11T03:31:50Z",
"AccessKeyId": "<some text>"
}
}
conor@xyz:~$ export AWS_SECRET_ACCESS_KEY=<some text>
conor@xyz:~$ export AWS_SESSION_TOKEN=<some text>
conor@xyz:~$ export AWS_ACCESS_KEY_ID=<some text>
conor@xyz:~$ aws s3 cp dreamstime_xxl_concert_profile_w500_q8.jpg s3://finding-taylor-swift
upload failed: ./dreamstime_xxl_concert_profile_w500_q8.jpg to s3://finding-taylor-swift/dreamstime_xxl_concert_profile_w500_q8.jpg An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
conor@xyz:~$
已按照 Using Temporary Security Credentials with the AWS CLI
中所述设置 AWS CLI“当您 运行 AWS CLI 命令时,AWS CLI 按特定顺序查找凭证——首先在环境变量中,然后在配置文件中。因此,在您将临时凭证放入环境变量,AWS CLI 默认使用这些凭证。(如果您在命令中指定配置文件参数,AWS CLI 会跳过环境变量。相反,AWS CLI 会查看配置文件,这让您可以覆盖配置文件中的凭证如果需要,可以使用环境变量。)
以下示例展示了如何为临时安全凭证设置环境变量,然后调用 AWS CLI 命令。由于 AWS CLI 命令中不包含配置文件参数,AWS CLI 首先在环境变量中查找凭证,因此使用临时凭证。"
您的方案无需使用 存储桶策略 。存储桶策略应用于 Amazon S3 存储桶,通常用于授予特定于该存储桶的访问权限(例如 public 访问权限)。
使用 IAM 角色
如果您希望向特定 IAM 用户、IAM 组或 IAM 角色提供存储桶访问权限,则应将权限附加到 IAM 实体而不是存储桶。
(对于get-session-token
,见我的回答结尾。)
设置
让我们首先创建一个类似于您所拥有的 IAM 角色。我选择 Create role,然后对于可信实体我 select Another AWS account(因为它将由 IAM 用户承担,而不是服务)。
然后我在 IAM 角色上创建一个内联策略以允许访问存储桶:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket"
}
]
}
(分配 s3:*
权限通常不是一个好主意,因为这会让用户删除内容甚至删除存储桶。尽量将其限制为实际需要的最低权限。)
IAM 角色的信任关系 决定谁可以承担 角色。它可以是一个人,也可以是帐户中的任何人(只要他们被授予调用 AssumeRole
的权限)。就我而言,我会将其分配给整个帐户:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::MY-ACCOUNT-ID:root"
},
"Action": "sts:AssumeRole"
}
]
}
现在有几种不同的方式来承担这个角色...
简单方法:凭证文件中的 IAM 角色
AWS CLI 能够在凭证文件中指定一个 IAM 角色,它会自动为您代入该角色。
参见:Using an IAM Role in the AWS CLI
为了使用它,我在 .aws/config
文件中添加了一个部分:
[profile foo]
role_arn = arn:aws:iam::MY-ACCOUNT-ID:role/MY-ROLE-NAME
source_profile = default
然后我可以简单地使用它:
aws s3 ls s3://my-bucket --profile foo
这成功地让我访问了那个特定的存储桶。
复杂方法:自己担任角色
与其让 AWS CLI 完成所有工作,我还可以自己承担这个角色:
aws sts assume-role --role-arn arn:aws:iam::MY-ACCOUNT-ID:role/MY-ROLE-NAME --role-session-name foo
{
"Credentials": {
"AccessKeyId": "ASIA...",
"SecretAccessKey": "...",
"SessionToken": "...",
"Expiration": "2020-02-11T00:43:30+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "AROA...:foo",
"Arn": "arn:aws:sts::MY-ACCOUNT-ID:assumed-role/MY-ROLE-NAME/foo"
}
}
然后我将此信息附加到 .aws/credentials
文件:
[foo2]
aws_access_key_id = ASIA...
aws_secret_access_key = ...
aws_security_token= ...
是的,您可以使用 aws configure --foo2
将其添加到凭据文件中,但它不会提示输入安全令牌。因此,无论如何您都需要编辑凭据文件以添加该信息。
然后我使用了配置文件:
aws s3 ls s3://my-bucket --profile foo2
它让我成功访问和使用了存储桶。
使用 GetSessionToken
以上示例使用 IAM 角色。这通常用于授予跨帐户访问权限或临时假定更强大的凭据(例如,管理员执行敏感操作)。
您的问题引用了 get-session-token
。这提供了基于用户现有凭据和权限的临时凭据。因此,作为此 API 调用的一部分,他们无法获得额外的权限。
此调用通常用于提供 MFA 令牌或提供用于测试目的的限时凭据。例如,我可以为您提供有效地让您使用我的 IAM 用户的凭据,但仅限于有限的时间。