PentAGI v2.2.0 API 使用详解

PentAGI v2.2.0 API 使用详解:认证双轨(会话 Cookie 与 Bearer API Token 及 userTier 权限边界)、REST 通用分页约定、flow 生命周期实操(创建/控制/删除)、GraphQL 查询与变更、日志排查接口,附 5 条实测排障,2026-10-23 溯源与实测。

PentAGI安全测试LLM2026/10/23

PentAGI v2.2.0 API 使用详解

目标:面向需要对 PentAGI 做二次集成、自动化编排与远程排障的工程师,讲清 v2.2.0 的 API 认证体系、REST 与 GraphQL 两套接口的用法与 flow 生命周期控制。全部接口结构与关键行为均溯源自 v2.2.0 源码与本机实测,日期为 2026-10-23。

一、环境信息与篇型说明

项目值
软件版本PentAGI v2.2.0(2026-10-05 发布)
实测镜像vxcontrol/pentagi:2.2.0(本机 Compose 部署,宿主端口 8150)
API 基地址https://<宿主>:<端口>/api/v1(OpenAPI 声明 basePath: /api/v1,默认部署自带自签 TLS)
认证方式会话 Cookie(Web)与 Authorization: Bearer <JWT>(API Token)双轨
溯源与实测日期2026-10-23

篇型说明:原任务按"常用 CLI 命令详解"立项,但实测确认 PentAGI v2.2.0 不提供独立 CLI——官方镜像与仓库中无 CLI 二进制,官方文档的管理入口为 Web 控制台与 HTTP API。故本文按 API 交互篇编写,覆盖原"CLI/API 交互、flow 控制、日志排查"全部目标场景。

接口全景实测:v2.2.0 内置 OpenAPI 文档(/api/v1/swagger/doc.json,本批次已完整拉取),REST 端点约 110 个,另有 GraphQL 单端点 /api/v1/graphql。按功能分组:认证、flows(含任务/子任务/日志/截图/文件/用量)、assistants、prompts、knowledge、providers、resources、settings、usage、users/roles/tokens。

二、前置条件

  • 已按部署篇完成 Compose 部署并可用浏览器登录(存在至少一个用户);
  • 客户端备有 curl 与 jq(本文示例用于格式化响应);
  • 自签证书环境下 curl 需加 -k(或 --cacert 指向自签 CA)。

三、认证体系(实测)

3.1 会话 Cookie(Web 同源通道)

登录端点字段为 mail 与 password(源码 models/users.go Login 结构体,实测曾因误用 username 得到 400 Auth.InvalidLoginRequest):

$ curl -sk -c cookies.txt -X POST https://127.0.0.1:8150/api/v1/auth/login \
    -H 'Content-Type: application/json' \
    -d '{"mail":"user@example.com","password":"<你的密码>"}'

