worldofhacks/headshot
GitHub: worldofhacks/headshot
AgentForge 是一个目标无关的多 agent 对抗性评估平台,用于对已授权的线上 AI 应用进行受管治的持续红队安全测试。
Stars: 0 | Forks: 0
# AgentForge / 对抗性 Machine
AgentForge 是一个可复用的多 agent 平台,用于对 AI 应用进行持续红队测试。其首个
目标是外部部署的 OpenEMR Clinical Co-Pilot。该目标仅通过
授权的线上 URL 访问;目标代码并不存放于此仓库中。
## 当前状态
截至 2026-07-26,该平台具备:
- 经过认证的 React/Clerk 操作员控制台和受保护的 FastAPI API;
- PostgreSQL 控制平面、队列、审计/证据存储,以及标准的 Alembic 链,直至
`0026` 活动结果、`0027` 不可变 prompt 快照、`0028` 有界 provider 响应
证据、`0029` 携带于其所做判定上的评估器依据,以及 `0030`
该推理传达至漏洞报告;
- 私有的 Railway Runner 和 Scheduler 服务;
- 精确范围的双人活动授权;
- 通过 OpenRouter 托管的 Orchestrator、Red Team、Judge 和 Documentation 角色;
- 通过 Policy Gateway 进行的精确已审查工作负载目标分发;
- 持久的逻辑 agent 与物理 provider 血缘;
- 权威的线上活动操作以及受保护的不可变 prompt 快照;
- 独立的确定性 Judge 优先级;以及
- 以 PostgreSQL 为权威的遥测,带有故障软化的 Langfuse 投影。
它**尚未达到全套件的可靠性**。最近的一次 staging 活动运行了 34 个用例中的 12 个,
随后一个 schema 无效的 Gemini Judge 响应导致整个批次失败。仓库传输层现在
将已确定的 schema 无效输出分类为仅在现有角色/全局权限内进行重试,但该候选方案
尚未部署,且当前的暂存配置授权的重试次数为零。Runner
仍然无法恢复已终止的批次,并且失败的活动无法通过当前的 Langfuse 验证器进行远程查询验证。
阅读 [`docs/CURRENT_STATE.md`](docs/CURRENT_STATE.md) 以获取确切的部署 ID、角色模型/upstream、
caps、策略/配置哈希、最新的运行分析以及未解决的缺陷。在将
标有日期的审查或计划文件视为
当前版本之前,请阅读
[`docs/DOCUMENTATION.md`](docs/DOCUMENTATION.md)。
## 线上 Endpoint
| Endpoint | URL | 当前状态 |
|---|---|---|
| Staging 平台 | `https://web-staging-8e30.up.railway.app` | `/health` 200, `/ready` 200, 未认证的受保护 API 401;服务共享当前策略摘要 |
| 生产平台 | `https://web-production-44528.up.railway.app` | 可达但存在发布偏差;请勿发起活动 |
| 授权的外部目标 | `https://agent-production-9f62.up.railway.app` | 在只读审计中处于活跃且健康状态;活跃流量仍需确切授权 |
已部署的 URL 会随每次检查点提交,但健康的 URL 并不等于活动被接受。
## 安全不变量
- 无真实 PHI。Fixture、canary、证据、演示和文档均使用合成数据。
- Red Team、Judge、Orchestrator 和 Documentation 是独立的角色和信任上下文。
- 模型 Judge 无法确认漏洞利用。只有 oracle、合成 canary 或人类才能确认。
- 已确认的漏洞利用无法降级为安全。
- Clerk 认证本身从不授权执行目标。
- 发起者不能批准自己的操作。
- 只有 Policy Gateway 能发布目标范围的 credential 并发送目标流量。
- 目标、surface、版本、工作负载、credential 生成、caps、租约、策略和托管
配置都是与授权绑定的确切值。
- 关键的发布和所有修复都需要人工批准。
- 成本和使用量来自持久的已测量事实;没有占位符被呈现为已测量数据。
## 架构
```
flowchart LR
B["Authenticated browser"] --> W["Railway Web
React + FastAPI"] C["Clerk"] --> B W --> P[("PostgreSQL
control plane + queue + evidence")] S["Private Scheduler"] --> P R["Private Runner"] --> P R --> O["OpenRouter
four hosted roles"] R --> L["Langfuse
fail-soft projection"] R --> G["Policy Gateway"] G --> T["Authorized live target"] ``` 在一个受管治的用例中: ``` flowchart LR O["Orchestrator"] --> RT["Hosted Red Team
closed reviewed-case selection"] RT --> PG["Policy Gateway"] PG --> T["Live target"] T --> E["Hashed AttemptResult"] E --> J["Independent Judge
model + oracle reconciliation"] J -->|confirmed only| D["Documentation + regression admission"] ``` PostgreSQL 是事实的来源。Langfuse 接收经过净化处理的投影,并且仅在 通过认证的确切查询反馈后才成为交付 证据。 请参阅 [`ARCHITECTURE.md`](ARCHITECTURE.md) 以了解绑定架构和 AI 使用披露。 ## 当前托管角色 | 角色 | 模型 | 当前 staging upstream | |---|---|---| | Orchestrator | `anthropic/claude-opus-4.8` | Anthropic | | Red Team | `qwen/qwen3.5-397b-a17b` | Chutes | | Judge | `google/gemini-2.5-pro` | Google Vertex | | Documentation | `openai/gpt-5.4` | OpenAI | 线上的 Red Team 仅从不可变的已审查语料库中进行选择。新颖/变异的候选生成 已被隔离,在人工审查、冻结来源、生成新的工作负载摘要以及 获得新的授权之前,无法触及目标。 ## 仓库布局 | 路径 | 用途 | |---|---| | `src/agentforge/` | 应用程序包 | | `src/agentforge/agents/` | 四种 agent 角色、托管策略/runtime、prompt | | `src/agentforge/policy/` | allowlist、范围受限的 credential、Policy Gateway、记录器 | | `src/agentforge/campaign/` | 授权、工作负载解析、协调器 | | `src/agentforge/control_plane/` | 持久控制平面存储和记录 | | `src/agentforge/providers/` | OpenRouter 传输、使用量账本、物理血缘 | | `src/agentforge/telemetry/` | PostgreSQL/Langfuse 投影 | | `src/agentforge/contracts/v1/` | 打包的 JSON Schema 契约 | | `evals/` | 合成 fixture、已审查工作负载、校准/证据产出物 | | `migrations/` | Alembic 历史;仓库唯一 head 为 `0032`;部署状态单独跟踪 | | `console/` | React/Vite 操作员控制台 | | `railway/` | Web/Runner/Scheduler 服务清单 | | `docs/` | 当前的 runbook 以及标有日期的证据/历史记录 | ## 本地开发 要求: - Python 3.12+ - Node `^20.19 || >=22.12` - PostgreSQL 16 ``` python3.12 -m venv .venv source .venv/bin/activate python -m pip install -e '.[dev]' cp .env.example .env.local docker compose up -d postgres alembic upgrade head cd console npm ci --ignore-scripts VITE_CLERK_PUBLISHABLE_KEY=pk_test_your_local_fixture npm run build cd .. python -m agentforge.web ``` `.env.local` 仅供本地使用。切勿提交 secret 或真实的临床数据。在 PostgreSQL 于确切的打包 Alembic head 处可达、console 构建存在且 Clerk/Web 安全配置解析成功之前,`/ready` 将返回 503。 ### 本地检查 ``` ruff check . ruff format --check . pytest cd console npm run typecheck npm test npm run check:forbidden npm run build npm run check:bundle ``` 单元和集成测试使用本地 fixture key 和受控的 adapter。它们禁止 联系 Clerk、Railway、Langfuse、模型 provider 或线上目标。 ## 人员访问权限 控制台使用仅限邀请的 Clerk 访问权限,每个环境对应一个确切的 Headshot Organization,并且 强制要求 MFA。后端仅授权来自已验证 session 声明的自定义 Organization 权限。 | 角色 | 权限 | |---|---| | `org:operator` | 控制台/发现/证据/审计读取;活动启动/中止;目标/配置管理 | | `org:approver` | 控制台/发现/证据/审计读取;活动授权;发现批准/解决 | 后端强制执行 [`docs/security/AUTHENTICATION.md`](docs/security/AUTHENTICATION.md) 中记录的完整确切权限名称。前端标签仅用于改善 UX。 无鉴权路由仅限于: - `GET /health`; - `GET /ready`;以及 - 静态/登录/session-task 应用程序外壳。 所有 `/api/v1` 的数据和变更默认受保护。缺失或无效的身份验证将返回 通用的 401。经过身份验证但缺乏确切 Organization/权限或独立人员 条件的主体将收到 403。损坏的验证器/安全配置会安全失败(失败关闭)。 受保护的线上读取模型包括: - `GET /api/v1/campaigns/{campaign_id}/operations`,受 `org:console:read` 和确切 Organization/campaign 范围控制;以及 - `GET /api/v1/agent-executions/{execution_id}/prompt-snapshot`,额外受 `org:evidence:read` 和确切 Organization/execution 范围控制。 Prompt 内容仅为单个展开的 execution 获取,并排除在列表、聚合、 event-stream、日志和 Langfuse payload 之外。Migration `0027` 特意没有 prompt-snapshot 回填:在该迁移之前创建的 execution 没有不可变快照,因此受保护的 endpoint 返回 HTTP 200 以及空的资源状态(如果验证/存储不可用, 则返回 `Unavailable`),并且控制台渲染 `Unavailable` 而不是重构 prompt。 针对每次物理调用的证据路由在接收端的行为相同。Migration `0028` 没有响应回填:在此之前确定的调用不包含记录的响应, 并且该路由明确报告该缺失,而不是将哈希或重构内容 作为响应内容呈现。它的 prompt 成员重用相同的受保护快照访问器,因此两半部分共享一个授权、 哈希验证和 secret 拒绝路径。记录的响应字节绝不会出现在聚合的 `provider-calls` 投影、SSE、日志、Langfuse 元数据或浏览器 bundle 中。 ## 活动授权 线上活动需要: 1. 经过认证的 Operator 请求; 2. 不可变的确切范围; 3. 由不同的已认证 Approver 批准; 4. 当前的 Web/Runner/Scheduler 发布版本对齐; 5. 当前的 Runner 心跳; 6. 处于就绪状态的 allowlisted 目标/surface/版本; 7. 已审查的工作负载和合成 fixture/canary 来源; 8. 密封的目标和 provider credential 引用; 9. 覆盖完整超时时间的授权和目标 session 租约; 10. 确切的模型/配置/生成策略权限;以及 11. 目标和 provider 的调用/token/cost/rate/retry/concurrency caps。 失败将拒绝启动或在不安全地继续之前中止。在 部署或权限更改后,先前的批准不可重复使用。 ## 文档 当前: - [当前状态](docs/CURRENT_STATE.md) - [架构](ARCHITECTURE.md) - [可靠性计划](PLAN.md) - [Railway runbook](docs/deployment/RAILWAY.md) - [认证契约](docs/security/AUTHENTICATION.md) - [成本分析](docs/cost/COST_ANALYSIS.md) - [威胁模型](THREAT_MODEL.md) - [用户与工作流](USERS.md) 历史/详细证据: - [需求矩阵](docs/requirements/REQUIREMENTS_MATRIX.md) - [红队覆盖审查,2026-07-25](docs/security/RED_TEAMING_COVERAGE_REVIEW_2026-07-25.md) - [Langfuse 审查,2026-07-24](docs/security/LANGFUSE_AGENT_OBSERVABILITY_REVIEW_2026-07-24.md) - [漏洞报告](docs/vulnerabilities/README.md) 历史文件保留了在其日期观察到的事实。它们不覆盖当前状态 快照。 ## 发布纪律 GitHub Actions 和 GitLab CI 都是发布门控。仅在以下情况下发布才有效: - GitHub 和 GitLab CI 在确切的提交上均为绿色通过; - 相同的提交存在于 `origin` 和 `gitlab` 上; - Web、Runner 和 Scheduler 使用相同的产出物/策略; - PostgreSQL 处于打包的唯一 Alembic head 处;且 - 在进行新的线上授权之前,部署后的无目标验收测试成功。 部署、Railway 变量更改、credential 轮换和线上活动都是明确的 人工操作。代码或文档的更改并不对其授权。
React + FastAPI"] C["Clerk"] --> B W --> P[("PostgreSQL
control plane + queue + evidence")] S["Private Scheduler"] --> P R["Private Runner"] --> P R --> O["OpenRouter
four hosted roles"] R --> L["Langfuse
fail-soft projection"] R --> G["Policy Gateway"] G --> T["Authorized live target"] ``` 在一个受管治的用例中: ``` flowchart LR O["Orchestrator"] --> RT["Hosted Red Team
closed reviewed-case selection"] RT --> PG["Policy Gateway"] PG --> T["Live target"] T --> E["Hashed AttemptResult"] E --> J["Independent Judge
model + oracle reconciliation"] J -->|confirmed only| D["Documentation + regression admission"] ``` PostgreSQL 是事实的来源。Langfuse 接收经过净化处理的投影,并且仅在 通过认证的确切查询反馈后才成为交付 证据。 请参阅 [`ARCHITECTURE.md`](ARCHITECTURE.md) 以了解绑定架构和 AI 使用披露。 ## 当前托管角色 | 角色 | 模型 | 当前 staging upstream | |---|---|---| | Orchestrator | `anthropic/claude-opus-4.8` | Anthropic | | Red Team | `qwen/qwen3.5-397b-a17b` | Chutes | | Judge | `google/gemini-2.5-pro` | Google Vertex | | Documentation | `openai/gpt-5.4` | OpenAI | 线上的 Red Team 仅从不可变的已审查语料库中进行选择。新颖/变异的候选生成 已被隔离,在人工审查、冻结来源、生成新的工作负载摘要以及 获得新的授权之前,无法触及目标。 ## 仓库布局 | 路径 | 用途 | |---|---| | `src/agentforge/` | 应用程序包 | | `src/agentforge/agents/` | 四种 agent 角色、托管策略/runtime、prompt | | `src/agentforge/policy/` | allowlist、范围受限的 credential、Policy Gateway、记录器 | | `src/agentforge/campaign/` | 授权、工作负载解析、协调器 | | `src/agentforge/control_plane/` | 持久控制平面存储和记录 | | `src/agentforge/providers/` | OpenRouter 传输、使用量账本、物理血缘 | | `src/agentforge/telemetry/` | PostgreSQL/Langfuse 投影 | | `src/agentforge/contracts/v1/` | 打包的 JSON Schema 契约 | | `evals/` | 合成 fixture、已审查工作负载、校准/证据产出物 | | `migrations/` | Alembic 历史;仓库唯一 head 为 `0032`;部署状态单独跟踪 | | `console/` | React/Vite 操作员控制台 | | `railway/` | Web/Runner/Scheduler 服务清单 | | `docs/` | 当前的 runbook 以及标有日期的证据/历史记录 | ## 本地开发 要求: - Python 3.12+ - Node `^20.19 || >=22.12` - PostgreSQL 16 ``` python3.12 -m venv .venv source .venv/bin/activate python -m pip install -e '.[dev]' cp .env.example .env.local docker compose up -d postgres alembic upgrade head cd console npm ci --ignore-scripts VITE_CLERK_PUBLISHABLE_KEY=pk_test_your_local_fixture npm run build cd .. python -m agentforge.web ``` `.env.local` 仅供本地使用。切勿提交 secret 或真实的临床数据。在 PostgreSQL 于确切的打包 Alembic head 处可达、console 构建存在且 Clerk/Web 安全配置解析成功之前,`/ready` 将返回 503。 ### 本地检查 ``` ruff check . ruff format --check . pytest cd console npm run typecheck npm test npm run check:forbidden npm run build npm run check:bundle ``` 单元和集成测试使用本地 fixture key 和受控的 adapter。它们禁止 联系 Clerk、Railway、Langfuse、模型 provider 或线上目标。 ## 人员访问权限 控制台使用仅限邀请的 Clerk 访问权限,每个环境对应一个确切的 Headshot Organization,并且 强制要求 MFA。后端仅授权来自已验证 session 声明的自定义 Organization 权限。 | 角色 | 权限 | |---|---| | `org:operator` | 控制台/发现/证据/审计读取;活动启动/中止;目标/配置管理 | | `org:approver` | 控制台/发现/证据/审计读取;活动授权;发现批准/解决 | 后端强制执行 [`docs/security/AUTHENTICATION.md`](docs/security/AUTHENTICATION.md) 中记录的完整确切权限名称。前端标签仅用于改善 UX。 无鉴权路由仅限于: - `GET /health`; - `GET /ready`;以及 - 静态/登录/session-task 应用程序外壳。 所有 `/api/v1` 的数据和变更默认受保护。缺失或无效的身份验证将返回 通用的 401。经过身份验证但缺乏确切 Organization/权限或独立人员 条件的主体将收到 403。损坏的验证器/安全配置会安全失败(失败关闭)。 受保护的线上读取模型包括: - `GET /api/v1/campaigns/{campaign_id}/operations`,受 `org:console:read` 和确切 Organization/campaign 范围控制;以及 - `GET /api/v1/agent-executions/{execution_id}/prompt-snapshot`,额外受 `org:evidence:read` 和确切 Organization/execution 范围控制。 Prompt 内容仅为单个展开的 execution 获取,并排除在列表、聚合、 event-stream、日志和 Langfuse payload 之外。Migration `0027` 特意没有 prompt-snapshot 回填:在该迁移之前创建的 execution 没有不可变快照,因此受保护的 endpoint 返回 HTTP 200 以及空的资源状态(如果验证/存储不可用, 则返回 `Unavailable`),并且控制台渲染 `Unavailable` 而不是重构 prompt。 针对每次物理调用的证据路由在接收端的行为相同。Migration `0028` 没有响应回填:在此之前确定的调用不包含记录的响应, 并且该路由明确报告该缺失,而不是将哈希或重构内容 作为响应内容呈现。它的 prompt 成员重用相同的受保护快照访问器,因此两半部分共享一个授权、 哈希验证和 secret 拒绝路径。记录的响应字节绝不会出现在聚合的 `provider-calls` 投影、SSE、日志、Langfuse 元数据或浏览器 bundle 中。 ## 活动授权 线上活动需要: 1. 经过认证的 Operator 请求; 2. 不可变的确切范围; 3. 由不同的已认证 Approver 批准; 4. 当前的 Web/Runner/Scheduler 发布版本对齐; 5. 当前的 Runner 心跳; 6. 处于就绪状态的 allowlisted 目标/surface/版本; 7. 已审查的工作负载和合成 fixture/canary 来源; 8. 密封的目标和 provider credential 引用; 9. 覆盖完整超时时间的授权和目标 session 租约; 10. 确切的模型/配置/生成策略权限;以及 11. 目标和 provider 的调用/token/cost/rate/retry/concurrency caps。 失败将拒绝启动或在不安全地继续之前中止。在 部署或权限更改后,先前的批准不可重复使用。 ## 文档 当前: - [当前状态](docs/CURRENT_STATE.md) - [架构](ARCHITECTURE.md) - [可靠性计划](PLAN.md) - [Railway runbook](docs/deployment/RAILWAY.md) - [认证契约](docs/security/AUTHENTICATION.md) - [成本分析](docs/cost/COST_ANALYSIS.md) - [威胁模型](THREAT_MODEL.md) - [用户与工作流](USERS.md) 历史/详细证据: - [需求矩阵](docs/requirements/REQUIREMENTS_MATRIX.md) - [红队覆盖审查,2026-07-25](docs/security/RED_TEAMING_COVERAGE_REVIEW_2026-07-25.md) - [Langfuse 审查,2026-07-24](docs/security/LANGFUSE_AGENT_OBSERVABILITY_REVIEW_2026-07-24.md) - [漏洞报告](docs/vulnerabilities/README.md) 历史文件保留了在其日期观察到的事实。它们不覆盖当前状态 快照。 ## 发布纪律 GitHub Actions 和 GitLab CI 都是发布门控。仅在以下情况下发布才有效: - GitHub 和 GitLab CI 在确切的提交上均为绿色通过; - 相同的提交存在于 `origin` 和 `gitlab` 上; - Web、Runner 和 Scheduler 使用相同的产出物/策略; - PostgreSQL 处于打包的唯一 Alembic head 处;且 - 在进行新的线上授权之前,部署后的无目标验收测试成功。 部署、Railway 变量更改、credential 轮换和线上活动都是明确的 人工操作。代码或文档的更改并不对其授权。
标签:AI安全, AV绕过, Chat Copilot, CISA项目, FastAPI, LLM安全测试, PyRIT, React, Syscalls, 人工智能, 多智能体系统, 测试用例, 版权保护, 用户模式Hook绕过, 红队评估, 逆向工具, 配置审计