跳转到内容

HTTP API

RTC Agent 的 HTTP API 包含三类端点:OAuth2 认证处理用户登录和令牌管理,运维端点提供健康检查和指标采集,业务端点支持中断应答与记忆导出。认证流程遵循标准 OAuth2 授权码模式,兼容 GitHub、Google 等常见 Provider。

端点方法功能调用时机
/oauth2/authorizeGET获取授权重定向 URL用户点击登录
/oauth2/providersGET获取已启用的 OAuth Provider 列表前端初始化登录页
/oauth2/tokenPOST授权码换取令牌 / RFC 8693 Token Exchange授权回调后 / 外部 JWT 换取
/oauth2/refreshPOST刷新 access_token令牌即将过期

Admin-server 端点(独立服务,端口 8081)

Section titled “Admin-server 端点(独立服务,端口 8081)”
端点方法功能认证
/api/auth/loginPOST管理员邮箱密码登录无需认证
/api/auth/refreshPOST刷新 admin access_token无需认证
/api/auth/meGET获取当前管理员信息Admin JWT
/api/auth/logoutPOST登出,撤销 refresh_tokenAdmin JWT
/.well-known/jwks.jsonGETJWKS 公钥集合(供主服务器验证 JWT)无需认证
/healthGET健康检查无需认证

💡 Admin-server 是独立服务,通过 RFC 8693 Token Exchange 机制与主服务器集成。管理员登录 admin-server 后,其 JWT 可被主服务器识别为合法用户身份。详见下文 Admin-server 认证。

运维端点(无需 JWT 认证):/healthz(健康检查)、/readyz(就绪检查)、/metrics(Prometheus 指标)。

📌 安全变更:生产环境中 /metrics 和 debug 端点强制要求认证,未配置时将直接禁用。Server 还自动为 OAuth2 端点启用 IP 限流(5 req/s,突发 10),并添加 HSTS 和 Permissions-Policy 安全头。

业务端点(需要 JWT 认证):/api/sessions/{sessionID}/interrupts/{interruptID}/answer(提交中断应答)、/api/memories/export(导出记忆数据)、/api/credentials/temporary(获取 S3 临时凭证)、/api/presigned-url(生成预签名 URL)。

💡 设计要点:前端(F-C)调用 /oauth2/authorize 获取重定向 URL,将用户引导至 OAuth2 Provider 的授权页面。授权完成后,Provider 回调前端,前端拿到授权码后调用 /oauth2/token 完成令牌交换。


获取 OAuth2 授权页面的重定向 URL。前端拿到 URL 后将用户引导至 Provider 的授权页面。

参数位置必填类型说明
providerquery✅stringOAuth2 Provider 名称(如 "github")
redirect_uriquery❌string授权完成后的回调地址(可选,部分 Provider 需要)
code_challengequery❌stringPKCE code_challenge(RFC 7636),由 code_verifier 经 SHA-256 + base64url 编码得到
code_challenge_methodquery❌stringPKCE challenge 方法,推荐 S256(默认),也支持 plain
{
"redirect_url": "https://github.com/login/oauth/authorize?client_id=xxx&state=yyy",
"state": "a1b2c3d4e5"
}
字段类型说明
redirect_urlstringOAuth2 Provider 授权页面的完整 URL
statestringCSRF 防护随机状态参数,回调时必须原样传回

获取当前已启用的 OAuth2 Provider 列表。前端在初始化登录页时调用此端点,动态展示可用的登录选项。

无。

{
"providers": ["github", "google"]
}
字段类型说明
providersstring[]已启用的 Provider 名称列表(如 "github"、"google"、"mock")

💡 前端根据返回的 provider 列表动态渲染登录按钮。如果只启用了 mock provider,则列表为 ["mock"]。


使用授权码(Authorization Code)换取 access_token 和 refresh_token。这是 OAuth2 授权码流程的核心步骤。

{
"code": "auth_code_from_callback",
"redirect_uri": "https://your-app.com/callback",
"state": "a1b2c3d4e5",
"device_id": "uuid-generated-by-client",
"device_name": "Chrome on Mac",
"user_agent": "Mozilla/5.0 ..."
}
字段必填类型说明
code✅string授权码,由授权回调 URL 的 query 参数携带
redirect_uri❌string回调地址,建议与授权请求中的一致
state✅stringCSRF 防护 state,必须与授权请求中的 state 一致且仅使用一次
device_id❌string前端生成的设备 UUID,用于标识客户端设备
device_name❌string设备显示名称,如 "Chrome on Mac"
user_agent❌string客户端 User-Agent,用于设备识别
code_verifier❌stringPKCE code_verifier(RFC 7636),授权请求时传入 code_challenge,交换时传入原始 verifier

