AWS访问密钥创建后怎么用更安全?新手必看的权限配置和泄露排查
很多新手第一次接入 AWS,都会卡在一个很基础的问题上:本地代码、脚本、CI/CD 或第三方工具要怎么访问 AWS 资源?
答案通常是使用AWS访问密钥。它由两部分组成:
- Access Key ID
- Secret Access Key
这两个值组合起来,就相当于程序访问 AWS 的“账号密码”。也正因为如此,AWS访问密钥创建并不难,真正容易出问题的是后面的使用和管理:权限给太大、密钥写进代码、上传到 GitHub、长期不轮换,最后导致 AWS密钥泄露和账单异常。
下面按实际开发流程整理一遍,从创建、配置到泄露排查,尽量把容易踩坑的地方说清楚。
先分清:不要优先给 Root 用户创建访问密钥
AWS 账号刚注册好时,会有一个 Root 用户。这个用户权限最大,可以操作账单、IAM、资源删除等关键功能。
不建议直接给 Root 用户创建访问密钥。
更合理的做法是:
- 使用 Root 用户登录 AWS 控制台;
- 创建 IAM 用户或 IAM 角色;
- 给这个 IAM 身份分配最小权限;
- 只给需要程序访问的 IAM 用户创建访问密钥。
Root 用户最好只用于账号级管理,比如账单、安全设置、创建管理员用户等。平时开发、部署、脚本调用,都应该通过 IAM 身份完成。
如果你的账号里已经存在 Root 访问密钥,建议尽快检查是否还在使用;如果没有明确用途,通常应考虑停用并删除。操作前要确认线上业务没有依赖这组密钥,避免误删导致服务中断。
AWS访问密钥创建步骤
下面以 IAM 用户为例。不同时间 AWS 控制台界面可能会有细微变化,具体按钮名称以控制台实际展示为准。
进入 AWS 控制台后,打开 IAM 服务。
路径通常是:
IAM -> Users -> 选择用户 -> Security credentials在安全凭证页面里,可以看到访问密钥相关区域。点击创建访问密钥后,AWS 会让你选择使用场景,比如:
- Command Line Interface,也就是 AWS CLI;
- Local code,本地代码;
- Application running outside AWS,运行在 AWS 外部的应用;
- Third-party service,第三方服务;
- 其他使用场景。
这个选择主要是帮助 AWS 给出安全提醒,不代表权限自动配置好了。真正决定密钥能访问什么资源的,还是 IAM 策略。
创建完成后,AWS 会展示 Access Key ID 和 Secret Access Key。
这里有一个很重要的细节:Secret Access Key 通常只在创建时展示一次。页面关闭后就不能再次查看,只能重新创建新的访问密钥。
所以创建后要马上保存到安全的位置,比如公司内部的密钥管理系统、密码管理器,或者云厂商提供的 Secrets Manager 一类服务。不要截图发群,也不要放在普通文档里长期保存。
给访问密钥配置最小权限
很多问题不是出在密钥创建,而是权限给得太大。
新手常见做法是直接给 IAM 用户绑定AdministratorAccess。测试阶段看起来省事,但风险很高。一旦 AWS密钥泄露,攻击者就可能创建资源、删除资源、读取数据,甚至修改权限。
更推荐的做法是按业务需要拆权限。
比如你的程序只需要上传文件到某个 S3 Bucket,就不要给它 EC2、RDS、IAM 的权限。可以只授权到指定 Bucket,并限制允许的动作。
示例思路大概是:
{"Effect":"Allow","Action":["s3:PutObject","s3:GetObject"],"Resource":"arn:aws:s3:::your-bucket-name/*"}这只是示意,实际策略要根据你的 Bucket 名称、目录结构、业务动作来调整。
如果是调用 CloudWatch Logs,就只给日志写入相关权限;如果是部署脚本需要操作 ECS、Lambda 或 ECR,也应限制到具体资源范围。权限越精确,密钥泄露后的影响面越小。
本地开发怎么配置 AWS访问密钥
如果只是本地开发,常见方式是使用 AWS CLI 配置凭证。
安装 AWS CLI 后执行:
aws configure按提示输入:
AWS Access Key ID AWS Secret Access Key Default region name Default output format配置后,凭证通常会写入:
~/.aws/credentials区域配置通常在:
~/.aws/config可以用下面的命令检查当前身份:
aws sts get-caller-identity正常情况下会返回账号 ID、用户 ARN 等信息。这个命令很适合用来确认:当前机器到底在用哪一组 AWS访问密钥。
如果你有多个项目,建议使用 profile 区分,而不是来回覆盖默认配置。
例如:
aws configure--profiledev aws configure--profileprod使用时指定 profile:
aws s3ls--profiledev代码里也可以通过环境变量指定:
exportAWS_PROFILE=dev这样比把密钥直接写在代码里安全得多,也方便区分测试环境和生产环境。
不要把访问密钥写进代码仓库
这是 AWS密钥泄露最常见的来源之一。
下面这些写法都不推荐:
access_key="AKIAxxxxxxxxxxxx"secret_key="xxxxxxxxxxxxxxxx"或者在配置文件里明文保存:
aws:accessKeyId:AKIAxxxxxxxxxxxxsecretAccessKey:xxxxxxxxxxxxxxxx即使仓库是私有的,也不建议这么做。私有仓库可能被误设为公开,成员账号可能被盗,日志和构建产物也可能把配置带出去。
更稳妥的方式是:
- 本地开发使用
~/.aws/credentials或环境变量; - CI/CD 使用平台提供的 Secret 管理功能;
- 生产环境优先使用 IAM Role;
- 密钥文件加入
.gitignore; - 定期扫描仓库中是否出现疑似密钥。
常见的.gitignore可以加上:
.env *.env .aws/ credentials config.local.*如果项目里确实需要.env.example,里面只能放字段名,不要放真实值。
例如:
AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_REGION=ap-southeast-1在 EC2、Lambda 等 AWS 环境里,优先用 IAM Role
如果程序运行在 AWS 自己的服务里,比如 EC2、Lambda、ECS、EKS,通常不需要手动创建长期访问密钥。
更推荐使用 IAM Role。
以 EC2 为例,可以给实例绑定 Instance Profile。程序运行时,AWS SDK 会自动从实例元数据服务获取临时凭证,不需要你在机器上保存 Access Key 和 Secret Key。
Lambda、ECS Task Role 也是类似思路。
这样做的好处很明显:
- 不需要在服务器上写死长期密钥;
- 临时凭证会自动轮换;
- 权限可以通过 IAM Role 管理;
- 泄露风险比长期访问密钥低。
如果你发现生产服务器上还有明文 AWS访问密钥,建议评估是否可以迁移到 IAM Role。尤其是长期运行的服务,不要依赖一组几年不变的密钥。
CI/CD 里使用访问密钥要注意什么
很多团队会在 GitHub Actions、GitLab CI、Jenkins 里调用 AWS,比如推镜像到 ECR、部署 Lambda、更新 ECS 服务。
这种场景下不要把密钥写进 workflow 文件或 Jenkinsfile。
应该使用 CI/CD 平台的 Secret 功能,例如:
AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_REGION脚本里通过环境变量读取即可。
如果权限允许,尽量给 CI/CD 单独创建 IAM 用户或角色,不要复用开发人员自己的密钥。这样后续排查问题时也更清楚:是哪个流水线在操作资源,权限范围是什么,是否需要单独轮换。
另外,部署类密钥的权限通常比较敏感。不要因为“流水线要部署”就直接给管理员权限。能限制到具体 ECR 仓库、ECS 集群、Lambda 函数,就尽量限制。
怎么判断 AWS访问密钥有没有泄露
如果怀疑 AWS密钥泄露,可以先做几件事。
第一步,看 IAM 里的访问密钥状态。
进入 IAM 用户的安全凭证页面,查看访问密钥的创建时间、最近使用时间。如果某个密钥长期不用,却突然出现最近使用记录,就要警惕。
第二步,看 CloudTrail。
CloudTrail 可以记录 AWS API 调用。可以根据 Access Key ID、IAM 用户、时间范围、事件名称来排查异常操作。
重点看这些情况:
- 是否创建了陌生的 EC2 实例;
- 是否开启了高成本资源;
- 是否新增了 IAM 用户或访问密钥;
- 是否修改了安全组规则;
- 是否访问了不该访问的 S3 Bucket;
- 是否在陌生区域创建资源。
第三步,看账单和 Cost Explorer。
密钥泄露后,攻击者常见操作之一就是创建大量计算资源。账单突然升高,或者某些平时不用的区域出现费用,都需要检查。
第四步,检查代码仓库和日志。
搜索关键词:
AKIA AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY aws_access_key_id aws_secret_access_key有些密钥不一定在代码里,可能出现在 CI 日志、错误日志、配置备份、镜像层、压缩包里。排查时不要只看源码目录。
发现 AWS密钥泄露后怎么处理
如果确认或高度怀疑访问密钥泄露,不要只是在代码里删掉那一行。密钥一旦暴露,就要按已经泄露处理。
建议顺序是:
- 先停用泄露的访问密钥;
- 确认业务是否受影响;
- 创建新的访问密钥并替换到业务配置;
- 删除旧密钥;
- 检查 CloudTrail、账单和资源列表;
- 排查是否有新增 IAM 用户、角色、策略或异常资源;
- 清理泄露源,比如 Git 历史、日志、构建产物;
- 复盘权限是否过大,必要时收缩 IAM 策略。
这里要注意,Git 仓库里删除文件并不等于彻底删除历史记录。密钥如果曾经提交过,仍可能在历史提交中被找到。即使你清理了 Git 历史,也应该轮换密钥,不能继续使用原来的那一组。
常见报错和排查方向
本地或程序接入 AWS 时,访问密钥相关报错很常见。可以按下面几个方向查。
Unable to locate credentials
这个报错通常表示 SDK 或 CLI 没找到凭证。
检查点:
aws configure list看看当前 profile、环境变量、配置文件是否正确。
如果使用环境变量,确认变量名是否拼错:
AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_REGION如果使用 profile,确认命令里有没有指定:
aws s3ls--profiledevThe security token included in the request is invalid
这个报错可能是密钥填错、密钥已删除、密钥状态异常,或者临时凭证缺少 session token。
如果你使用的是长期访问密钥,检查 Access Key ID 和 Secret Access Key 是否对应同一组。
如果你使用的是临时凭证,还需要确认是否配置了:
AWS_SESSION_TOKENAccessDenied 或 UnauthorizedOperation
这类报错通常不是密钥不存在,而是权限不够。
要看具体 API 调用需要什么权限。例如访问 S3、操作 EC2、写 CloudWatch Logs,对应的 IAM Action 都不一样。
排查时不要直接加管理员权限。更好的方式是根据报错里的 action 和 resource 调整 IAM 策略,只补充业务真正需要的权限。
SignatureDoesNotMatch
这个问题常见原因包括:
- Secret Access Key 填错;
- 请求签名区域和实际区域不一致;
- 系统时间偏差过大;
- SDK 配置异常;
- 手写签名逻辑有问题。
如果是自己拼请求签名,建议优先使用 AWS 官方 SDK,减少低级错误。
日常管理建议
AWS访问密钥不是创建完就不用管了。对团队来说,至少要建立几条基本规范。
不要多人共用同一组访问密钥。每个人、每个系统、每条流水线尽量使用独立身份,方便审计和回收。
不要长期使用高权限密钥。能用 IAM Role 的地方优先用角色;必须使用长期访问密钥时,也要限制权限范围。
定期检查访问密钥的最近使用时间。长期不用的密钥可以停用观察,确认无影响后删除。
生产环境和测试环境分开。不要让测试脚本拿着生产权限,也不要让开发人员随手使用生产密钥。
仓库、CI 日志、镜像和配置文件都要纳入排查范围。密钥泄露不一定发生在源码里,很多时候是构建和运维环节不小心带出去的。
写在最后
AWS访问密钥创建本身不复杂,真正考验团队的是权限设计和日常管理。
如果只是本地调试,用 IAM 用户加最小权限,再配合 profile 管理,基本够用;如果是跑在 EC2、Lambda、ECS 这类 AWS 服务上的程序,优先考虑 IAM Role;如果接入 CI/CD,就把密钥放进 Secret 管理,不要写进脚本和仓库。
最重要的一点是:访问密钥一旦公开,就不要抱侥幸心理。停用、轮换、查 CloudTrail、查账单、查异常资源,这些动作要尽快做。对开发团队来说,把 AWS密钥泄露当成真实安全事件处理,远比事后补救成本低。