实测观察:HTTP 200,响应头 Set-Cookie 写入会话 Cookie(本批次保存为 cookies.txt,内容属会话凭据不予展示)。密码须满足内置强密码策略:至少 16 字符,或至少 8 字符且同时含大写、小写、数字、特殊字符(限 !@#$&*);实测 q1w2e3r4 被拒(InvalidPassword),q1W2e3R4! 通过。

3.2 API Token(Bearer JWT,机器对机器通道)

用会话 Cookie 创建 API Token(POST /tokens),响应即返回 JWT:

$ curl -sk -b cookies.txt -X POST https://127.0.0.1:8150/api/v1/tokens \
    -H 'Content-Type: application/json' \
    -d '{"name":"s8-doc-test","ttl":86400}' | jq

实测响应结构(JWT 属凭据,中间段省略):

{"data":{"id":1,"token_id":"CUaC7ESduF","user_id":1,"role_id":1,"name":"s8-doc-test","ttl":86400,"status":"active","created_at":"2026-10-22T21:15:54Z","updated_at":"2026-10-22T21:15:54Z","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.<…JWT 主体…>"},"status":"success"}

之后所有 Bearer 通道请求携带:

$ TOKEN=$(jq -r .data.token token.json)
$ curl -sk -H "Authorization: Bearer $TOKEN" https://127.0.0.1:8150/api/v1/flows/?page=1\&pageSize=5\&type=init | jq

3.3 两级权限边界(实测重点)

源码 pkg/server/router.go 将接口分为两档,实测行为与源码一致:

权限档覆盖接口接受的凭据
tokenTier(AuthTokenRequired)flows、prompts、knowledge、providers、resources、settings、usage、日志查询等业务接口Bearer JWT 或会话 Cookie 均可
userTier(AuthUserRequired)users、roles、tokens(用户/角色/API Token 管理)与用户自身资料接口仅会话 Cookie

实测记录:对 GET /users/ 携带有效 Bearer JWT 返回 403(cookie claim 校验失败);改用 -b cookies.txt 后正常返回。这不是故障而是设计——API Token 只该访问业务面,用户与令牌管理必须走人工会话。

四、REST 通用约定

  • 基地址 /api/v1,请求与响应均为 JSON;成功包络 {"data":…,"status":"success"};
  • 列表接口必带三个查询参数(源码 rdb/table.go TableQuery binding,实测缺任一项返回 400):
    • page:页码,最小 1,必填;
    • pageSize:每页条数;
    • type:查询类型,必填,合法值含 sort / filter / init / page / size(首次拉取用 init);
  • 可选:sort[](排序字段)、filters[](过滤条件)、group(分组字段)。

实测排障:GET /flows/ 不带参数直接 400;补全 page=1&pageSize=5&type=init 后 200。

五、Flow 生命周期 REST 实操

Flow 是 PentAGI 的执行单元:创建 flow 即下达首个任务,系统随后自动拉起沙箱容器执行。

5.1 创建 flow

请求体字段(源码 models/flows.go CreateFlow):input(首任务描述,必填)、provider(LLM provider 名,必填)、functions/resource_ids(可选):

$ curl -sk -H "Authorization: Bearer $TOKEN" -X POST https://127.0.0.1:8150/api/v1/flows/ \
    -H 'Content-Type: application/json' \
    -d '{"input":"对测试靶机做信息收集并输出报告","provider":"custom"}' | jq

实测响应(2026-10-22 21:17,flow 1):

{"data":{"id":1,"status":"created","title":"untitled","model":"unknown","model_provider_name":"custom","model_provider_type":"custom","language":"English","functions":{},"tool_call_id_template":"call_{r:24:x}","trace_id":null,"user_id":1,"created_at":"2026-10-22T21:17:32Z","updated_at":"2026-10-22T21:17:32Z"},"status":"success"}

创建成功后 PentAGI 随即执行首个任务:为 flow 拉起沙箱容器(本批次实测可见 vxcontrol/kali-linux 沙箱被创建,flow 标题也随镜像名更新)。

5.2 列表与详情

$ curl -sk -H "Authorization: Bearer $TOKEN" \
    'https://127.0.0.1:8150/api/v1/flows/?page=1&pageSize=5&type=init' | jq
$ curl -sk -H "Authorization: Bearer $TOKEN" \
    https://127.0.0.1:8150/api/v1/flows/1 | jq        # 单个 flow
$ curl -sk -H "Authorization: Bearer $TOKEN" \
    https://127.0.0.1:8150/api/v1/flows/1/containers  # flow 的沙箱容器

列表响应为 {"flows":[…],"total":N} 包络(源码 services/flows.go);flow 状态取值:created / running / waiting / finished / failed。

5.3 flow 控制(PUT = PatchFlow)

PUT /flows/{flowID} 按 action 分派,合法动作:stop / finish / input / rename / report(源码 PatchFlow 校验标签):

# 停止一个 running 的 flow
$ curl -sk -H "Authorization: Bearer $TOKEN" -X PUT https://127.0.0.1:8150/api/v1/flows/1 \
    -H 'Content-Type: application/json' -d '{"action":"stop"}' | jq
# flow 处于 waiting 时补充用户输入(input 动作必须带 input 字段)
$ curl -sk -H "Authorization: Bearer $TOKEN" -X PUT https://127.0.0.1:8150/api/v1/flows/1 \
    -H 'Content-Type: application/json' -d '{"action":"input","input":"改为只扫描 80/443 端口"}' | jq
# 重命名(rename 动作必须带 name 字段)
$ curl -sk -H "Authorization: Bearer $TOKEN" -X PUT https://127.0.0.1:8150/api/v1/flows/1 \
    -H 'Content-Type: application/json' -d '{"action":"rename","name":"内网靶机巡检"}' | jq

input 动作可选带 timeout(秒,30–7200)。实测记录:对停留在 created 状态(尚未真正开跑)的 flow 执行 stop 得到 Flows.NotFound 错误——stop 面向已运行的执行流,created 状态的 flow 直接 DELETE 即可。

5.4 删除

$ curl -sk -H "Authorization: Bearer $TOKEN" -X DELETE https://127.0.0.1:8150/api/v1/flows/1 | jq

六、GraphQL API

单端点 POST /api/v1/graphql,同样走 Bearer/Cookie 双凭据。schema 权威来源为源码 backend/pkg/graph/schema.graphqls(Web 控制台即用该接口)。

核心 Query(schema 实查):flows: [Flow!]!(无分页参数,与 REST 列表不同)、flow(flowId)、tasks(flowId)、terminalLogs(flowId)、messageLogs(flowId)、toolCallLogs(flowId)、usageStatsTotal 等。

核心 Mutation:createFlow(modelProvider: String!, input: String!, resourceIds: [ID!]): Flow!、stopFlow(flowId: ID!): ResultType!。

实测查询(2026-10-22 21:22,本批次真实响应):

$ curl -sk -H "Authorization: Bearer $TOKEN" https://127.0.0.1:8150/api/v1/graphql \
    -H 'Content-Type: application/json' \
    -d '{"query":"{ flows { id status title provider { type name } } }"}' | tee graphql_flows.json | jq
{"data":{"flows":[{"id":2,"status":"created","title":"vxcontrol/kali-linux","provider":{"type":"custom","name":"custom"}},{"id":1,"status":"failed","title":"untitled","provider":{"type":"custom","name":"custom"}}]}}

(flow 1 失败原因见 8.3——当时 mock 端点未返回 tool_calls;flow 2 在修复后成功创建沙箱。)

七、日志与排查接口

接口用途
GET /flows/{id}/termlogs/沙箱内终端命令执行日志(排障首选)
GET /flows/{id}/msglogs/模型消息日志(prompt/响应流水)
GET /flows/{id}/agentlogs/代理角色调度日志
GET /flows/{id}/searchlogs/搜索工具调用记录
GET /flows/{id}/toolcalls/工具调用明细(含参数与结果)
GET /flows/{id}/screenshots/网页截图清单,/{screenshotID}/file 取图
GET /flows/{id}/usage单 flow 的 token 用量
GET /usage/、GET /usage/{period}全局用量统计
GET /termlogs/ 等全局版跨 flow 检索同类日志

以上均支持第四节的三参数分页约定;全局日志接口便于"不记得哪个 flow 出过某条命令"的横向排查。

八、常见问题(含实测排障)

8.1 列表接口一律 400

缺 page/pageSize/type 任一参数。TableQuery 校验要求三者必填,首次拉取用 type=init(见第四节)。

8.2 Bearer Token 访问 users/tokens 返回 403

userTier 接口仅接受会话 Cookie(见 3.3)。用 -b cookies.txt 代替 -H "Authorization: …"。

8.3 flow 创建后立刻 failed:"no tool call ID samples collected"

flow 启动时会向所选 LLM 端点发一次探测调用采样其 tool call ID 形态(实测 flow 1 的 tool_call_id_template 为默认模板 call_{r:24:x})。端点若不支持 OpenAI tools 参数(返回纯文本、无 tool_calls 字段),探测失败即 flow failed。本批次实测:mock 端点补上 tool_calls 回显后,flow 2 正常创建沙箱。自定义 OpenAI 兼容网关必须完整支持 function calling。

8.4 Token 失效

API Token 按 ttl(秒)过期(实测 ttl=86400 即 24 小时);COOKIE_SIGNING_SALT 更换后所有旧会话与已签发 Token 全部失效,需重新登录并重建 Token。

8.5 登录 400 Auth.InvalidLoginRequest

请求体字段是 mail/password,不是 username;且密码需满足 3.1 的强密码策略。

九、参考链接