📌 PKCE 约束:如果授权请求中携带了 code_challenge,则令牌交换时 code_verifier 变为必填,服务端将验证 code_verifier 与 code_challenge 的匹配性。

{
"access_token": "eyJhbGciOi...",
"refresh_token": "dGhpcyBpcyBh...",
"expires_in": 3600,
"user_id": "user-uuid"
}
字段类型说明
access_tokenstringJWT access token,有效期由 expires_in 指定
refresh_tokenstringrefresh token,用于在 access_token 过期后换取新 token
expires_inintegeraccess token 过期时间(秒),通常为 3600(1 小时)
user_idstring已认证用户的唯一 ID

💡 Refresh Token 复用:refresh_token 在有效期内可多次使用,每次返回新的 access_token。refresh_token 本身不会被替换或撤销,直到自然过期(默认 30 天)。


POST /oauth2/token(Token Exchange — RFC 8693)

Section titled “POST /oauth2/token(Token Exchange — RFC 8693)”

POST /oauth2/token 同时支持授权码换取令牌和 RFC 8693 Token Exchange 两种模式,通过 grant_type 区分。当 grant_type 为 urn:ietf:params:oauth:grant-type:token-exchange 时,进入 Token Exchange 模式——将外部 JWT(如 admin-server 签发的管理员 JWT)换取 RTC 主服务器的 access_token。

💡 完整集成指南:本节仅包含 API 协议细节。如需了解完整的 Token Exchange 集成流程(包括如何签发 JWT、配置 JWKS 端点、前端配置等),请参阅 认证与授权 - Token Exchange 完整指南。

{
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
"subject_token": "eyJhbGciOi...(外部 JWT)",
"subject_token_type": "urn:ietf:params:oauth:token-type:access_token",
"device_id": "uuid-generated-by-client"
}
字段必填类型说明
grant_type✅string必须为 urn:ietf:params:oauth:grant-type:token-exchange
subject_token✅string外部 JWT(由受信任的签发方签发)
subject_token_type✅string令牌类型,通常为 urn:ietf:params:oauth:token-type:access_token
device_id✅stringRTC Agent 扩展字段,客户端设备 UUID(嵌入到签发的 JWT 中)

💡 同时支持 application/json 和 application/x-www-form-urlencoded 两种 Content-Type。

{
"access_token": "eyJhbGciOi...(RTC JWT)",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
"token_type": "Bearer",
"expires_in": 3600
}
字段类型说明
access_tokenstringRTC 主服务器签发的 JWT,有效期由 expires_in 指定
issued_token_typestring固定为 urn:ietf:params:oauth:token-type:access_token
token_typestring固定为 Bearer
expires_inintegeraccess token 过期时间(秒),通常为 3600(1 小时)

Token Exchange 错误响应遵循标准 OAuth2 错误格式:

{
"error": "invalid_grant",
"error_description": "Invalid subject_token"
}
HTTP 状态码error 值含义
400invalid_request缺少必填字段或 grant_type 不正确
400invalid_grantsubject_token 无效、JWT 签名验证失败或签发方不受信任
401invalid_grantJWT 验证失败且无法刷新 JWKS
500server_error服务端内部错误
503temporarily_unavailable身份提供方暂时不可用(JWKS 端点无法访问)

💡 错误格式说明:Token Exchange 端点使用标准 OAuth2 错误格式(error + error_description),与 /oauth2/token 的其他模式保持一致。这与 Admin-server 端点使用的统一响应格式(success + errorCode + errorMessage,始终返回 HTTP 200)不同。

📌 前置条件:主服务器需在 config.yaml 中配置 token_exchange.external_issuers 以信任对应的 JWT 签发方。详见 Admin-server 认证。


使用 refresh_token 换取新的 access_token。refresh_token 在有效期内可重复使用。

{
"refresh_token": "dGhpcyBpcyBh..."
}
字段必填类型说明
refresh_token✅stringrefresh token,有效期内可重复使用
{
"access_token": "eyJhbGciOi...(new)",
"expires_in": 3600
}
字段类型说明
access_tokenstring新的 JWT access token
expires_ininteger新 access token 过期时间(秒)

所有端点在出错时返回统一的错误格式:

{
"error": "invalid_grant",
"error_description": "Authorization code has expired"
}
错误码HTTP 状态码说明常见原因
invalid_request400请求参数无效缺少必填字段、格式错误
invalid_client400客户端认证失败Provider 配置错误
invalid_grant401授权码无效或已过期授权码已使用或超过有效期
server_error500服务器内部错误服务端异常

