diff --git a/火山引擎IAM子账号管控工具_深度研究报告.md b/火山引擎IAM子账号管控工具_深度研究报告.md index 9ab7b2f..0b739c7 100644 --- a/火山引擎IAM子账号管控工具_深度研究报告.md +++ b/火山引擎IAM子账号管控工具_深度研究报告.md @@ -31,7 +31,7 @@ |------|----------|--------| | 子账号不能看到主账号信息 | IAM 默认零权限 + 显式 Deny 策略 | **完全可行** | | 子账号仅有 Seedance 2.0 + TOS 权限 | 仅附加 ArkFullAccess + TOSFullAccess 策略 | **完全可行** | -| 子账号能看到自己的账单 | 通过 AirGate 按项目维度查询,主账号代查展示 | **部分可行**(见下方说明)| +| 子账号能看到自己的账单 | 通过 AirGate 按多项目聚合查询,主账号代查展示,可按项目查看明细 | **完全可行** | | 子账号不能看到其他账号消费/余额 | 不授予 billing/bss 权限 + 显式 Deny | **完全可行** | | 消费达到阈值发告警 | 额度划拨制 + 阶梯式告警(50%/80%/90%)+ 飞书通知 | **完全可行** | | 消费达到阈值自动停用 | 消费达到已划拨额度 100% 时自动停用 | **完全可行** | @@ -507,24 +507,31 @@ iam_client.call("UpdateAccessKey", { > **核心问题**:IAM 子账号没有独立的计费维度。不能直接按 IAM UserName 查询消费。 -**可行方案:** +**AirGate 采用的方案:多项目聚合追踪** -| 方案 | 实现方式 | 精确度 | -|------|----------|--------| -| **按项目追踪** | 为每个子账号/部门创建独立项目,资源都放在项目中 | 高 | -| **按标签追踪** | 资源打上子账号标签(如 `owner=sub_user_1`) | 高 | -| **按 Ark 端点追踪** | Seedance/方舟按 Endpoint 分账(ListSplitBillDetail) | 中 | -| **按 TOS 存储桶追踪** | TOS 按 Bucket 分账 | 高 | - -**推荐方案:项目 + 标签 双维度** +一个子账号可以关联多个火山项目,每个项目有独立的监测开关。消费追踪按**所有开启监测的项目消费之和**计算。 ``` -1. 创建项目 "DeptA-Project" -2. 子账号的权限限定在该项目范围内 (AttachPolicyInProject) -3. 资源打标签 tag: {"department": "DeptA", "owner": "sub_user_1"} -4. 通过 ListBillDetail + ListSplitBillDetail 按项目/标签筛选消费 +子账号 (seaislee) + ├── 项目A: Seedance-团队1 ← 开启监测 → 消费 ¥30,000 + ├── 项目B: Seedance-团队2 ← 开启监测 → 消费 ¥20,000 + ├── 项目C: Seedance-团队3 ← 开启监测 → 消费 ¥15,000 + ├── 项目D: 测试项目 ← 关闭监测(不计入) + └── 项目E: 内部工具 ← 关闭监测(不计入) + +累计消费 = 项目A + 项目B + 项目C = ¥65,000(仅算开启监测的) +已划拨额度: ¥100,000 +使用率: 65% → 50% 告警已触发 ``` +**典型使用场景:** +- 一个部门子账号下,每个团队各创建一个火山项目 +- 每个项目下各有一个 Seedance 2.0 API 端点 +- 管理员可按需开关某些项目的监测(如测试项目不计费) +- 告警和自动停用基于所有开启项目的消费总和 vs 划拨额度 + +**消费查询方式:** 对每个开启监测的项目分别调用 `ListBillDetail`(按 Project 字段筛选),累加得出总消费。同时记录每个项目的独立消费,前端可展开查看明细。 + ### 6.4 账户余额查询 ```python @@ -602,7 +609,9 @@ balance = billing_client.call("QueryBalanceAcct") 主账号通过 AirGate 给子账号划拨额度(如 10 万元) │ ▼ 定时任务每小时查询 Billing API - 累计消费不断增长,对比已划拨额度 + 遍历子账号下所有开启监测的项目 → 分别查询消费 → 累加得出总消费 + │ + ▼ 总消费对比已划拨额度 │ ├── 消费达到额度 50% → 飞书告警 ├── 消费达到额度 80% → 飞书告警 @@ -614,6 +623,8 @@ balance = billing_client.call("QueryBalanceAcct") ``` **关键设计:** +- **多项目聚合**:一个子账号可关联多个火山项目,每个项目有独立监测开关。消费 = 所有开启监测的项目消费之和 +- **项目明细可查**:前端可展开查看每个项目的独立消费,便于分析哪个团队/项目花得多 - **非月度制**:额度不按月重置,是一次性划拨,用完再充 - **可追加可扣减**:主账号可随时追加额度(+5万)或扣减额度(-3万),支持灵活调整 - **扣减保护**:扣减后总额度不能低于已消费金额(否则会立即触发停用) @@ -1002,10 +1013,17 @@ def get_user_spending(bill_period: str, project_name: str = None) -> float: **AirGate 实现的核心流程:** 1. 主账号通过界面给子账号**划拨额度**(如 10 万元) -2. 定时任务每小时调用 Billing API 查询累计消费 -3. 消费达到额度的阶梯百分比(如 50%/80%/90%)时 → 飞书告警 -4. 消费达到 100% → 自动停用子账号 + 飞书告警 -5. 主账号可随时追加额度(告警状态自动重置)→ 恢复子账号 +2. 子账号下挂多个火山项目,每个项目有独立监测开关 +3. 定时任务每小时遍历所有开启监测的项目,分别调用 Billing API 查询消费,累加得出总消费 +4. 总消费达到额度的阶梯百分比(如 50%/80%/90%)时 → 飞书告警 +5. 总消费达到 100% → 自动停用整个子账号 + 飞书告警 +6. 主账号可随时追加额度(告警状态自动重置)→ 恢复子账号 + +**多项目管理:** +- 每个子账号可关联 N 个火山项目 +- 每个项目有独立的监测开关(开/关) +- 可通过"全选"一键开启/关闭所有项目的监测 +- 消费明细可按项目展开查看,但告警和停用看的是**所有开启项目的消费总和** **告警状态管理:** - 每个阶梯只通知一次,通过 `triggered_alerts` 字段(存数据库)去重 @@ -1034,6 +1052,15 @@ PUT /api/v1/iam-users/{id}/update/ # 更新配置(告警阈值/开 POST /api/v1/iam-users/{id}/disable/ # 停用子账号 POST /api/v1/iam-users/{id}/enable/ # 恢复子账号 GET /api/v1/iam-users/{id}/policies/ # 查看权限策略 +POST /api/v1/iam-users/{id}/policies/attach/ # 附加权限策略 +POST /api/v1/iam-users/{id}/policies/detach/ # 移除权限策略 + +# 子账号项目管理(多项目关联) +GET /api/v1/iam-users/{id}/projects/ # 查看子账号关联的项目列表 +POST /api/v1/iam-users/{id}/projects/ # 添加关联项目 +PUT /api/v1/iam-users/{id}/projects/{pid}/ # 更新项目监测开关 +DELETE /api/v1/iam-users/{id}/projects/{pid}/ # 移除关联项目 +POST /api/v1/iam-users/{id}/projects/toggle-all/ # 全选/全不选监测开关 # 额度管理 POST /api/v1/iam-users/{id}/allocate/ # 追加额度(正数)或扣减额度(负数) @@ -1063,7 +1090,7 @@ GET /api/v1/projects/ # 从火山拉取项目列表 | 限制项 | 说明 | |--------|------| -| IAM 子账号无独立计费 | 所有费用归主账号,需通过项目/标签追踪 | +| IAM 子账号无独立计费 | 所有费用归主账号,通过多项目聚合追踪(子账号关联 N 个项目,消费=开启监测的项目之和) | | Billing API 无实时数据 | 最快 T+1 天粒度,有 1-2 天延迟 | | 每用户最多 2 个 API 密钥 | 无法创建更多 | | SecretKey 仅返回一次 | 创建后立即保存 |