🔑 认证

除内部 /in/v1 接口外,所有接口都需要认证:请求时在 HTTP 头中携带 Authorization: Bearer <token>

curl -H "Authorization: Bearer <token>" \
     https://<your-instance>/api/bkn-backend/v1/knowledge-networks

若部署使用自签名证书(测试、内网环境常见),本页所有 curlopenbkn 命令均需追加 -k(即 --insecure,跳过 TLS 证书校验,仅限开发环境使用)。

获取 token 有三种方式,按场景选择:

方式适用场景覆盖范围
CLI 登录个人 / 交互使用全部服务接口
AppKey(bak_脚本 / 自动化仅 Context Loader(检索 / MCP,只读
应用集成设备码流自研应用以用户身份调用全部服务接口

方式一 · CLI 登录(个人使用,推荐)

bkn-sdkopenbkn CLI 登录一次,后续所有命令自动携带 token 并按需刷新。登录基于 OAuth2 设备码流程(RFC 8628)。

# 浏览器登录(打印 URL + user code,在浏览器里确认)
# 自签名证书的部署需加 -k
openbkn auth login https://<your-instance>

# 无浏览器 / CI 场景:使用用户名密码,CLI 自动完成 login/consent 流程(-k 同上)
openbkn auth login https://<your-instance> -u <account> -p <password> -k

需要获取原始 token(例如供其它工具或 curl 使用)时,用 token 子命令打印(过期会自动刷新):

openbkn auth token           # 打印当前 access token(自动刷新)
openbkn auth status          # 查看是否已登录 / 当前平台
openbkn auth whoami          # 查看当前身份

# 供 curl 直接使用:
curl -H "Authorization: Bearer $(openbkn auth token)" \
     https://<your-instance>/api/bkn-backend/v1/knowledge-networks

方式二 · AppKey(自动化,推荐)

覆盖范围:AppKey 是给 Context Loader(检索 / MCP,/api/agent-retrieval/...)用的长期凭据,仅支持只读操作(刻意的权限分层设计,写接口不接受 AppKey)。请求以签发人身份执行,可读范围与签发人的 OAuth token 一致。写操作或其它服务接口请使用 OAuth token。

支持两种签发方式:在 BKN Studio 个人中心页面自助签发和管理,或使用已登录的 OAuth token 调用接口签发(AppKey 本身不能用于签发新的 AppKey)。name 必填;不传 expires_at 默认有效期 1 年。

# 签发(需已登录的 OAuth token)
curl -X POST https://<your-instance>/api/safe/v1/me/api-keys \
  -H "Authorization: Bearer $(openbkn auth token)" \
  -H "Content-Type: application/json" \
  -d '{"name":"my-key","expires_at":"2027-01-01T00:00:00Z"}'

# 201 响应,明文 key 只在此出现一次,务必保存:
# {"id":"...","key_id":"2882bb603277","name":"my-key",
#  "key":"bak_2882bb603277_BSxTZHTBiJXk4QoUBc0u17zSWua",
#  "masked":"bak_2882****SWua","expires_at":"...","enabled":true}

# 使用(同样走 Bearer 头;仅限 Context Loader 接口。kn_id 必填,也可通过 X-Kn-ID 头传递)
curl -X POST https://<your-instance>/api/agent-retrieval/v1/kn/search_schema \
  -H "Authorization: Bearer bak_2882bb603277_BSxTZHTBiJXk4QoUBc0u17zSWua" \
  -H "Content-Type: application/json" \
  -d '{"query":"客户","kn_id":"<知识网络ID>"}'

CLI 等价:openbkn appkey create --name my-key;使用时 openbkn --token bak_... context ...。管理:GET /api/safe/v1/me/api-keys 列出、DELETE /api/safe/v1/me/api-keys/{id} 撤销、POST /api/safe/v1/me/api-keys/{id}/regenerate 轮换。

Python 示例

import requests

BASE = "https://<your-instance>"
oauth_token = "<OAuth access token>"  # 例如 CLI 里 `openbkn auth token` 的输出

# 签发(明文 key 只在响应里出现一次,务必保存)
resp = requests.post(
    f"{BASE}/api/safe/v1/me/api-keys",
    headers={"Authorization": f"Bearer {oauth_token}"},
    json={"name": "my-key"},          # 可选 "expires_at",缺省 1 年
)
app_key = resp.json()["key"]          # bak_...

# 使用(Context Loader 检索接口,只读;kn_id 必填,也可通过 X-Kn-ID 头传递)
r = requests.post(
    f"{BASE}/api/agent-retrieval/v1/kn/search_schema",
    headers={"Authorization": f"Bearer {app_key}"},
    json={"query": "客户", "kn_id": "<知识网络ID>"},
)

自签名证书环境下,给每个请求加 verify=False(或通过 requests.Session() 统一设置)。

方式三 · 在自己的应用里集成登录(设备码流)

开发自己的应用调用平台接口时,无需注册 client,也无需管理员介入:每套部署都预置了公共客户端 openbkn-sdk(OAuth2 设备码流程,RFC 8628)。应用引导用户在浏览器中登录一次,即可获得该用户权限的 token,之后通过 refresh token 长期免登录运行。

第 1 步 · 发起设备授权

curl -X POST https://<your-instance>/oauth2/device/auth \
  -d "client_id=openbkn-sdk" -d "scope=openid offline"
# -> {"device_code":"ory_dc_...","user_code":"EKgw7AQa",
#     "verification_uri_complete":"https://<your-instance>/oauth2/device/verify?user_code=EKgw7AQa",
#     "expires_in":600,"interval":5}

第 2 步 · 用户浏览器确认

verification_uri_complete 展示给用户(链接或二维码均可)。用户打开后确认设备码,输入平台账号密码登录并同意授权。

第 3 步 · 轮询换取 token

curl -X POST https://<your-instance>/oauth2/token \
  -d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
  -d "device_code=ory_dc_..." \
  -d "client_id=openbkn-sdk"
# 用户完成登录前返回 {"error":"authorization_pending"},按 interval 秒的间隔重试;
# 完成后 -> {"access_token":"...","refresh_token":"...","expires_in":3600,
#            "scope":"openid offline","token_type":"bearer"}

第 4 步 · 调用接口与续期

# 调用任意服务接口(token 权限 = 登录用户的权限)
curl -H "Authorization: Bearer <access_token>" \
     https://<your-instance>/api/bkn-backend/v1/knowledge-networks

# access token 有效期 1 小时;用 refresh token 续期,无需用户再次登录。
# 每次续期都会轮换出新的 refresh_token,务必保存最新一份:
curl -X POST https://<your-instance>/oauth2/token \
  -d "grant_type=refresh_token" \
  -d "refresh_token=<refresh_token>" \
  -d "client_id=openbkn-sdk"

Python 完整示例

import time
import requests

BASE = "https://<your-instance>"
CLIENT_ID = "openbkn-sdk"

s = requests.Session()
# s.verify = False   # 自签名证书的部署打开这行

# 1. 发起设备授权
da = s.post(f"{BASE}/oauth2/device/auth",
            data={"client_id": CLIENT_ID, "scope": "openid offline"}).json()
print("请在浏览器打开并登录:", da["verification_uri_complete"])

# 2. 轮询换 token(用户完成登录前返回 authorization_pending)
while True:
    time.sleep(da.get("interval", 5))
    r = s.post(f"{BASE}/oauth2/token", data={
        "grant_type": "urn:ietf:params:oauth:grant-type:device_code",
        "device_code": da["device_code"],
        "client_id": CLIENT_ID,
    }).json()
    if "access_token" in r:
        tokens = r
        break
    if r.get("error") not in ("authorization_pending", "slow_down"):
        raise RuntimeError(r)

# 3. 调用接口(token 权限 = 登录用户的权限)
kns = s.get(f"{BASE}/api/bkn-backend/v1/knowledge-networks",
            headers={"Authorization": f"Bearer {tokens['access_token']}"}).json()

# 4. access token 1 小时过期;用 refresh token 续期,无需再登录。
#    每次续期都会轮换出新的 refresh_token,务必覆盖保存最新一份。
tokens = s.post(f"{BASE}/oauth2/token", data={
    "grant_type": "refresh_token",
    "refresh_token": tokens["refresh_token"],
    "client_id": CLIENT_ID,
}).json()
token 属于用户委托凭据:应用以「完成登录的那个用户」的身份调用接口,权限随该用户的授权变化。全自动的后台服务建议使用专属服务账号完成第 2 步登录,之后通过 refresh token 持续运行;refresh token 一旦失效(长期未使用或被撤销),需要用户重新登录一次。

提示:openbkn-sdk 是公共客户端(无 secret,安全性由 PKCE 与设备码流程保障),任何应用均可直接使用。若以脚本代替浏览器完成登录页(CI 等无头场景),注意登录 / 授权页 URL 中的 *_challenge 参数是百分号编码的,提交表单前需先做 URL 解码,否则会因二次编码而报错。

方式一的交互式登录底层就是方式三的设备码流程,由 CLI 自动完成,无需自行实现。