告别长期密钥:AWS CLI 免密钥登录与策略模拟器实战

用 aws login 换取自动刷新的临时凭证替代长期密钥,再用 IAM policy simulator 在提交前彩排策略行为。
文章梳理了一条免长期密钥的 AWS CLI 工作流:用 `aws login` 把浏览器控制台登录换成 CLI 自动管理的临时凭证,凭证每 15 分钟自动刷新、最长 12 小时,磁盘上不再保存 access key。登录后先用 `aws sts get-caller-identity` 确认身份,再用 IAM policy simulator 的 Custom 模式验证草稿策略,关键是配对一个应通过和一个应失败的用例,才能证明条件确实生效。文章特别提示 2.38.1 起模拟器对每个动作只返回聚合结果,单资源决策需从 `ResourceSpecificResults` 读取,并提醒模拟器存在边界:结果可能与真实环境不一致,它只是排练而非保证。
告别长期密钥:AWS CLI 免密钥登录与策略模拟器实战
把 access key 和 secret 粘贴进配置文件,几乎是每个开发者上手 AWS CLI 的第一课。这个动作留下的是一把长期有效的密钥,静静躺在你的笔记本里。接着你得写一条权限策略,而它到底允许了什么、拒绝了什么,往往要等到某个服务报错才真相大白。
本文基于一篇 AWS CLI 实战教程,梳理两条替代路径:用 aws login 把普通的控制台登录换成 CLI 自动管理的临时凭证,以及用 IAM policy simulator 在不发出任何真实请求的前提下验证一条策略的行为。两者结合,你既不用在磁盘上保存长期密钥,也能在策略造成实际影响之前先做一次彩排。需要提前说明的是:模拟器是排练,不是保证,它在哪里失灵同样值得搞清楚。

