关于 iam-audit
iam-audit 是用于审查、设计和迁移身份与访问管理系统的安全技能,覆盖云、身份提供商和应用授权,并分别支持现有部署审计、全新设计及整合迁移。
主要功能
- 01审计云提供商权限
- 02检查身份提供商策略与 MFA
- 03评估应用授权模型
- 04设计全新 IAM 模式
- 05规划身份提供商和访问迁移
- 06记录审计发现与建议
适用场景
- 01发现过度或长期未使用的权限
- 02为新项目设计 IAM
- 03规划迁移至 SSO 或联合访问
- 04审查角色与租户隔离
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ briiirussell/ cybersecurity-skills --skill iam-audit安装后在 Claude Code 中输入/iam-audit确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/findings-format.mdfindings.schema.jsonseverity-calibration.mdto-sarif.mjsvalidate-findings.mjsverification.md详细介绍
IAM 审计 — 身份与访问管理评审和设计
端到端覆盖身份与访问层:审计现有设置、从头设计、规划迁移,并将大多数团队容易出错的模式规范化。这是一项顾问式技能——不只是指出“哪些配置有误”,还要说明“应该是什么样子”。
三种模式——选择符合当前合作需求的一种:
- 审计 — 评审已部署的设置,找出权限蔓延和缺口
- 设计 — 为新项目或新的身份提供商从零设计 IAM
- 迁移 — 整合多个身份提供商、联合访问、迁移到 SSO
交叉参考:cloud-audit 用于云提供商审计(范围比 IAM 更广),container-audit 用于 K8s RBAC 和 ServiceAccounts(编排层身份),personal-opsec 用于个人操作者自己的账户——硬件密钥 MFA、恢复途径、SIM 卡交换防护——这些不属于组织 IAM 的覆盖范围。
授权
仅审计用户拥有或获准评审的身份提供商、云账户和应用,并且已为此授予读取权限。预先批准的命令用于读取策略和发现结果。审计期间,切勿更改角色、移除用户、轮换凭据或在实际环境中尝试权限提升路径:报告该路径和修复方法,由所有者采取行动。
模式 1 — 审计现有 IAM
云提供商 IAM
AWS:
- 可通过控制台访问的 IAM 用户——成熟的设置中应为零(使用 SSO/Identity Center)
- 拥有永久访问密钥的 IAM 用户——每个都是凭据轮换问题;改为通过 SSO 或 IAM Roles Anywhere 承担角色
- 为每个可创建角色的角色设置权限边界(防止通过
iam:CreateRole+iam:AttachRolePolicy提升权限) - 附加了
AdministratorAccess策略——标记每一项并说明理由 - 紧急访问角色之外的通配符
Action: "*"或Resource: "*" - 跨账户信任策略——
Principal: { AWS: "*" }对所有人开放;应指定具体账户 ID,并可选用aws:PrincipalOrgID条件 - 强制使用 IMDSv2——每个 EC2 启动模板都应设置
MetadataOptions.HttpTokens: required - 审计服务关联角色——它们可绕过常规限制
- 运行:
aws accessanalyzer list-findings、aws iam generate-credential-report、aws iam get-account-authorization-details
GCP:
roles/owner和roles/editor权限过宽——替换为自定义角色或细粒度的roles/*Admin- 已下载服务账号密钥(
projects.serviceAccounts.keys.create)——应为零;改用 Workload Identity Federation - 服务账号对自身拥有
iam.serviceAccountTokenCreator= 自我模拟 = 权限提升 - 组织级与项目级绑定——组织级绑定范围过宽,会悄然向每个项目授予权限
- 任何敏感资源上的
allUsers/allAuthenticatedUsers绑定 - 运行:
gcloud asset analyze-iam-policy、gcloud policy-intelligence query-activity、Recommender API
Azure:
- 订阅/管理组范围内的
Owner和Contributor角色分配 - 包含
*操作的自定义角色 - 条件式访问策略覆盖所有登录入口(明确说明排除旧式身份验证、服务主体和紧急访问账户的理由)
- 所有全局管理员 / 特权角色管理员 / 应用程序管理员角色均使用特权身份管理(PIM)
- 服务主体凭据(客户端密钥)——应设置过期时间并轮换;检查过期日期
- 运行:
az role assignment list --all、Microsoft GraphauditLogs/signIns、Microsoft Entra 建议
身份提供方
Okta / Entra ID / Auth0 / Google Workspace:
- 100% 的用户都强制启用 MFA,不存在“MFA 可选”人群
- 管理员使用抗网络钓鱼的 MFA(FIDO2 / WebAuthn / 硬件密钥);所有人至少使用 TOTP
- 不活跃账户在 30/60/90 天后停用(选定一项策略并强制执行)
- 生命周期自动化——入职 / 调岗 / 离职流程均自动执行,而不是依赖工单
- 基于组的访问控制——用户通过组成员身份获得权限,而非直接分配;组成员身份是可审计的对象
- 管理员隔离——特权管理操作必须使用单独的提升权限账户,而非日常使用的账户
- 应用分配——每季度审查所有 SaaS 应用;移除孤立应用(不再使用的应用)
- 身份验证策略——阻止旧版协议(IMAP、POP、SMTP 基本身份验证),对高信任级别的应用强制执行设备合规要求
- 会话时长应与敏感级别相符(管理员:较短;最终用户:较长,并支持刷新)
- 将日志转发到 SIEM——登录、管理员变更、MFA 失败
应用授权
- 将角色定义记录在某处(而不只是写在代码中),例如
docs/roles.md或同等文档 - “管理员”不是一个单一角色,通常有 3-5 种:支持、计费、内容审核、平台管理、安全响应
- 按租户隔离角色——组织 A 的“租户管理员”即使拥有相同角色,也不能读取组织 B 的数据
- 集中进行权限检查——使用一个
can(user, action, resource)函数,而不是在各处散布if (user.role === "admin")检查 - 当访问决策取决于资源属性(记录所有者、租户、状态)时使用 ABAC;当角色激增成为威胁时,使用 ReBAC 工具(Cerbos、OpenFGA、Oso、SpiceDB)
- 记录权限检查,以供审计追踪
常见审计发现
- 角色激增——每项新需求都会催生一个新角色;没人知道这些角色各自的作用,也没人敢删除
- 权限累积——工程师为处理事件获得临时权限,但之后从未撤销
- 隐性管理员权限——非管理员角色可以通过
iam:AssumeRole间接获得管理员权限 - 过期的紧急访问账户——紧急访问账户已有 12 个月或更久未测试;没人知道它们是否可用
- 通过旧版身份验证绕过 MFA——对“已启用 MFA”的账户,IMAP/POP/SMTP 基本身份验证仍然有效
- 服务账户泛滥——服务账户数量超过了人员账户;其中一半已不再使用,另一半权限过高
模式 2 — 设计全新 IAM
原则(顾问的原则,而不只是 OWASP 的原则)
- 身份提供方是事实来源。 即使是云 IAM,也应通过 SAML/OIDC 联合身份验证;不要直接在 AWS/GCP/Azure 中管理用户。
- 人员通过组获得访问权限,而不是直接分配。 直接分配只会制造审计噪声。
- 服务账户就是角色。 不要发放密钥;使用工作负载身份联合(AWS IRSA、GCP Workload Identity、Azure Workload Identity、Kubernetes ServiceAccounts → OIDC)。
- 特权访问应为 JIT,而非长期保留。 默认“不授予访问权限”;仅在明确的时段内授予,并保留审计追踪(AWS IAM Identity Center + 带会话时长设置的权限集、Azure PIM、Okta Workflows、通过上下文感知访问实现的 Google JIT)。
- 紧急访问必须经过测试,并能触发警报。 保留紧急访问账户,但要进行严格审计并每季度测试。
- 最小权限应可观测,而非仅停留在理想层面。 每月获取访问顾问 / 未使用访问权限报告;移除未使用的权限。
- 记录授权决策。 每个
allow或deny都应可追溯,以便响应事件。
绿地项目检查清单(Web 应用 + 云)
对于新项目,请按以下顺序进行设计:
- 选择身份提供商。 企业使用 Okta 或 Entra ID;B2B SaaS 使用 Auth0 / Clerk / Stytch / WorkOS;小型团队使用 Google Workspace。不要自行开发。
- 定义授权模型。 RBAC 是基础。如果权限取决于记录属性,则添加 ABAC。如果权限复杂到代码中的
if语句难以阅读,则使用权限服务(Cerbos、OpenFGA、Oso)。 - 编写代码前定义角色。 产品中会有哪些角色?在文档中列出这些角色,并用一句话描述每个角色能做什么。大多数产品的角色包括:终端用户、终端用户管理员(租户范围)、支持人员、账单人员、内容审核员、平台管理员。
- 联合云访问。 AWS IAM Identity Center + 你的 IdP;GCP Workload Identity Federation + 你的 IdP;Azure 角色以 Azure AD 为事实来源。
- 使用工作负载身份,而非密钥。 EC2 → IAM Roles;EKS → IRSA / Pod Identity;ECS → task role;Lambda → execution role;GitHub Actions → OIDC federation。不要使用长期有效的密钥。
- 从第 1 天起启用日志记录。 将 CloudTrail / 审计日志写入关联 SIEM 的存储桶;拒绝除日志服务外的所有主体对日志存储桶执行
*:Delete*和*:Put*操作。 - 记录并测试紧急备用账户。 遵循双人规则,使用硬件 MFA,仅在“IdP 停机”情形下使用,每次登录都触发警报。
身份验证流程选择(Web / 移动客户端)
- 公共客户端(浏览器、移动设备)——使用 OAuth 2.0 Authorization Code with PKCE;绝不使用 implicit flow(已弃用,会泄露令牌)
- 机密客户端(服务器到服务器)——使用 Client Credentials 授权,并采用短时有效的访问令牌
- 第一方原生应用——由 IdP 的原生 SDK(Okta、Auth0、Clerk)处理存储和令牌刷新的细节
- 将长期有效的刷新令牌存储在 HttpOnly Secure Cookie 中;绝不要存储在
localStorage中(令牌可能被 XSS 窃取) - 令牌撤销列表——你的 IdP 应该支持此功能;如果不支持,就说明你有 JWT 问题(参见
owasp-auditA07)
模式 3 — 迁移 / 整合
常见迁移
- 从 AWS IAM 用户 → AWS IAM Identity Center(SSO): 通过群组将用户映射到权限集;设定期限,轮换 / 停用 IAM 用户访问密钥;剩下的长期工作是服务账户和 CI/CD——将它们转换为 OIDC federation
- 从 Active Directory → Entra ID: 使用 Entra Connect 同步,然后添加 Conditional Access;难点在于旧式身份验证(SMB、NTLM、本地 LDAP)——这些需要单独制定弃用计划
- 从“Google Workspace 作为 IdP” → 专用 IdP(Okta / Entra): Google 可处理电子邮件,但向 30 个 SaaS 应用配置用户会越来越麻烦;迁移主要涉及 SCIM 配置 + SAML federation;用户几乎不会察觉
- 从到处使用
roles/owner→ 自定义角色(GCP): 使用 Recommender API 建议权限最小化的替代方案;一次迁移一个项目
迁移操作手册(适用于上述所有迁移)
- 盘点当前状态。 谁在什么地方拥有什么访问权限?使用电子表格即可。包含服务账户。
- 确定目标状态。 定义角色和群组,选择 IdP,选定联合模式。
- 并行搭建目标环境。 新 IdP / IAM Identity Center 等与当前设置并存。暂不切换。
- 邀请小组试点。 让 5-10 人使用新流程,找出阻碍并修复。
- 分批迁移。 按团队或应用迁移,不要一次性全面切换。每一批都要有回滚流程。
- 设定期限,弃用旧流程。 规定“到 X 日期,旧 IAM 用户将被停用”,并严格执行。没有期限的迁移永远无法完成。
- 记录切换审计轨迹。 记录谁在何时迁移、迁移前拥有什么权限、迁移后获得了什么权限,以及由谁批准。
验证,然后记录
结果来自审计模式,以及迁移过程中的当前状态清单(模式 3,第 1 步)。设计和迁移建议不属于结果:应将它们放入报告的「建议」表格,而不是 findings.json。按照 references/findings-format.md 中的定义,为每个审计候选项给出一个结论。
1. 先保存证据。 这里几乎所有内容都是已部署的设置,而非文件。将支持每个候选项的只读输出脱敏后保存到 <audit dir>/evidence/<name>.json(或 .txt),并美化输出(使用 | jq .),以便行号保持不变:evidence/aws-iam-get-account-authorization-details.json、evidence/aws-accessanalyzer-list-findings.json、evidence/gcloud-asset-analyze-iam-policy-acme-prod.json、evidence/okta-policies-okta-sign-on.json、evidence/entra-conditional-access-policies.json。将 location、trace[] 和 evidence[] 指向该文件以及关键陈述或设置所在的行,路径应像其他位置一样相对于仓库(例如 security-audit/evidence/...)。对于没有仓库的审计,路径应相对于审计目录,并在报告标题中说明这一点。应用程序授权相关结果应指向源文件。
切勿保存机密值。写入文件前,删除客户端密钥值(secretText)、私钥、SAML 签名证书中的私钥部分、API 令牌、会话令牌和密码哈希。保留查找资源所需的主体名称和 ID。
2. 对每个候选项执行反证核查,然后再确认,具体请参阅 references/verification.md。对于 IAM,路径为:信任级别较低的主体(窃取了密码的互联网用户、GitHub 组织中的任意仓库、其他账户中的任意主体、开发者角色)→ 允许其进入的授权、信任或策略缺口 → 其最终获得的权限或数据。通过证据文件将其写入 trace[]:entrypoint = 允许其进入的信任策略、登录规则或绑定;propagation = 每一跳(iam:PassRole、iam:CreatePolicyVersion、actAs、组嵌套);sink = 到达的管理员权限或数据资源。应重点查找高于所读策略的控制:SCP 和组织策略、权限边界、资源策略条件(aws:PrincipalOrgID、aws:SourceAccount)、条件访问、IdP 身份验证策略、拒绝策略。
3. 选择结论。
| 判定 | 此处的示例 |
|---|---|
confirmed | 保存的输出展示了完整路径。例如:角色 ci-deploy 信任 GitHub OIDC,其 token.actions.githubusercontent.com:sub = repo:acme/*,且其策略允许对 * 执行 iam:PassRole,并允许 lambda:CreateFunction;AdminRole 可被传递,因此任何组织仓库中的工作流都能以管理员身份运行代码。Okta 登录策略中针对“Everyone”的规则不要求 MFA,且该规则涵盖的应用是拥有生产权限集的 AWS IAM Identity Center 应用。 |
needs_validation | 你能看到的策略支持该说法,但有一个决定性事实位于你无法读取的地方。例如:开发者角色对自己的策略拥有 iam:CreatePolicyVersion 权限(可升级为 *),但 SCP 位于你无权访问的管理账户中(阻碍因素:SCP 是否拒绝 iam:CreatePolicyVersion;计划:从管理账户运行 aws organizations list-policies-for-target --target-id <account-id> --filter SERVICE_CONTROL_POLICY,或运行 aws iam simulate-principal-policy --policy-source-arn <role-arn> --action-names iam:CreatePolicyVersion)。某个 Conditional Access 策略要求 MFA,但排除了组 CA-Exclusions,而你无法列出其成员。任何你描述但未运行的检查,都属于 needs_validation,并须在 validation_plan 中写明具体命令。 |
rejected | 某个已命名位置的具名控制措施会阻断所有路径。例如:拥有 iam:CreateRole + iam:AttachRolePolicy 的角色看似构成升级路径,但某个 SCP 会拒绝这两项操作,除非新角色带有 dev-boundary 权限边界(ruled_out_by.location = SCP 证据文件及行号)。信任策略包含 "Principal": {"AWS": "*"},但其 Condition 要求 aws:PrincipalOrgID = 你的组织。 |
若升级路径始于已经是管理员的主体,则不构成发现项。你收到的 IaC 模块或角色模板中存在不安全默认值(某个模块的信任策略默认允许 "AWS": "*",除非设置 trusted_accounts),属于 confirmed,其条件为 system_configuration(“未设置 trusted_accounts 的部署”),置信度为 medium。
没有追踪到影响的缺口属于加固建议,而非记录:未记录的角色、未授予额外权限的直接用户分配、非管理员用户使用 TOTP 而非 FIDO2、会话时长超过策略规定、未将登录日志转发到 SIEM、今年尚未测试的紧急访问账户。它们应列入报告的加固部分,不标注严重程度。
4. 校准严重程度,仅针对 confirmed 记录,参照 references/severity-calibration.md,并根据主体最终能执行的操作评级。从低权限角色升级到账户或租户管理员权限,评级为 High;可读取生产数据的角色存在开放信任策略,评级为 High 或 Critical;缺少 MFA 的评级取决于受影响账户能够访问的资源(生产环境管理员:High;内部 Wiki 的低权限用户:Medium 或 Low)。overall ≤ 已证明的影响。
置信度:从实时 API 读取的策略属于证据,而非复现。切勿实际执行升级路径。若提供商自带的只读评估工具(aws iam simulate-principal-policy、gcloud policy-troubleshoot iam、Entra 的 Conditional Access What If)对决定性操作返回“allowed”,则计为 "reproduced": true;请将命令和结果记录在 evidence[] 中。没有此项时,置信度最高为 medium。
5. 按主体或策略生成指纹,而非按行生成。 格式:iam-audit/<class>/<provider>/<tenant>/<principal or policy>;对于应用授权和 IaC,使用 iam-audit/<class>/<file>/<symbol>。ARN 中的斜杠应保留;验证器会拒绝包含 :<digits> 段的值。
iam-audit/shadow-admin/aws/123456789012/role/ci-deploy # arn:aws:iam::123456789012:role/ci-deploy
iam-audit/open-trust-policy/aws/123456789012/role/partner-read
iam-audit/sa-self-impersonation/gcp/acme-prod/[email protected]
iam-audit/mfa-not-enforced/okta/acme.okta.com/policy/default-sign-on
iam-audit/tenant-role-isolation/src/auth/can.ts/can
正在使用的类别:wildcard-policy、admin-attachment、open-trust-policy、missing-permissions-boundary、shadow-admin、sa-self-impersonation、sa-key、static-access-key、console-user、primitive-role、public-binding、org-level-binding、mfa-not-enforced、legacy-auth-allowed、ca-gap、sp-secret-no-expiry、inactive-account、orphaned-app、tenant-role-isolation。如果没有合适的类别,请添加一个新类别。
6. 域字段放在 ext 下:
| 键 | 值 |
|---|---|
provider | aws、gcp、azure、entra、okta、auth0、google-workspace、cognito、app |
tenant | 账号 ID、GCP 项目或组织 ID、Entra 租户域名、Okta 组织域名 |
principal | 调查结果涉及的用户、角色、群组、服务账号或应用,使用提供商显示的名称 |
7. 编写并验证。 设置 skill: "iam-audit",按指纹排序,写入 findings.json,并修正问题,直到验证通过:
node references/validate-findings.mjs findings.json
node references/to-sarif.mjs findings.json -o findings.sarif # optional
再次运行时,加载之前的 findings.json 并按指纹匹配。除非该记录所指的控制项已更改,否则 rejected 记录应保持拒绝状态(先重新读取相关证据)。处置状态通常由之后运行的 finding-triage 设置:Fixed / Deferred / Accepted Risk / Mitigated (platform/config) / Requires major migration。误报应标记为 rejected 记录。
输出格式
首先写入 findings.json(审计模式)。报告从该文件生成,不会更改 JSON 中未明确说明的判定、严重性、阻断项或影响。不要使用“Potential”或“Possible”标签。
# IAM [Audit | Design | Migration] Report
## Scope: [accounts / orgs / IdPs / apps covered] ## Mode: [Audit | Design | Migrate] ## Date: [date]
## Access: [read-only role / API scopes used] ## Not covered: [what and why]
## findings.json: [path] — validated: [yes] ## Evidence: [audit dir]/evidence/
### Executive Summary
[2-3 paragraphs — the IAM posture in plain English, top 3 risks, recommended next 90 days]
### Summary
- Confirmed: [N] (Critical [n] | High [n] | Medium [n] | Low [n])
- Needs validation: [N] Rejected: [N] Hardening notes: [N]
### Confirmed findings
#### [SEVERITY] [Title] `fingerprint`
**Provider / tenant / principal:** [ext.provider / ext.tenant / ext.principal]
**Evidence:** `evidence/<file>:<line>` — [the decisive statement or setting, redacted]
**Confidence:** [medium | high (reproduced via simulator)] **Conditions:** [from conditions[]]
**Path:** [lower-trust principal → grant or gap → privilege or data reached]
**Fix:** [the policy, binding or IdP change]
**Verify the fix:** [the read-only command or simulator check that shows it's closed]
### Needs validation
| Finding | Blocker | Check for the owner to run |
|---|---|---|
### Hardening notes (not findings)
- [gap] — [why it isn't a finding] — [effort]
### Rejected (do not re-raise)
| Fingerprint | Ruled out by | Location |
|---|---|---|
### Privileged access inventory
| Principal | Provider / tenant | Admin-level grant | Standing or JIT | MFA type | Last used |
|---|---|---|---|---|---|
### Recommendations (Design / Migrate mode — not findings)
| ID | Category | Recommendation | Effort |
|---|---|---|---|
### Roadmap
[Quarterly milestones — what to do this month, next 90 days, next year]
边界
- 仅审计用户获准访问的账号和身份提供商
- 审计期间仅执行只读操作(不得执行
iam:AttachPolicy、创建角色或停用用户) - 迁移时,除非已确认存在回滚路径,否则不得停用用户
- 拒绝协助绕过 MFA、通过社会工程手段找回凭据或设计后门访问
- 审计中发现的权限提升链应记录为调查结果,不得加以利用
参考资料
- AWS IAM 最佳实践
- GCP IAM 最佳实践
- Microsoft Entra ID — 特权访问策略
- NIST SP 800-63(数字身份指南)
- NIST SP 800-207(零信任架构)
- OWASP 身份验证速查表
- OWASP 授权速查表
- Open Policy Agent / Cedar / Cerbos / OpenFGA 文档
- AWS 权限边界文档
- “仅需足够访问权限” / JIT 访问模式
- 共享参考资料(构建时复制到
references/):findings-format.md、findings.schema.json、validate-findings.mjs、to-sarif.mjs、severity-calibration.md、verification.md