使用 IAM 角色的临时凭据

AWSBeginner
立即练习

介绍

一个工作进程需要通过临时作业身份访问报表。你将创建角色,选择谁可以使用它,测试读取权限,并在清理前撤销访问。

请先完成 为报表读取者授予最小权限,掌握策略字段和请求边界。这个全新 VM 已准备好 default、worker 和 outsider 配置档。使用 /home/labex/project 和 AWS View,不需要设置个人账户。请保密凭据文件、CLI 缓存和未经筛选的 AssumeRole 响应。

认证考点

认证 考点 本实验练习
Cloud Practitioner (CLF-C02) 任务 2.3 IAM 角色信任、临时会话与资源访问。
Solutions Architect – Associate (SAA-C03) 任务 1.1 IAM 角色信任、临时会话与资源访问。
Developer – Associate (DVA-C02) 任务 2.1 IAM 角色信任、临时会话与资源访问。
CloudOps Engineer – Associate (SOA-C03) 任务 4.1 IAM 角色信任、临时会话与资源访问。
Security – Specialty (SCS-C03) 任务 4.1, 任务 4.2 基础练习:IAM 角色信任、临时会话与资源访问;IAM 策略、操作与资源范围及最小权限。
Data Engineer – Associate (DEA-C01) 任务 4.1 基础练习:IAM 角色信任、临时会话与资源访问。
DevOps Engineer – Professional (DOP-C02) 任务 6.1 基础练习:IAM 角色信任、临时会话与资源访问。
Solutions Architect – Professional (SAP-C02) 任务 2.3 基础练习:IAM 角色信任、临时会话与资源访问。

实验概览

概念图:角色信任决定谁可以获得 ReportReader 临时会话;角色权限将该会话限制为读取 S3 中今天的报表。

定义角色信任和读取权限

在本步骤中,你将创建 ReportReader,并通过信任策略指定允许的调用者。信任策略(trust policy)是角色上的资源策略:Principal 标识谁可以代入角色。角色权限策略则单独定义所得会话可以做什么。

报表作业现在需要临时角色会话。用熟悉的 Action 和 Resource 字段定义 S3 工作权限,用独立的信任策略决定谁能进入角色。撤权前,你会分别测试这两个决定。

IAM 角色(role)定义权限及谁可以代入它。AWS Security Token Service(STS,安全令牌服务)为角色会话签发临时凭据,该会话身份不同于调用者。

信任控制谁能进入角色;角色权限控制所得会话可以做什么。

确认工作进程的 ARN,以便与初始信任比较。

cd /home/labex/project
aws sts get-caller-identity --profile worker --query Arn --output text

预期为 arn:aws:iam::123456789012:user/report-worker。先建立只指定操作员的信任。sts:AssumeRole 请求角色会话;Principal 是身份 ARN,不是配置档名称。工作进程暂时刻意不被信任。

cat > trust.json <<'JSON'
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:user/iam03-operator"},"Action":"sts:AssumeRole"}]}
JSON
aws iam create-role \
  --role-name ReportReader \
  --assume-role-policy-document file://trust.json \
  --query Role.Arn \
  --output text

预期 ARN 以 role/ReportReader 结尾。创建角色不会赋予 S3 权限。添加一份限定范围的内联策略:角色只能对今天的报表执行 GetObject,不能写入报表或读取工资数据。

cat > role-policy.json <<'JSON'
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"arn:aws:s3:::labex-iam03-reports/reports/today.txt"}]}
JSON
aws iam put-role-policy \
  --role-name ReportReader \
  --policy-name ReportRead \
  --policy-document file://role-policy.json
aws iam get-role --role-name ReportReader --query Role.AssumeRolePolicyDocument
aws iam get-role-policy \
  --role-name ReportReader \
  --policy-name ReportRead \
  --query PolicyDocument

读回两份文档。信任控制进入角色,角色权限控制会话操作。工作进程仍未被信任。测试这个入口,只选择安全的返回 ARN 字段。

