SuperAPI AI 工具集

entra-workload-identity

安全与审计

查看项目

更新于 10-16 02:25

技能介绍

Microsoft Entra 工作负载身份(Workload Identity)

工作负载身份是应用、服务、脚本和流水线用于访问受 Microsoft Entra 保护资源的非人类身份。在近期的事后事件报告中,它们是云入侵的首要来源——通常是因为客户端密钥泄露、服务主体权限过大或证书过期无人管理。

本技能涵盖选择正确的身份类型、通过联合消除密钥、加固服务主体,以及应用 Workload Identities Premium 控制项。

何时使用

设计 Azure 资源、GitHub Action、Azure DevOps 流水线、AKS Pod 或外部工作负载如何向受 Entra 保护的 API(Azure Resource Manager、Microsoft Graph、Key Vault、Storage 等)进行身份验证时使用。

不要将本技能用于人类身份(entra-id)、多云权限分析(entra-permissions-management)或专门针对 AI 智能体身份治理(agent-identity-governance)的场景。

选择正确的身份

工作负载 / 最佳身份

Azure 托管资源(App Service、Function、VM、AKS Pod、Container Apps):托管标识(若为 1:1 则用系统分配,若共享或生命周期解耦则用用户分配)

GitHub Actions / GitLab CI / Azure DevOps / Jenkins:工作负载身份联合到用户分配的托管标识或应用注册

Azure 之外且具有 OIDC 颁发者的工作负载(Kubernetes、AWS、GCP):工作负载身份联合

无 OIDC 的旧式本地服务:使用证书的应用注册(绝不用密钥)

仅向 Microsoft Graph 进行身份验证的任何场景:应用注册 + 联合/证书

经验法则:如果你的设计文档中出现客户端密钥,说明你错过了联合的机会。先尝试联合;退而求其次用证书;新构建绝不使用客户端密钥。

方法

清点现有服务主体和凭据。使用 Microsoft Graph(servicePrincipals、applications)列出每个应用注册、其密钥/密钥凭据、到期日期和已分配角色。大多数租户会发现过期密钥、十年前的测试应用以及无人拥有的管理员已同意应用。

在联合可行处消除密钥:

GitHub Actions → Azure:在用户分配的托管标识(或应用注册)上配置联合凭据,主题为 repo:org/repo:environment:prod。GitHub 中无需密钥。

AKS 工作负载身份:在集群上启用,为服务账户添加注解,投影令牌;Pod 以绑定到的用户分配托管标识进行身份验证。

Azure DevOps:使用工作负载身份联合服务连接。

外部 OIDC 颁发者(GCP、AWS、Okta):添加带有颁发者 URL 和主题声明的联合凭据。

在必须保留凭据的地方,使用由 Key Vault 轮换的证书,而非客户端密钥。设置较短有效期(≤180 天)并自动轮换。

应用最小权限 RBAC。默认在资源或资源组级别进行范围化角色分配——除非有正当理由,绝不使用订阅所有者。当存在范围化或按应用集合的权限(Sites.Selected、通过应用访问策略的特定邮箱 Mail.Send)时,避免 Microsoft Graph .All 权限(如 Files.ReadWrite.All)。

Workload Identities Premium(单独 SKU)。解锁:

工作负载的条件访问——阻止来自意外 IP 范围的服务主体登录,要求命名位置,按客户端应用限制。

工作负载身份风险检测——泄露的凭据、异常登录、可疑管理员活动。

工作负载身份的访问评审——定期由所有者评审服务主体角色。适用于面向外部或高权限的工作负载身份;不必对租户中每个服务主体都应用。

生命周期:每个应用注册必须有所有者(不是已离职人员,也不是空列表)。每季度评审无主和未使用的应用;先禁用再删除。

监控。将 ServicePrincipalSignInLogs 流式传输到 Sentinel。对以下情况告警:

来自预期基线之外的国家/IP 的登录。

新增凭据(尤其是由所有者之外的其他身份添加)。

非工作时间高权限角色的令牌颁发。

护栏

新设计中不使用客户端密钥。联合 > 证书 > 密钥。

系统分配的托管标识与资源生命周期绑定。删除资源,标识(及其角色分配)随之消失——通常是好事,有时令人意外。

跨资源共享的用户分配托管标识很方便,但会破坏爆炸半径隔离。仅当生命周期和信任边界真正匹配时才共享。

联合凭据必须具体。主题 repo:org/repo:* 接受每个分支和 PR——包括攻击者的 fork。固定到环境或受保护分支。

没有明确理由不使用 .All Graph 权限。使用 Sites.Selected、邮件应用访问策略或仅应用 RBAC 范围化。

不要为每个环境创建一个应用注册。每个工作负载一个应用,多个联合凭据(每个环境一个)——保持角色清单整洁。

所有者 = 一个人 + 一个组。单一所有者的应用在人员离职后会变成孤儿。

工作负载的 CA 是单独的、高级策略类型。如果依赖它满足合规,请确保已启用。

常见反模式

“GitHub Action 将 AZURE_CREDENTIALS 存储为 JSON 密钥”——泄露密钥风险。改用 OIDC 联合。

“整个 DevOps 平台用一个巨型服务主体,在每个订阅上拥有所有者”——一次入侵 = 整个租户。应按流水线划分身份并范围化。

“客户端密钥 2099 年到期”——长期有效的持有者密钥使任何轮换策略失效。上限 180 天,自动化。

“AKS Pod 使用节点池 MSI 访问应用数据”——节点上每个 Pod 拥有相同身份。按服务账户使用 AKS 工作负载身份。

“联合凭据主题 = repo:org/repo:**”——接受任何分支包括 PR。固定到 environment:prod。

“服务主体被授予全局管理员以运行报告脚本”——只读 Graph 权限、范围化,本已足够。

“应用注册所有者列表为空”——无人评审或轮换。孤儿应用是审计发现项。

示例提示

将我们 GitHub Actions Azure 部署中的客户端密钥替换为工作负载身份联合。

将 12 个 AKS 工作负载从 kiam/pod-identity 迁移到 AKS 工作负载身份。

清点所有 30 天内密钥到期的应用注册,并优先安排证书轮换。

对薪资集成服务主体应用条件访问,将 IP 限制为合作伙伴 CIDR。

为 Azure DevOps 设计联合凭据,使用环境范围化的主题声明区分生产与开发。

审计具有 Microsoft Graph .All 权限的服务主体,并提出范围化替代方案。

使用 Workload Identities Premium 为高权限工作负载身份推出季度访问评审。

在 Sentinel 中搜寻异常服务主体登录——KQL 检测。

Microsoft Learn

工作负载身份概述:https://learn.microsoft.com/entra/workload-id/workload-identities-overview

托管标识:https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/overview

工作负载身份联合:https://learn.microsoft.com/entra/workload-id/workload-identity-federation

GitHub Actions OIDC:https://learn.microsoft.com/entra/workload-id/workload-identity-federation-create-trust?pivots=identity-wif-apps-methods-azp

AKS 工作负载身份:https://learn.microsoft.com/azure/aks/workload-identity-overview

Azure DevOps 工作负载身份:https://learn.microsoft.com/azure/devops/pipelines/library/connect-to-azure?view=azure-devops#create-an-azure-resource-manager-service-connection-that-uses-workload-identity-federation

工作负载身份的条件访问:https://learn.microsoft.com/entra/identity/conditional-access/workload-identity

工作负载身份风险:https://learn.microsoft.com/entra/id-protection/concept-workload-identity-risk

Microsoft Graph 应用程序权限参考:https://learn.microsoft.com/graph/permissions-reference