💡 Content-Type 支持:POST 端点(/oauth2/token 和 /oauth2/refresh)同时支持 application/json 和 application/x-www-form-urlencoded 两种请求格式。


运维端点无需 JWT 认证,供基础设施层调用。

健康检查端点,用于负载均衡器和 Kubernetes liveness probe。

响应:

{"status": "ok"}

就绪检查端点,用于 Kubernetes readiness probe。仅当服务完全启动并可接收请求时返回 200。会检查数据库、Redis 和 Centrifuge 的连接状态。

响应(服务就绪时):

{
"status": "ready",
"checks": {
"db": "ok",
"redis": "ok",
"centrifuge": "ok"
}
}

响应(服务未就绪时,HTTP 503):

{
"status": "not ready",
"checks": {
"db": "ok",
"redis": "error",
"centrifuge": "not configured"
}
}
字段类型说明
statusstring整体状态:"ready" 或 "not ready"
checksobject各依赖组件的检查结果
checks.dbstring数据库连接状态:"ok" 或 "error"
checks.redisstringRedis 连接状态:"ok" 或 "error"
checks.centrifugestringCentrifuge 状态:"ok"、"error" 或 "not configured"

Prometheus 指标端点,暴露服务运行指标,供监控系统(Prometheus / Grafana)采集。

响应:text/plain 格式的 Prometheus 指标。

认证:Basic Auth,通过 metrics.user 和 metrics.password 配置。生产环境必须配置认证,否则 /metrics 端点将被直接禁用;开发环境未配置时仍可访问。

💡 完整的 Prometheus 指标列表、Grafana 仪表盘和告警规则参见 可观测性监控。


业务端点需要 JWT 认证(Authorization: Bearer <token> 请求头)。开发模式下支持 X-User-ID / X-Device-ID 请求头旁路。

POST /api/sessions/{sessionID}/interrupts/{interruptID}/answer

Section titled “POST /api/sessions/{sessionID}/interrupts/{interruptID}/answer”

提交中断应答。当 AI 在执行过程中遇到需要用户决策的问题时,会通过中断机制暂停并向前端发送提问。前端收集用户回答后,通过此端点提交。

路径参数:

参数类型说明
sessionIDUUID会话 ID
interruptIDstring中断 ID(由中断事件携带)

请求体:

{
"answer": "用户对中断问题的回答"
}
字段必填类型说明
answer✅string用户的回答内容

响应:成功时返回 202 Accepted,响应体为 {"status": "accepted"}。

💡 内部实现使用 Redis 的 SET+PUBLISH 模式将应答投递给等待中的中断处理协程,确保应答不丢失。详见 中断处理流程。

导出记忆数据为 OKF(Open Knowledge Format)bundle。支持按范围(会话 / 用户 / 全局)、类型、标签过滤。

请求体:

{
"scope": "user",
"scopeId": "user-uuid",
"format": "okf-bundle",
"types": ["user", "feedback"],
"tags": ["work"],
"includeLog": false
}
字段必填类型说明
scope✅string导出范围:session / user / global
scopeId✅string范围对应的 ID(session UUID / user UUID / 空字符串)
format✅string导出格式,当前仅支持 okf-bundle
types—string[]按记忆类型过滤(可选)
tags—string[]按标签过滤(可选)
includeLog—boolean是否生成 log.md(默认 false)

响应:Content-Type: application/gzip,返回 gzip 压缩的 OKF bundle 流。

💡 由于采用流式响应,一旦开始写入响应体后发生错误,将无法返回 JSON 错误响应。客户端应通过 HTTP 状态码和 Content-Length 判断导出是否成功。

📌 OKF bundle 中的时间戳统一使用 UTC 时区,格式为 RFC 3339(如 2026-09-26T08:30:00Z)。


Admin-server 是独立于主服务器的管理服务,提供管理员登录、用户管理等功能。管理员通过 admin-server 登录后获得 JWT,该 JWT 可通过 RFC 8693 Token Exchange 机制被主服务器识别。

💡 完整集成指南:本节仅包含 Admin-server 的 API 协议细节。如需了解完整的 Token Exchange 集成流程(包括架构、配置、JWT 签发、JWKS 端点等),请参阅 认证与授权 - Token Exchange 完整指南。

在主服务器的 config.yaml 中配置 token_exchange 以信任 admin-server 签发的 JWT:

