2. 跨环境资产与身份统一建模

跨环境安全事件响应的第一道难题,不是检测规则,而是"我到底有什么、谁在用它"。云主机、本地物理机、Kubernetes Pod、SaaS 账号分散在四套甚至更多控制平面里,各自有独立的 ID 体系、命名规则和生命周期。当一条告警指向某个 IP 或某个邮箱时,如果不能在数秒内把它还原成"哪台资产、属于谁、能访问什么",后续的隔离、取证、封禁都会失去准星。本节要解决的就是这件事:把四类环境中的资产、身份、权限与依赖关系,收敛成一张可查询的统一资产图谱,并给出身份映射方法。

四类环境的建模差异

先看清各环境的"原生对象"是什么,才能设计统一模型。

  • 云环境:核心对象是实例(Instance)、弹性 IP、安全组、IAM Role、存储桶。实例 ID 稳定但 IP 会漂移,因此云侧主键应选实例 ID 而非 IP;IAM Role 是权限的集中载体,必须单独建模。
  • 本地环境:核心对象是物理机/虚机、主机名、MAC、域账号、AD 组。主机名可能重复,MAC 相对稳定,域账号与 AD 组构成权限链。
  • 容器环境:核心对象是 Pod、Service、Namespace、ServiceAccount、镜像。Pod 生命周期极短,名称带随机后缀,必须用"工作负载(Deployment/StatefulSet)+ 副本"来稳定标识,而不是 Pod 名。
  • SaaS 环境:核心对象是用户账号、OAuth 应用、API Token、角色。账号以邮箱为主键,但同一人可能有多个邮箱别名,需要归一。

差异的本质是:标识符的稳定性不同。统一建模的关键,就是为每类对象选一个"生命周期内不变"的稳定主键,再用别名表吸收其余标识。

统一资产图谱的数据结构

推荐用属性图(Property Graph)而非关系表来承载。节点表示资产或身份,边表示"归属、运行于、可访问、依赖"等关系。下面给出一个可直接落地的节点与边定义示例(字段为示例设计,非实测数据):

节点类型(Node)
  Asset   : {uid, env, type, stable_id, ip[], hostname, image, tags[], risk}
  Identity: {uid, type, primary_id, aliases[], mfa, status}
  Permission: {uid, scope, action, resource_pattern, source}

边类型(Edge)
  RUNS_ON      : Pod -> Node
  BELONGS_TO   : Asset -> Identity(owner)
  ASSUMES      : Identity -> IAMRole
  CAN_ACCESS   : Identity -> Asset / Resource
  DEPENDS_ON   : Asset -> Asset
  MEMBER_OF    : Identity -> Group

稳定主键示例
  云实例   : cloud:aws:instance:i-0a1b2c3d
  本地主机 : onprem:host:MAC=00:1A:2B:3C:4D:5E
  容器负载 : k8s:prod:deploy:payment-api
  SaaS账号 : saas:okta:user:zhang.san@corp.com

注意 uid 采用"环境:平台:类型:稳定标识"的分层命名,这样即使跨云、跨集群也不会冲突,且从 uid 就能反推归属环境,便于响应时快速定位控制平面。

身份映射:把多个账号收敛到一个人

身份映射的目标是回答"这个邮箱、这个 IAM Role、这个 ServiceAccount,是不是同一个人或同一个服务"。做法分三步:

  1. 归一主身份:以企业目录(如 Okta/AD)的邮箱为人员主键,建立 primary_id。
  2. 别名归并:把云 IAM 用户名、SaaS 别名邮箱、Git 提交邮箱等写入 aliases[],用规则+人工确认的方式合并。规则示例:zhang.san@corp.com 与 zhangsan@corp.com 若同属一个部门且 MFA 设备一致,可自动合并。
  3. 服务身份单独建模:ServiceAccount、API Token、CI 机器人账号不应挂到人身上,而应作为独立 Identity 节点,通过 ASSUMES 边关联到其所属团队。
映射冲突时(如两个邮箱指向同一人但 MFA 设备不同),不要自动合并,应标记为待确认并保留两条记录,避免把攻击者的账号误并进合法身份。

依赖关系与爆炸半径

资产图谱的价值在响应时体现为"爆炸半径计算"。当某台云主机被确认失陷,响应系统沿边做有限深度遍历:向上找 BELONGS_TO 得到负责人,向下找 CAN_ACCESS 得到该主机身份能触达的资源,横向找 DEPENDS_ON 得到依赖它的服务。深度建议限制在 2~3 跳,否则图会迅速膨胀到无法人工判读。

下面这张图展示了四类环境的原生对象如何经稳定主键归一后汇入统一图谱,以及一次失陷事件如何沿边扩散出爆炸半径。

跨环境资产与身份统一图谱 云环境 Instance / EIP IAM Role / SG 主键: instance-id 本地环境 物理机 / 虚机 AD账号 / 组 主键: MAC 容器环境 Pod / Service ServiceAccount 主键: 工作负载名 SaaS 环境 用户账号 / 角色 OAuth / API Token 主键: 邮箱 统一资产图谱 Property Graph Asset 节点 Identity 节点 Permission Edge 关系 uid = 环境:平台:类型:稳定标识 失陷资产 cloud:aws:instance:i-0a1b 可达资源 CAN_ACCESS → S3 / DB 依赖服务 DEPENDS_ON → payment-api 爆炸半径 = 2~3 跳遍历 归一映射 爆炸半径扩散

落地要点与常见坑

第一,先定主键再谈采集。很多团队一上来就接各种 API 拉数据,结果发现同一台机器在云侧叫 instance-id、在 CMDB 里叫资产编号、在监控里叫主机名,三份数据对不上。正确顺序是先定义 uid 规则,再让各采集器按规则输出。

第二,容器侧不要以 Pod 为节点。Pod 平均存活时间可能只有几分钟,把它作为图谱节点会导致图不断抖动。应以 Deployment/StatefulSet 为稳定节点,Pod 作为其瞬时实例挂在边上。

第三,权限边要带来源。同一条 CAN_ACCESS 边,可能来自 IAM Policy、安全组规则或 K8s RBAC,来源不同,处置方式完全不同——改 IAM 策略和改安全组是两套操作。因此 Permission.source 字段不可省。

第四,定期做一致性校验。建议每天跑一次对账:云侧实例数 vs 图谱 Asset 节点数、目录账号数 vs Identity 节点数,偏差超过阈值(示例阈值 2%)即告警。这能及时发现采集器掉线或权限变更未同步。

身份映射涉及个人数据,别名归并结果应限制访问范围,并在审计日志中记录每次合并操作的操作者与依据,避免图谱本身成为新的数据泄露面。

把上述模型建起来后,响应流程中的每一步——从告警定位到资产、从资产找到负责人、从负责人确认其权限范围、再到计算隔离影响面——都可以转化为对图谱的几次查询。这才是跨环境响应能够"快而准"的底层支撑。