aws sts assume-role --profile worker --role-arn arn:aws:iam::123456789012:role/ReportReader --role-session-name report-run --query AssumedRoleUser.Arn --output text || true

预期为 AccessDenied。不要移除查询过滤:成功的完整响应包含秘密。

授权调用者并使用角色配置档

在本步骤中,你将允许工作进程请求 ReportReader,更新角色信任,并使用角色配置档。两个测试用户都会获得相同的调用者权限;只有被信任的工作进程应获得角色会话。

编写 Resource 为准确角色 ARN 的调用者策略,再将它附加到工作进程。

cat > assume-policy.json <<'JSON'
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"sts:AssumeRole","Resource":"arn:aws:iam::123456789012:role/ReportReader"}]}
JSON
aws iam put-user-policy \
  --user-name report-worker \
  --policy-name AssumeReportReader \
  --policy-document file://assume-policy.json

为单独测试信任检查,给 outsider 相同的限定调用者权限。这个一次性对照用户不在信任文档中。

aws iam put-user-policy \
  --user-name outsider \
  --policy-name AssumeReportReader \
  --policy-document file://assume-policy.json
aws sts assume-role --profile worker --role-arn arn:aws:iam::123456789012:role/ReportReader --role-session-name before-trust --query AssumedRoleUser.Arn --output text || true

预期为 AccessDenied:身份上的 Allow 不能覆盖已有的只指定操作员的信任。将信任替换为目标工作进程,并更新角色。

cat > trust.json <<'JSON'
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:user/report-worker"},"Action":"sts:AssumeRole"}]}
JSON
aws iam update-assume-role-policy \
  --role-name ReportReader \
  --policy-document file://trust.json
aws sts assume-role --profile outsider --role-arn arn:aws:iam::123456789012:role/ReportReader --role-session-name outsider-test --query AssumedRoleUser.Arn --output text || true

即使 outsider 的身份策略允许 AssumeRole,预期仍为 AccessDenied。它的 ARN 不被信任。以工作进程身份重复:

aws sts assume-role \
  --profile worker \
  --role-arn arn:aws:iam::123456789012:role/ReportReader \
  --role-session-name report-run \
  --query AssumedRoleUser.Arn \
  --output text

角色信任决定哪个调用者可以进入。身份 Allow 不能绕过它。对于同账户中直接指定用户的信任,该信任可以在没有独立身份 Allow 的情况下授予进入权限;这里相同的调用者授权用于单独比较信任。

预期 ARN 以 assumed-role/ReportReader/report-run 结尾。会话名称有助于在活动记录中区分角色使用。角色凭据会过期;下面的 CLI 角色配置档会为你获取临时凭据。

配置已准备好的 report-role 配置档,让它自动请求这些临时凭据。source_profile 选择调用者,role_arn 选择目标角色。这些设置不包含秘密值。CLI 安全存储临时缓存;不要打印它。

aws configure set role_arn arn:aws:iam::123456789012:role/ReportReader --profile report-role
aws configure set source_profile worker --profile report-role
aws configure set role_session_name report-run --profile report-role
aws sts get-caller-identity --profile report-role --query Arn --output text

预期再次获得 assumed-role ARN。CLI 在内部为这个配置档执行 STS 身份验证。工作进程身份本身拥有 AssumeRole 权限,不拥有角色的 S3 权限。

aws s3api get-object --profile worker --bucket labex-iam03-reports --key reports/today.txt direct-worker.txt || true

预期为 AccessDenied。代入角色不会将角色权限附加回源用户。

测试角色会话的资源和操作边界

在本步骤中,你将使用角色配置档执行报表作业,并确认它不能执行无关工作。成功的 AssumeRole 请求只证明可以进入角色;实际 S3 请求证明有效访问权限。

aws s3api get-object \
  --profile report-role \
  --bucket labex-iam03-reports \
  --key reports/today.txt today.txt
