Platform
Platform(平台)就是整个 OpenBot 部署。一个平台有许多组织。
平台管理员负责运行平台。本页介绍如何设置平台,以及如何用 /v1/platform 管理它。
平台管理员
平台管理员管理平台。平台管理员不是每个组织的成员。除非他也是某个组织的成员,否则他不能读取这个组织的 Session、Agent 或成员。他只能通过 /v1/platform 管理平台。
平台管理员是一个电子邮件地址。当有人第一次用这个邮箱登录、并且提供方已验证该邮箱时,这个条目会关联到那个账号。
| 路由 | 作用 |
|---|---|
GET /v1/platform/admins |
列出平台管理员。 |
POST /v1/platform/admins |
添加一个平台管理员。请求体是 { email }。 |
DELETE /v1/platform/admins/:email |
移除一个平台管理员。 |
curl -b cookies.txt \ -H "Origin: https://api.example.com" \ -H "Content-Type: application/json" \ -d '{"email":"bob@example.com"}' \ https://api.example.com/v1/platform/admins{ "email": "bob@example.com", "userId": null, "addedAt": "2026-10-21T09:00:00.000Z"}在 Bob 第一次登录之前,userId 为 null。
平台必须至少保留一个管理员。移除最后一个管理员会返回 409 和 LastPlatformAdmin。
设置
新数据库中没有平台设置。在你运行设置程序之前,除 /health 之外的每个路由都会返回 503 和 SetupRequired。
设置程序用 OPENBOT_DATABASE_URL 和 OPENBOT_SECRET_KEYS 连接数据库。它会写入第一份平台设置和第一批平台管理员。
在镜像中,它是 /app/dist/app/Setup.mjs。从源代码运行时,使用 pnpm --filter @openbot-build/openbot setup。这个包还提供命令 openbot-setup。
docker run --rm --env-file openbot.env openbot:$OPENBOT_RELEASE \ /app/dist/app/Setup.mjs \ --public-origin=https://api.example.com \ --oidc-issuer=https://id.example.com \ --oidc-client-id=openbot \ --admin-email=alice@example.com| 参数 | 必需 | 作用 |
|---|---|---|
--public-origin |
是 | OpenBot 的公开 HTTPS 源,比如 https://api.example.com。不带路径,结尾不带斜杠。 |
--oidc-issuer |
与 ID 一起 | 平台 OpenID Connect 提供方的 HTTPS 地址,结尾不带斜杠。 |
--oidc-client-id |
与 issuer 一起 | 在该提供方那里的客户端 ID。 |
--oidc-client-secret |
否 | 客户端密钥。对于使用 PKCE 的公开客户端,不填。 |
--admin-email |
至少一个 | 拥有这个已验证邮箱的人登录后会成为平台管理员。要添加更多人,就重复这个参数。 |
--force |
否 | 即使设置已存在也写入。只在恢复时使用,也就是没有任何平台管理员能登录的时候。 |
--oidc-issuer 和 --oidc-client-id 要么一起设置,要么都不设置。当大家只通过各组织的 SSO 连接登录时,两者都不设置。
命令行可能会出现在进程列表中。所以,你可以改用环境变量 OPENBOT_SETUP_OIDC_CLIENT_SECRET 提供客户端密钥,而不是 --oidc-client-secret。这是更好的做法。
设置程序还会生成一个随机的登录密钥。Better Auth 用它来签名登录 cookie。OpenBot 加密保存它,你永远看不到它。
再次运行设置
- 使用同样的源和提供方时,设置程序什么也不改。它只会添加管理员邮箱。
- 使用其他值时,设置程序会失败。它会告诉你改用
PATCH /v1/platform/settings。 - 使用
--force时,设置程序会写入新的值。它会保留当前的登录密钥,所以不会因此让任何人退出登录。
平台设置
GET /v1/platform/settings 读取设置。PATCH /v1/platform/settings 修改设置。
curl -H "Authorization: Bearer $OPENBOT_TOKEN" \ https://api.example.com/v1/platform/settings{ "version": 3, "publicOrigin": "https://api.example.com", "identityProvider": { "issuer": "https://id.example.com", "clientId": "openbot", "clientSecret": { "set": true, "hint": "…k9Qz" } }, "organizationCreation": "anyone", "policyCeiling": [], "appRestrictions": [], "codeMode": { "enabled": false, "timeoutMs": 30000, "memoryMb": 64, "outputBytes": 65536 }, "rateLimit": { "requestsPerMinute": null }, "updatedAt": "2026-10-21T09:00:00.000Z"}| 字段 | 是什么 |
|---|---|
version |
每次修改加一。 |
publicOrigin |
OpenBot 的公开 HTTPS 源。 |
identityProvider |
平台的 OpenID Connect 提供方;当大家只通过 SSO 连接登录时为 null。 |
organizationCreation |
谁可以创建组织:anyone 或 platform_admins。参见组织创建。 |
policyCeiling |
对每个组织生效的拒绝策略。参见策略上限。 |
appRestrictions |
App Index 隐藏的 App。参见 App Index。 |
codeMode |
Agent 能否使用 Code Mode,以及它的限制。参见 Code Mode。 |
rateLimit |
每个调用方在一分钟内最多可以发送多少个 API 请求。参见速率限制。 |
updatedAt |
设置最后一次修改的时间。 |
机密永远不会返回
机密可以写入,但永远不会读出。响应中显示的是 { set, hint }:
- 当保存了机密时,
set为true。 hint是…加上最后 4 个字符,方便你区分不同的机密。对于短于 12 个字符的机密,它为null。
修改设置
PATCH 的请求体需要 expectedVersion,也就是你读到的 version。只加入你想修改的字段。
curl -X PATCH -H "Authorization: Bearer $OPENBOT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"expectedVersion":3,"organizationCreation":"platform_admins"}' \ https://api.example.com/v1/platform/settings如果有人在你读取之后修改了设置,OpenBot 会返回 409 和 SettingsConflict,以及当前的 version。请重新读取设置,然后再试一次。
PATCH 中的 identityProvider 是这样工作的:
| 值 | 结果 |
|---|---|
null |
移除平台提供方。 |
{ issuer, clientId } |
设置提供方,并保留当前的密钥。 |
{ issuer, clientId, clientSecret: "…" } |
设置提供方和一个新的密钥。 |
{ issuer, clientId, clientSecret: null } |
把提供方设置为公开的 PKCE 客户端。 |
每个实例都会立刻使用修改后的值。参见配置。
策略上限
policyCeiling 是一组在每个组织中都生效的策略。它们只能是 deny。OpenBot 在组织的策略之前检查它们,所以任何角色、任何令牌都不能做它们拒绝的事。
资源中可以用 {org} 表示请求所在的组织。参见权限。
下面这个上限禁止每个组织添加自己的模型提供方:
{ "expectedVersion": 4, "policyCeiling": [ { "effect": "deny", "permissionGroups": ["model_providers.write"], "resources": ["openbot.org.{org}"] } ]}列表最多包含 50 条策略。
组织创建
当一个账号登录时如果没有任何组织,OpenBot 可以为它创建一个。由 organizationCreation 决定:
| 值 | 结果 |
|---|---|
anyone |
默认值。没有组织的新账号会得到一个名为 “Personal” 的组织,它在其中是 Super Administrator。任何人都可以调用 POST /v1/organizations。 |
platform_admins |
新账号不会得到自己的组织。只有平台管理员可以调用 POST /v1/organizations。 |
账号加入组织的所有方式,参见组织。
组织
GET /v1/platform/organizations 分页列出平台的所有组织。使用 limit(1 到 100),以及值为上一页 next 的 after。
PATCH /v1/platform/organizations/:organizationId 修改组织的 status:active 或 suspended。
curl -X PATCH -H "Authorization: Bearer $OPENBOT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"status":"suspended"}' \ https://api.example.com/v1/platform/organizations/org_8f3a任何人都不能使用被暂停的组织。它的令牌会立刻失效。把 status 设为 active 即可撤销暂停。
GET /v1/platform/organizations/:organizationId/credits 读取一个组织的额度。对同一路由使用 PATCH 可以打开或关闭额度,POST .../credits/grants 给出额度。参见额度。
共享的模型提供方
平台可以为模型提供方付费,并把它们共享给各个组织。它也可以共享模型。组织也可以使用自己的密钥。参见 Model。
| 路由 | 作用 |
|---|---|
GET /v1/platform/models |
列出共享的模型。 |
POST /v1/platform/models |
添加一个共享的模型。 |
GET /v1/platform/models/:modelId |
读取一个共享的模型。 |
PATCH /v1/platform/models/:modelId |
修改一个共享的模型。 |
DELETE /v1/platform/models/:modelId |
移除一个共享的模型。 |
GET /v1/platform/model_providers |
列出共享的提供方。 |
POST /v1/platform/model_providers |
添加一个共享的提供方。 |
GET /v1/platform/model_providers/:providerId |
读取一个共享的提供方。 |
PATCH /v1/platform/model_providers/:providerId |
修改一个共享的提供方。 |
DELETE /v1/platform/model_providers/:providerId |
移除一个共享的提供方。 |
GET /v1/platform/model_providers/:providerId/prices |
列出一个共享的提供方的价格。参见价格。 |
PUT /v1/platform/model_providers/:providerId/prices |
为一个共享的提供方中的一个模型设置新价格。 |
请求体和组织的模型与提供方相同,只是多了 availability。先添加模型,再添加一个关联它的提供方:
curl -H "Authorization: Bearer $OPENBOT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "id": "gpt-4.1", "name": "GPT-4.1", "reasoningEfforts": [], "serviceTiers": [], "availability": { "_tag": "All" } }' \ https://api.example.com/v1/platform/models
curl -H "Authorization: Bearer $OPENBOT_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "kind": "openai", "name": "OpenAI", "apiKey": "sk-...", "models": [{ "model": "gpt-4.1", "modelOwner": "platform" }], "availability": { "_tag": "All" } }' \ https://api.example.com/v1/platform/model_providersavailability |
谁可以使用这个模型或提供方 |
|---|---|
{ "_tag": "All" } |
每个组织。 |
{ "_tag": "None" } |
没有任何组织。 |
{ "_tag": "Selected", "organizations": ["org_…"] } |
只有列出的组织。 |
只有当两者的 availability 都允许时,组织才能看到共享提供方的共享模型。
组织也可以把一个它能使用的共享模型关联到自己的提供方。这时它用自己的密钥使用这个模型。
共享提供方只能关联共享模型。当某个共享提供方关联着一个共享模型时,你不能移除这个模型:OpenBot 会返回 409 和 ModelInUse。
当你移除一个共享模型时,OpenBot 也会移除各组织的提供方与它之间的关联。
调用平台 API
/v1/platform 接受两种调用者:
- 平台管理员的 session cookie。
- 平台管理员的用户令牌。令牌自身的策略必须在资源
openbot.platform上允许platform.read(用于GET)或platform.write(用于其他所有方法)。
权限组 platform.read 和 platform.write 只对 openbot.platform 有效。组织中的任何角色都不会授予它们。
没有指定 policies 创建的令牌永远得不到它们。所以,用于平台的令牌必须在创建时写明它们:
curl -b cookies.txt \ -H "Origin: https://api.example.com" \ -H "Content-Type: application/json" \ -d '{"name":"Platform admin","expiresInDays":30,"policies":[{"effect":"allow","permissionGroups":["platform.read","platform.write"],"resources":["openbot.platform"]}]}' \ https://api.example.com/v1/user/tokens只有在它的账号仍是平台管理员时,令牌才有效。其他调用者会得到 403 和 PermissionDenied。
OpenBot 把每次平台修改写入审计日志,组织 ID 为 platform。API 目前还不能读取这些条目。
在 Platform 参考中查看完整的结构。
错误
| 状态 | 错误 | 何时 |
|---|---|---|
400 |
SettingsInvalid |
修改中的某个值无效。 |
403 |
PermissionDenied |
调用者不是平台管理员,或者令牌不允许。 |
404 |
OrganizationNotFound |
没有这个 ID 的组织。 |
404 |
PlatformAdminNotFound |
没有使用这个邮箱的平台管理员。 |
409 |
SettingsConflict |
有人在你读取之后修改了设置。 |
409 |
LastPlatformAdmin |
这次修改会让平台没有管理员。 |
503 |
SetupRequired |
还没有人运行过设置程序。 |
503 |
PlatformUnavailable |
OpenBot 无法访问它的数据库。 |