token_exchange:
external_issuers:
- name: "admin-server"
issuer: "http://admin-server:8081" # admin-server 地址
jwks_uri: "http://admin-server:8081/.well-known/jwks.json"
allowed_algorithms: ["RS256", "ES256"]
cache_ttl: 3600
# admin-server 使用标准 JWT claim 名称(email, name, picture),
# 默认映射即可覆盖,无需显式配置 claims_mapping
字段说明
nameissuer 标识名称
issuerJWT iss claim 必须匹配的值
jwks_uriJWKS 公钥端点地址
allowed_algorithms允许的签名算法(推荐 ES256 或 RS256)
cache_ttlJWKS 公钥缓存时间(秒)
claims_mappingJWT claims 到用户字段的映射

Admin-server 使用非对称密钥签名 JWT,支持 RS256 / ES256 / EdDSA 等算法。主服务器通过 JWKS 端点获取公钥进行验证,无需共享密钥。

终端窗口
# 方式一:使用 admin keygen 子命令(推荐)
./bin/rtc-agent admin keygen # 默认 RS256
./bin/rtc-agent admin keygen --algorithm ES256 # ES256(推荐用于生产)
./bin/rtc-agent admin keygen --algorithm EdDSA # EdDSA(Ed25519)
./bin/rtc-agent admin keygen --force # 强制覆盖已有密钥
# 方式二:使用脚本(兼容旧版)
./scripts/generate-keys.sh all # RS256 + ES256
./scripts/generate-keys.sh es256 # 仅 ES256
# 自动模式(Docker 部署时自动生成)
# Docker 容器首次启动时,docker-entrypoint.sh 会自动检测并生成 RS256 密钥对
# 密钥存储在 Docker named volume(full-admin-server-keys)中,跨重启持久化
# 生产环境建议使用持久化密钥,避免重启后所有 JWT 失效
环境密钥存储建议
开发本地 etc/keys/ 目录(已在 .gitignore 中排除 *.pem)
DockerNamed volume full-admin-server-keys(自动生成,跨重启持久化)
生产KMS 服务(AWS KMS / 阿里云凭据管家 / HashiCorp Vault)

💡 建议每 90 天轮换密钥。轮换时保留旧公钥 24-48 小时以兼容已签发的 token,详见 etc/keys/README.md。

💡 Admin-server 使用 Ant Design Pro 统一响应格式:成功时 { "success": true, "data": {...} },失败时 { "success": false, "errorCode": "...", "errorMessage": "..." }(HTTP 状态码始终为 200)。

📌 例外:/health 健康检查端点在数据库不可用时返回 HTTP 503(而非 200),以便负载均衡器和 Kubernetes 探针正确识别服务状态。

管理员邮箱密码登录。

请求体:

{
"email": "admin@example.com",
"password": "your-password"
}

成功响应(200):

{
"success": true,
"data": {
"access_token": "eyJhbGciOi...",
"refresh_token": "dGhpcyBpcyBh...",
"expires_in": 3600,
"token_type": "Bearer",
"user": {
"id": "uuid",
"email": "admin@example.com",
"name": "Admin",
"avatar_url": ""
}
}
}

使用 refresh_token 换取新的 access_token。每次刷新会同时返回新的 refresh_token(轮换机制),旧 refresh_token 立即失效。

请求体:

{
"refresh_token": "previous-refresh-token"
}

成功响应(200):

{
"success": true,
"data": {
"access_token": "eyJhbGciOi...(new)",
"refresh_token": "rt_...(new)",
"expires_in": 3600,
"token_type": "Bearer"
}
}

获取当前管理员信息。需要 Authorization: Bearer <admin-jwt> 请求头。

成功响应(200):

{
"success": true,
"data": {
"id": "uuid",
"email": "admin@example.com",
"name": "Admin",
"avatar_url": ""
}
}

撤销 refresh_token。需要 JWT 认证。

请求体:

{
"refresh_token": "refresh-token-to-revoke"
}

成功响应(200):

{
"success": true,
"data": {
"status": "ok"
}
}

返回 admin-server 的 JWK Set(RFC 7517),主服务器通过此端点获取公钥以验证 JWT 签名。

Admin-server 错误响应始终返回 HTTP 200,通过 errorCode 字段区分错误类型:

errorCode触发场景说明
invalid_request请求体格式错误、字段校验失败客户端应检查请求参数
invalid_credentials邮箱或密码错误登录凭证不正确
invalid_grantrefresh_token 无效、已撤销或已过期应引导用户重新登录
unauthorized缺少/无效/过期的 Authorization 头JWT 认证失败
user_not_found用户 ID 对应的用户不存在数据一致性异常
server_error服务器内部错误(密钥生成失败、数据库异常等)可重试,持续发生需排查