Files
agentic-soc-platform/docs/specs/v0.6.0/04-custom-variables.md
T
2026-07-31 16:28:47 +08:00

8.0 KiB
Raw Blame History

Custom Variables

Status: Confirmed

1. Purpose

提供一个由 Admin 通过 UI 管理、由自定义 Playbook 和 Agentic Module 在后端运行时读取的字符串变量仓库。它类似受控的数据库版环境变量,但不会修改真实 os.environ,也不影响 Django 全局配置。

典型用途:

  • 外部系统 base URL。
  • API token、username/password。
  • tenant/project ID。
  • 自定义 JSON 字符串。
  • Module 或 Playbook 的运行参数。

2. Scope

Consumers

  • BasePlaybook.get_variable(key)
  • BaseModule.get_variable(key)

Not consumers

  • Agent API。
  • CLI 或插件。
  • 前端运行时。
  • Django template。
  • 其他任意后端模块。
  • 系统 Runtime Settings。

Excluded

  • 写入真实进程环境变量。
  • 全局配置覆盖。
  • per-Playbook/per-Module scope。
  • 变量继承或 override。
  • value 类型系统。
  • .env 导入导出。
  • REQUIRED_VARIABLES 声明。
  • Secret 加密、版本历史或自动泄露防护。

3. Data model

建议模型 CustomVariable

Field Type Rules
id UUID primary key
key CharField(128) unique, immutable
value TextField non-empty, max 65,536 UTF-8 bytes
is_secret Boolean controls API masking only
description TextField optional
enabled Boolean default true
created_at DateTime auto
updated_at DateTime auto

Key validation

Regex

[A-Z][A-Z0-9_]{0,127}
  • 全局唯一。
  • 大小写敏感,但合法输入只有大写。
  • 创建后不可改名。
  • 修改 key 的 PATCH/PUT 返回 validation error。

Value validation

  • 必须至少一个字符。
  • 以 UTF-8 bytes 计算,最多 65,536 bytes。
  • 可包含换行。
  • 不支持 binary。
  • 不做 trim;空格可能是有意值,但零长度禁止。
  • 更新 Secret 时省略 value 表示保留旧值。
  • 显式 "" 始终拒绝。

4. Storage security

已确认:

  • Secret 和非 Secret 均以 PostgreSQL 明文保存。
  • 数据库管理员、数据库泄露和未加密备份可以读取 Secret。
  • is_secret 只控制 API/UI 显示与审计,不提供 cryptographic protection。
  • 用户文档必须明确该限制。

不得在 AuditLog、普通 API response、异常文本或日志中复制 value。

5. Runtime API

Base class helper

def get_variable(self, key):
    ...

返回:

  • Enabled 且存在:原始 str
  • 不存在:None
  • DisabledNone
  • 已删除:None

行为:

  • 每次调用都查询 PostgreSQL。
  • 不做 per-run、per-message 或 Worker 全局缓存。
  • Admin 在 Playbook/Module 运行中修改、Disabled 或删除变量,下一次读取立即看到变化。
  • 不抛 missing variable 异常。
  • 不支持 default 参数作为平台约定;自定义代码自行使用 or 或显式 None 处理。
  • 不返回 is_secret/description 等 metadata。
  • 不记录 read audit 或 usage relation。

建议共享 service 位于 apps.settings.custom_variables 或等价窄模块,BasePlaybook/BaseModule 只做代理,避免重复 ORM 代码。

6. Permissions

Action Admin User Viewer Playbook/Module Worker
List metadata Yes No No No
Read non-secret value via Admin API Yes No No N/A
Reveal secret Yes No No N/A
Create/update/delete Yes No No No
get_variable runtime No direct API No direct API No direct API Yes

Worker 读取不根据发起 Playbook 的用户角色过滤。User 发起的 Playbook 仍可读取所有 Custom Variables,因此 Admin 必须只安装可信自定义代码。

7. Admin API

建议资源:

/api/settings/custom-variables/

List/retrieve default representation

非 Secret

{
  "id": "...",
  "key": "EDR_BASE_URL",
  "value": "https://edr.internal.example",
  "is_secret": false,
  "description": "Production EDR API",
  "enabled": true
}

Secret

{
  "id": "...",
  "key": "EDR_API_TOKEN",
  "value": "",
  "value_configured": true,
  "is_secret": true,
  "description": "Production EDR token",
  "enabled": true
}