三步走:登录、验证、清理
整个流程被拆成三个有严格顺序的任务:
- 不使用 access key 登录 CLI,并确认它当前以什么身份在行动;
- 写一条策略,并在模拟器中证明它的行为符合预期;
- 找到会话的存储位置,查看它,然后删除它。
顺序不能乱。第二个任务里的每一条模拟器命令本身都是 AWS CLI 调用,因此依赖第一个任务产生的凭证;第三个任务则负责清理第一个任务留下的痕迹。这种"先建立临时身份、再拿它做验证、最后回收"的结构,正是免长期密钥工作流的核心。
版本门槛与身份前提
aws login 要求 AWS CLI 版本不低于 2.32.0。该教程基于 2.38.1 编写,远高于这个下限。用全局 --version 选项确认本机版本:
$ aws --version
除了版本,你还需要一个能登录 AWS 管理控制台的身份——根用户、IAM 用户,或者来自身份提供商的联合身份都可以。如果组织使用 IAM Identity Center,则要走另一套配置路径。
这个身份还必须被允许使用该登录方式:给 IAM 用户、角色或用户组挂上 SignInLocalDevelopmentAccess 托管策略。根用户不需要额外权限,但在共享账号上为了做实验而登录根用户是很糟糕的习惯,更合理的默认选择是携带上述托管策略的 IAM 用户或联合身份。
什么是 SignInLocalDevelopmentAccess 托管策略。 这是 AWS 在 2024 年为配合 aws login 推出的 AWS 托管策略,语义非常窄:它只授权主体通过本地开发登录流程获取临时凭证,不附带任何对业务资源的访问权。换言之,它是一个"准入证"而非"通行证"——挂上它只是让你有资格走 aws login 这条路,登录后能做什么仍然由你原有的权限策略决定。正因为权限边界清楚,把它附加到 IAM 用户、角色或用户组上,比为了做实验而使用根用户要安全得多;根用户天生具备该能力,无需附加任何策略,但它同时也是最不该日常使用的身份。
什么是 IAM Identity Center 路径。 IAM Identity Center(原 AWS SSO)是面向多账号组织的集中式身份与访问管理服务:管理员在组织层面统一配置用户、权限集与账号分配,用户通过一次登录获得多个账号的短期凭证。它的 CLI 集成方式是 aws configure sso 加 aws sso login,凭证同样落在本地缓存而非长期密钥,但配置流程、profile 结构和登出命令(aws sso logout)都与 aws login 不同。文章中明确把 IAM Identity Center 划为"另一套配置路径",正是提醒读者不要混用两者。
aws login 如何把控制台登录变成临时凭证
在终端直接运行:
$ aws login
若要登录到指定(或新建)的 profile,加上 --profile:
$ aws login --profile my-dev-profile
如果 profile 是新的,或者尚未设置 Region,CLI 会询问 Region 并默认推荐 us-east-1,之后可以用 aws configure set region NEW_REGION 更改。
接着 CLI 会尝试打开默认浏览器进入登录页。你既可以挑选一个已激活的控制台会话,也可以重新登录。在浏览器里选定要使用的凭证,然后回到终端。
有一个容易被忽略的细节:如果该 profile 里已经存着另一个会话——比如原先配置成只读用户,而你现在以管理员身份登录——CLI 会询问是否覆盖已有会话,并等待你输入 y 或 n。
对于没有浏览器的机器(例如远程服务器),使用 aws login --remote,CLI 会打印一个 URL 让你在别的设备上打开,登录后把授权码复制回 CLI 提示符即可。这两种流程各有独立的资源 ARN,可以在 IAM 策略中分别允许或拒绝,这意味着团队可以精细控制"同设备登录"和"跨设备登录"哪一条被放行。
临时凭证与刷新机制的基本原理。 aws login 背后调用的是 AWS 的登录服务,换取的是由 AWS Security Token Service 签发的临时安全凭证,包含 access key ID、secret access key 以及一个必不可少的 session token。三者缺一不可,session token 是它区别于长期密钥的核心标志。这类凭证带有明确的过期时间,无法续期,只能重新签发。CLI 与各语言 SDK 在本地缓存中保存凭证及其到期时间,并在每次调用前检查剩余有效期,接近到期时自动完成一次刷新——文章提到的"每 15 分钟刷新一次"指的就是这个后台环节。
为什么刷新不会打断工作。 因为刷新对使用方是透明的:你在终端敲下的 aws s3 ls 与你配置里的长期密钥并无语法差别,CLI 在底层替换了签名所用的凭证。这也解释了为什么会话有上限:临时凭证的链式刷新最终受限于最初登录时确立的 IAM 主体会话时长,达到上限后必须重新走一次浏览器流程。SSH 密钥、OAuth access token 都遵循类似思路——短期、可撤销、可审计——aws login 只是把这套模式搬到了 AWS CLI 上。
先问清楚"我是谁"
在信任这个会话之前,先向 AWS 确认身份:
$ aws sts get-caller-identity
$ aws sts get-caller-identity --profile my-dev-profile
第一条用默认 profile,第二条用命名 profile,返回结果应当与你在浏览器中选择的身份一致。
凭证之后会自行打理:CLI 与各 SDK 会在需要时每 15 分钟刷新一次缓存凭证,整个会话持续到 IAM 主体设定的会话时长上限,最长 12 小时,超时后重新运行 aws login 即可。原文把这个机制比作"在闸机口自动续期的日票,而不是你切割好随身携带一辈子的钥匙",这个类比相当准确。
模拟器:不碰任何真实资源回答"允许还是拒绝"
IAM policy simulator 会对你提供的策略评估一个请求,并且从不把这个请求发送给任何 AWS 服务。对于你测试的每个动作和资源,它只返回两种结果之一:allowed 或 denied。当结果是允许或显式拒绝时,它还会指出是哪条策略语句导致的。
模拟器有两种模式:
- Principal 模式:测试已经挂载在某个用户、角色或用户组上的策略;
- Custom 模式:测试你现场编写或粘贴的策略,不会向账号保存任何内容。
检查草稿策略时应该用 Custom 模式,在命令行里对应 aws iam simulate-custom-policy;测试已附加到身份的策略则用 simulate-principal-policy。
一条命令加一个上下文值,验证条件是否真的生效
设想一条草稿策略:允许所有 DynamoDB 动作,但仅在某个日期时间之后。下面的命令模拟 dynamodb:CreateBackup,并为条件所检查的 aws:CurrentTime 键提供一个值:
aws iam simulate-custom-policy \
--policy-input-list '{"Version":"2012-10-17","Statement":{"Effect":"Allow","Action":"dynamodb:*","Resource":"*","Condition":{"DateGreaterThan":{"aws:CurrentTime":"2018-08-16T12:00:00Z"}}}}' \
--action-names dynamodb:CreateBackup \
--context-entries "ContextKeyName='aws:CurrentTime',ContextKeyValues='2019-04-25T11:00:00Z',ContextKeyType=date"
提供的日期晚于条件中的日期,结果会显示 "EvalDecision": "allowed",其 MatchedStatements 指向 PolicyInputList.1,也就是你传入的第一条策略。
一次通过的测试本身说明不了什么。把上下文值改成早于策略要求日期的 2014-04-25T11:00:00Z,决策会变成 implicitDeny,MatchedStatements 为空——这才证明条件确实在起作用。两个都允许的用例同样证明不了这一点,必须一个通过、一个失败配对出现。实践中值得养成的习惯是:每一条你在意的条件,都写一个应当通过的测试和一个应当失败的测试。
输入上有几条规则:动作名必须带服务前缀(如 iam:CreateUser),不允许使用通配符;若省略 --resource-arns,资源默认为 * 即所有资源;你指定的资源不必在账号中真实存在。
读结果:决策、语句与缺失的上下文键
每个结果都带有一个 EvalDecision,取值有三种。当多条语句同时适用时,一条显式拒绝会压过任意数量的允许,且结果中只出现那条拒绝语句。
另一个必须盯住的字段是 MissingContextValues,它列出策略需要、但你并未提供的上下文键。如果提供的值不满足条件,动作就会被拒绝。
模拟器会自动填入一部分键:主体键(如 aws:PrincipalAccount、aws:UserName)和组织键(如 aws:PrincipalOrgID),其余所有键都要你自己提供。想在运行前知道一条草稿策略需要哪些键,CLI 参考文档指向 GetContextKeysForCustomPolicy。
EvalDecision 三种取值的含义。 allowed 表示至少有一条 Allow 语句匹配且没有更严格的语句推翻;explicitDeny 表示某条 Deny 语句明确匹配了该请求,这是不可绕过的结果;implicitDeny 则表示没有任何语句明确允许该请求——它并不是"被拒绝"的主动判定,而是"默认不通过"。理解这三者的差别很关键:显式拒绝会让你几乎无法通过任何方式找回权限,而隐式拒绝往往意味着你漏写了一条 Allow,或遗漏了一个上下文键。
上下文键是什么。 上下文键是 IAM 在评估条件时读取的请求属性,以 aws: 为前缀的是 AWS 提供的全局键(如 aws:CurrentTime、aws:SourceIp、aws:PrincipalArn),不带前缀的通常是服务特有的键(如 s3:prefix)。条件块正是靠这些键来做时间、IP、标签、加密状态之类的判断。模拟器不会去推断你打算传什么值,因此凡是策略里出现、你却没在 --context-entries 中给出的键,都会落入 MissingContextValues。把它们补全,模拟才有意义;忽略它们,得到的 allowed 极可能是误报。
2.38.1 的聚合行为:多资源只给一个答案
在 2.38.1 版本中,无论传入多少个资源 ARN,模拟器对每个动作只返回一个评估结果,而旧行为是按资源各返回一个结果(携带相同的总体决策)。
现在的顶层 EvalDecision 是所有资源中最严格的决策:任一资源产生 explicitDeny,顶层决策就是 explicitDeny。要看每个资源各自的决策,得读 ResourceSpecificResults。这直接影响你解析输出的方式——顶层 EvalResourceName 现在是该资源类型的 ARN 模板,而不再是你传入的某个具体 ARN,任何从顶层解析单资源答案的脚本都需要改为读取 ResourceSpecificResults。
还有几处限制值得记住:每次模拟只能包含一条基于资源的策略;模拟器不会替你抓取资源自身的策略,必须手动传入;IAM 角色不支持模拟基于资源的策略;服务控制策略可以按从组织根到账号的顺序传入,但出于安全原因,其匹配到的语句不会显示在结果里。
清理:会话存在哪、怎么看、怎么删
存在哪。 用默认 profile 登录会在 config 文件中写入一行 login_session,其中保存身份的 ARN,紧挨着 Region。临时凭证以及刷新所需的细节缓存在 Linux 和 macOS 的 ~/.aws/login/cache,Windows 则是 %USERPROFILE%\.aws\login\cache。环境变量 AWS_LOGIN_CACHE_DIRECTORY 可以把缓存挪到别处。
怎么看。 打开 config 文件,找到对应 profile 的 login_session 条目,顺便列一下缓存目录——其中文件名基于解析后的 profile。
怎么删。 可以让凭证自然过期,也可以立刻移除:
$ aws logout
$ aws logout --profile my-dev-profile
$ aws logout --all
命令行或 AWS_PROFILE 中没有指定 profile 时,aws logout 登出默认 profile;--all 则登出所有使用登录凭证的 profile。策略相关工作无需清理:Custom 模式的策略从不保存到账号,在模拟器里编辑策略也不会改动真实的那一份。
模拟器的边界在哪里
原文对这套流程的局限说得很坦诚,这一点值得保留。
模拟器自己声明:其结果可能与你的实际环境不一致。它不评估 resource control policies,在 VPC endpoint 策略、角色链式调用、以及拥有多条基于资源策略的资源上也可能出现偏差。模拟出的 allowed 是强证据,但不是证明。还有最后一步检查这篇教程没有覆盖:把策略真正附加之后,在你的实际账号中确认它的行为。
换句话说,把模拟器当作提交前的静态检查,而不是发布后的验收测试。真正稳妥的路径是:模拟器负责拦截明显错误,实际账号中的验证负责兜底。
resource control policies 与 VPC endpoint 策略。 前者是 AWS Organizations 在 2024 年引入的策略类型,作用于组织内资源,用于设置与 SCP 类似的资源侧护栏;后者则附加在 VPC endpoint 上,决定经由该 endpoint 的流量能否访问特定资源。两者都可能在实际请求时改变最终结果,而模拟器并不把它们纳入评估,于是"模拟通过、实机失败"或反之的情况都可能发生。
角色链式调用。 当一个主体通过 sts:AssumeRole 切换到另一个角色再发起请求时,真正生效的是角色会话的权限与被切换身份的权限的交集(在权限边界、SCP 等约束下)。模拟器针对的是单一主体的策略集合,无法完整重建这条链路,因此在跨账号或层层扮演角色的场景中,它的结论参考价值会打折。把这几项限制记住,就能更准确地判断:哪些模拟结果值得信任,哪些必须留到真实账号里再验一次。
核心要点
aws login要求 CLI 版本不低于 2.32.0,它用控制台登录换取可自动刷新的临时凭证,最长 12 小时,磁盘上不落长期密钥。- 在依赖会话之前,先用
aws sts get-caller-identity确认身份。 - 用 Custom 模式的
simulate-custom-policy验证草稿策略,务必配对一个应通过用例和一个应失败用例,并补全条件所检查的每一个上下文键。 - 在 2.38.1 中,单资源的决策要从
ResourceSpecificResults读取,顶层决策是所有资源的聚合结果。 - 用
aws logout清理,模拟过的策略不会在账号中留下任何东西。
相关推荐

iPhone Duo续航实测:一天一充跑不掉,大屏是耗电元凶
iPhone Duo续航实测:重度使用一天需至少充电一次,6.5小时亮屏约剩30%电量。大屏展开频率是耗电关键,MagSafe电池背夹可救场,长期衰减同样值得关注。

Kimi K3.1 Pro开源发布:2.8万亿参数逼近Opus
Moonshot发布开源MoE模型Kimi K3.1 Pro,2.8万亿总参数、1040亿激活参数,Terminal Bench 4.0仅落后Opus 5.5不到1分,单任务成本约三分之一,API价格减半,开源权重11月4日开放。

Costco科技产品价格竞猜:显示器、键鼠、Bose音响值不值?
YouTube博主在Costco竞猜科技产品价格:2K 180Hz显示器、罗技键鼠、Bose音响和CyberPower UPS实测估价,揭示仓储会员店的选品定价逻辑与品牌溢价真相。