cat today.txt

预期为 Daily orders: 145。尝试访问角色准确对象 ARN 之外的两个已有资源。

aws s3api get-object --profile report-role --bucket labex-iam03-reports --key private/payroll.txt private-denied.txt || true
aws s3api get-object --profile report-role --bucket labex-iam03-reference --key reference.txt reference-denied.txt || true

两者都必须返回 AccessDenied。再尝试用提供的未批准替换文件覆盖今天的报表。GetObject 不授权 PutObject。

aws s3api put-object --profile report-role --bucket labex-iam03-reports --key reports/today.txt --body upload.txt || true
aws s3api get-object \
  --profile report-role \
  --bucket labex-iam03-reports \
  --key reports/today.txt today.txt
cat today.txt

预期 PutObject 返回 AccessDenied,报表仍为 Daily orders: 145。本地文件缺失、凭据过期错误或服务不可用属于不同诊断,不能证明权限边界。AWS View 显示存储的信任、角色策略和实际角色会话读取;展开今天的报表,查看字节内容。

角色会话只读取报表. 示例:信任指定 report-worker,调用者为 assumed-role 会话,且只有报表可读。展开的对象显示实际返回字节。

撤销角色访问并清理

在本步骤中,你将在删除角色数据前移除角色的报表授权。移除角色权限和阻止新的角色代入是不同操作;仅清除本地缓存不会撤销服务端权限。

角色和报表仍存在时移除 ReportRead,再通过角色配置档重复读取。

aws iam delete-role-policy --role-name ReportReader --policy-name ReportRead
aws s3api get-object --profile report-role --bucket labex-iam03-reports --key reports/today.txt revoked.txt || true

预期为 AccessDenied。移除两个调用者授权,并将直接信任工作进程改为只信任操作员。仅移除身份 Allow 不会撤销同账户直接信任授权。再测试工作进程无法获取新会话。

aws iam delete-user-policy --user-name report-worker --policy-name AssumeReportReader
aws iam delete-user-policy --user-name outsider --policy-name AssumeReportReader
cat > trust.json <<'JSON'
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:user/iam03-operator"},"Action":"sts:AssumeRole"}]}
JSON
aws iam update-assume-role-policy \
  --role-name ReportReader \
  --policy-document file://trust.json
aws sts assume-role --profile worker --role-arn arn:aws:iam::123456789012:role/ReportReader --role-session-name after-revocation --query AssumedRoleUser.Arn --output text || true

角色仍存在时,预期为 AccessDenied。只在这些功能性撤销检查后删除角色。

aws iam delete-role --role-name ReportReader
aws iam list-roles --query 'Roles[].RoleName'
aws s3api delete-object --bucket labex-iam03-reports --key reports/today.txt
aws s3api delete-object --bucket labex-iam03-reports --key private/payroll.txt
aws s3api list-objects-v2 --bucket labex-iam03-reports

预期角色列表为空,对象响应中有 KeyCount: 0。删除自己的空桶,再确认参考资源仍存在,且字节未变。

aws s3api delete-bucket --bucket labex-iam03-reports
aws s3api list-buckets --query 'Buckets[].Name'
aws s3api get-object --bucket labex-iam03-reference --key reference.txt reference.txt
cat reference.txt

只剩下参考桶,内容为 Platform reference: keep。这些成功查询证明删除和保留。一次性环境结束时,会回收已准备好的身份和临时凭据文件。你已删除本练习创建的角色和调用者授权。

总结

你区分了角色信任和权限策略,证明单独的调用者授权不能绕过信任,并通过 CLI 角色配置档使用 STS。角色会话只能读取自己的报表,不能写入或读取无关数据。你在限定范围的清理前移除了角色和调用者授权。工作负载应优先使用临时角色而非永久密钥;诊断访问时,检查实际身份及允许和拒绝的请求。

进一步阅读 AWS 官方资料:IAM 角色、信任与临时凭据.