Reveal

POST /api/settings/custom-variables/{id}/reveal/

  • 仅 active Admin session。
  • 不要求重新输入本地或 LDAP 密码。
  • 返回一次明文 value。
  • 每次请求写 AuditLog。
  • 不应支持 bulk reveal。
  • response 应使用 no-store cache headers。

Update

  • key 不可改。
  • Secret update 未包含 value:保留旧值。
  • Secret→non-secretAPI 需要显式确认字段,例如 confirm_secret_exposure=true
  • 没有确认返回 400。
  • non-secret→secret 正常允许。
  • 所有 changes 审计不包含 value。

Delete

  • 允许硬删除。
  • UI 必须二次确认。
  • API 不负责扫描 Python 代码引用。
  • 删除后运行时返回 None。
  • 删除 AuditLog 保存 key、description、is_secret、enabled,不保存 value。

8. Audit

写 AuditLog

  • create
  • update
  • enable/disable(作为 update
  • reveal
  • delete

不写:

  • get_variable runtime read。
  • Admin 普通 list/retrieve。

Secret 和非 Secret value 均不得进入 changes。可使用:

{
  "changes": {
    "value": {"from": "***", "to": "***"},
    "enabled": {"from": true, "to": false}
  },
  "metadata": {
    "key": "EDR_API_TOKEN",
    "value_changed": true
  }
}

不保留旧 value,不支持 rollback。

9. Frontend

位置:System Settings 中新增 Custom Variables

List

  • Key。
  • Description。
  • Secret 标记。
  • Enabled。
  • Value configured。
  • Updated time。
  • Edit/Delete actions。
  • Secret 默认不可见。

Create/edit modal

  • Key 创建时可编辑,编辑时只读。
  • Value 使用 multiline inputSecret 使用 password input。
  • is_secret switch。
  • enabled switch。
  • description。
  • value byte limit 提示。
  • 编辑 Secret 时 value 留空表示不修改,UI 必须明确说明。

Reveal

  • Secret 行显示 Reveal。
  • active Admin session 直接调用。
  • 明文只显示在临时 Modal。
  • Modal 关闭后从前端 state 清除。
  • 不复制到列表 state、URL、localStorage 或 console。

Secret downgrade

从 Secret 改为普通变量时显示额外确认:

This value will become visible in normal Admin API responses and UI.

10. Interaction with custom code

示例:

class Playbook(BasePlaybook):
    def run(self):
        base_url = self.get_variable("EDR_BASE_URL")
        token = self.get_variable("EDR_API_TOKEN")
        if not base_url or not token:
            raise ValueError("EDR custom variables are not configured.")

自定义代码责任:

  • 检查 None。
  • 解析 JSON/boolean/number。
  • 不把 Secret 写入 log、Stage summary、remark、Enrichment 或异常。
  • 为 HTTP 调用设置 timeout、TLS、proxy、重试和幂等。

平台不静态分析 key,也不展示“变量被哪些脚本使用”。

11. Migration and backup

  • 新表 migration,无旧数据迁移。
  • v0.5.2 现有 LLM/SIEM/LDAP/TI Secret 不自动复制到 Custom Variables。
  • 备份/恢复自然包含明文 value。
  • Compose 文档需提醒保护数据库备份。

12. Acceptance criteria

  1. 只有 Admin 能访问资源和 Reveal。
  2. key regex、唯一和不可改名规则生效。
  3. 空 value 和超过 65,536 bytes 被拒绝。
  4. Secret 默认 response 不含明文。
  5. Admin Reveal 返回明文并写不含 value 的审计。
  6. Secret→普通无确认被拒绝。
  7. Playbook 和 Module 每次读取当前数据库值。
  8. Disabled/missing/deleted 返回 None。
  9. Agent API、CLI 和普通用户没有读取端点。
  10. CRUD AuditLog 永不包含 old/new value。
  11. 删除无需引用检查且立即影响运行时读取。

13. Known tradeoffs

  • PostgreSQL 和备份保存明文 Secret。
  • active Admin session 无需重新认证即可 Reveal。
  • User 发起的可信 Playbook 可以间接使用全部 Secret。
  • 平台无法阻止恶意或错误自定义代码泄露 Secret。
  • 每次 ORM 查询增加少量开销,这是为即时一致性接受的成本。