2669 字约 9 分钟
概述
平台令牌供第三方服务通过换票接口获取云原生构建 OpenAPI 的临时访问票据。
平台令牌申请
前往 admin 管理平台,为第三方服务创建平台令牌,获得 name 和 secret_key。
服务地址
服务请求地址为 3rd.cnbprod.alpha.qq.com。
接口
CNB 提供以下换票接口:
基于用户名的换票
- 接口地址:
/platform-token/-/user/{username} - 接口方法:"POST"
- 系统授权:system-token:rw
- 功能描述:换取指定 {username} 用户的个人令牌。
- 参数:
- expire:可选参数,令牌有效期,支持 1m ~ 24h
基于用户 ID 的换票
- 接口地址:
/platform-token/-/userid/{userid} - 接口方法:"POST"
- 系统授权:system-token:rw
- 功能描述:换取指定 {userid} 用户的个人令牌。
- 参数:
- expire:可选参数,令牌有效期,支持 1m ~ 24h
基于 OpenID 的换票
- 接口地址:
/platform-token/-/openid/{openid} - 接口方法:"POST"
- 系统授权:system-token:rw
- 功能描述:换取指定 {openid} 用户的个人令牌。
- 参数:
- user_type:可选参数,用户类型,对应关系如下:
0: 微信用户1: oauth 授权用户2: 测试用户3: 助手用户4: ioa 授权用户 默认值为1。
- expire:可选参数,令牌有效期,支持 1m ~ 24h
- user_type:可选参数,用户类型,对应关系如下:
基于仓库全路径的换票
- 接口地址:
/platform-token/-/repo/{repo-path} - 接口方法:"POST"
- 系统授权:system-token:rw
- 功能描述:随机选择 {repo-path} 仓库的某位负责人用户,换取该用户的个人令牌。
- 参数:
- expire:可选参数,令牌有效期,支持 1m ~ 24h
基于组织全路径的换票
- 接口地址:
/platform-token/-/organization/{organization-path} - 接口方法:"POST"
- 系统授权:system-token:rw
- 功能描述:随机选择 {organization-path} 组织的某位负责人用户,换取该用户的个人令牌。
- 参数:
- expire:可选参数,令牌有效期,支持 1m ~ 24h
列出所有根组织
- 接口地址:
/platform-token/-/organization - 接口方法:"GET"
- 系统授权:system-search:r
- 功能描述:列出所有根组织信息。
- 参数:
- page:页码,从 1 开始
- page_size:每页数量
- search:根组织名称,只支持全匹配
查找资源 ID 对应的对象信息
- 接口地址:
/platform-token/-/resolve/{type:string} - 接口方法:"POST"
- 系统授权:system-search:r
- 功能描述:根据资源 ID 查询对象信息。
- 参数:
type:类型 organization/repo/mission/registry/user
body:请求 ID 列表
{ "id": ["123"] }
获取活跃仓库列表
接口地址:
/platform-token/-/active-repos接口方法:"GET"
系统授权:system-search:r
功能描述:查询指定 10 分钟时间段内产生过动态的仓库列表, 用于第三方服务增量拉取仓库变更。
参数(时间参数均按 UTC+8 时区计算):
- date:可选参数,日期,格式 yyyyMMdd,默认当天
- hour:可选参数,小时,取值 0 ~ 23,默认当前小时
- segment:可选参数,10 分钟段编号,取值 0 ~ 5,默认当前所处的段。 每小时划分为 6 段,
0表示第 0 ~ 9 分钟,1表示第 10 ~ 19 分钟,依此类推
返回:活跃仓库列表,该时间段内没有动态时返回空数组
[ { "repo_id": "1293243433212", "slug": "organization/repo" } ]
注意
活跃仓库数据仅保留 24 小时,请在 24 小时内拉取,超出保留期的时间段返回空数组。 建议按 10 分钟的周期轮询,避免遗漏时间段。
查找绑定码或认证手机号码对应的对象信息
接口地址:
/platform-token/-/bind/user接口方法:"POST"
系统授权:system-bind:r
功能描述:根据绑定码或认证手机号码查询对象信息
参数:
body:请求 JSON 内容
{ "type": "code", "user": "someone", "code": "123456" }- type:码类型,支持
code(绑定码)或phone(手机号码) - code:码内容,如
123456或1581xxx - user:CNB 账户用户名
- type:码类型,支持
返回:用户信息
{ "id": "1293243433212", "username": "someone" }
绑定用户
接口地址:
/platform-token/-/bind/user/{openid:string}接口方法:"POST"
系统授权:system-bind:rw
功能描述:绑定用户
参数:
openid:第三方平台用户唯一 ID
body:请求 JSON 内容
{ "type": "code", "code": "123456", "user": "someone", "metadata": { "name": "hello" } }- type:码类型,支持
code(绑定码)或phone(手机号码) - code:码内容,如
123456或1581xxx - user:CNB 账户用户名
- metadata:自定义元数据
- type:码类型,支持
返回:用户信息
{ "id": "1293243433212", "username": "someone" }
批量解除用户绑定
- 接口地址:
/platform-token/-/unbind/user/{username:string or userid:string} - 接口方法:"POST"
- 系统授权:system-bind:rw
- 功能描述:解除该用户在此平台上的所有绑定记录
解除用户绑定
- 接口地址:
/platform-token/-/unbind/user/{username:string or userid:string}/{openid:string} - 接口方法:"POST"
- 系统授权:system-bind:rw
- 功能描述:解除该用户在此平台上的某一条绑定记录
锁定用户
- 接口地址:
/platform-token/-/lock/user/{username:string} - 接口方法:"POST"
- 系统授权:system-lock:rw
- 功能描述:锁定指定 {username} 的用户
- 参数:
body:请求 JSON 内容
{ "lock_duration": "10" }- lock_duration:锁定天数
解锁用户
- 接口地址:
/platform-token/-/unlock/user/{username:string} - 接口方法:"POST"
- 系统授权:system-lock:rw
- 功能描述:解锁指定 {username} 的用户
创建新用户
- 接口地址:
/platform-token/-/user/create/{openid:string} - 接口方法:"POST"
- 系统授权:system-user:rw
- 功能描述:新建指定 {openid} 的 cnb 用户
- 参数:
body:请求 JSON 内容
{ "name": "someone", "nick": "someone", "email": "someone@cnb.com" }- name:用户名
- nick:用户昵称
- email:用户邮箱
更新用户信息
- 接口地址:
/platform-token/-/user/update/{openid:string} - 接口方法:"POST"
- 系统授权:system-user:rw
- 功能描述:更新指定 {openid} 的 cnb 用户的信息
- 参数:
body:请求 JSON 内容
{ "name": "someone", "nick": "someone", "email": "someone@cnb.com" }- name:用户名
- nick:用户昵称
- email:用户邮箱
基于邮箱查询用户信息
- 接口地址:
/platform-token/-/user - 接口方法:"POST"
- 系统授权:system-userinfo:r
- 功能描述:基于邮箱查询用户信息
- 参数:
body:请求 Email 邮箱列表
{ "emails": ["test1@tencent.com", "test2@tencent.com"] }
资源绑定接口
绑定资源
- 接口地址:
/platform-token/-/bind/resource - 接口方法:"POST"
- 系统授权:system-bind:rw
- 功能描述:将第三方平台的实例与 CNB 资源绑定
- 参数:
body:请求 JSON 内容
{ "openid": "third-party-instance-id", "slug": "organization/repo", "code": "123456", "metadata": { "key": "value" } }- openid:第三方平台实例唯一 ID
- slug:CNB 资源路径(如:组织/仓库)
- code:绑定码
- metadata:可选,绑定的扩展信息
获取资源绑定信息
接口地址:
/platform-token/-/bind/resource接口方法:"GET"
系统授权:system-bind:r
功能描述:获取资源的绑定信息
参数:
- slug:可选参数,过滤绑定的资源路径
- openid:可选参数,过滤绑定的实例 OpenID
返回:资源绑定信息
{ "data": [ { "slug": "organization/repo", "openid": "third-party-instance-id", "metadata": "{\"key\":\"value\"}", "created_at": "2026-03-10T10:00:00Z", "updated_at": "2026-03-10T10:00:00Z" } ], "repository": { "id": "123456", "name": "repo", "path": "organization/repo" } }
解绑资源
- 接口地址:
/platform-token/-/bind/resource - 接口方法:"DELETE"
- 系统授权:system-bind:rw
- 功能描述:解除第三方平台实例与 CNB 资源的绑定关系
- 参数:
- slug:可选参数,过滤绑定的资源路径
- openid:可选参数,过滤绑定的实例 OpenID
- 注意:如果只提供 openid,则解除该实例的所有绑定;如果同时提供 slug 和 openid,则只解除特定资源的绑定
部署令牌接口
平台令牌绑定资源后,可为绑定的实例创建和管理部署令牌。 部署令牌用于访问绑定的 CNB 资源(如代码仓库), 每个实例通过唯一的密钥标识(key)管理其部署令牌。
创建部署令牌
接口地址:
/platform-token/-/deploy-keys/{openid}/{key}接口方法:"POST"
系统授权:继承平台令牌的权限范围
功能描述:为已绑定的第三方平台实例创建部署令牌
路径参数:
- openid:第三方平台实例唯一 ID(必须已完成资源绑定)
- key:密钥标识,用于标识和管理该实例的部署令牌(同一 openid + key 组合唯一)
参数:
body:请求 JSON 内容
{ "slug": "organization/repo", "description": "用于 CI/CD 的部署令牌", "scope": "registry-package:r", "metadata": { "environment": "production" } }- slug:CNB 资源路径,必须是已绑定的资源
- description:可选,令牌描述信息
- scope:可选,令牌的权限范围
- metadata:可选,令牌的扩展信息
返回:创建成功的令牌
{ "token": "dk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }注意:令牌只在创建时返回一次,请妥善保存
删除部署令牌
- 接口地址:
/platform-token/-/deploy-keys/{openid}/{key} - 接口方法:"DELETE"
- 系统授权:继承平台令牌的权限范围
- 功能描述:删除指定的部署令牌
- 路径参数:
- openid:第三方平台实例唯一 ID
- key:密钥标识
- 返回:HTTP 204 No Content
根据实际需求选择合适的接口。
Header 信息
Authorization:string 类型,HTTP 标准身份认证头部字段,使用标准 JWT 计算签名,格式为Bearer ${token}。Go JWT 签名示例如下:
import ( "fmt" "time" "github.com/golang-jwt/jwt/v5" ) // Claims 认证请求所需的参数 type Claims struct { JWTPayload // 用户自定义 JWT payload 结构 jwt.RegisteredClaims } // Generate 签名编码 func Generate(payload JWTPayload, name, secretKey string) (string, error) { claims := Claims{ payload, jwt.RegisteredClaims{ Issuer: name, // 平台令牌 name IssuedAt: jwt.NewNumericDate(time.Now().UTC()), // 当前 UTC 时间 }, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) return token.SignedString([]byte(secretKey)) }Python JWT 签名示例如下:
from datetime import datetime, timezone import jwt class JWTPayload: """JWT payload 自定义结构""" pass def generate(payload: JWTPayload, name: str, secret_key: str) -> str: claims = { # 标准声明 "iss": name, # Issuer - 平台令牌 name "iat": datetime.now(timezone.utc), # IssuedAt - 当前 UTC 时间 # 可以在这里添加自定义 payload 字段 # 如果 payload 有属性,可以通过 vars(payload) 或 payload.__dict__ 获取 } token = jwt.encode(claims, secret_key, algorithm="HS256") return tokenNode.js JWT 签名示例如下:
// 依赖:npm install jsonwebtoken const jwt = require('jsonwebtoken') /** * 生成 JWT 签名 * @param {object} payload 自定义 JWT payload 字段 * @param {string} name 平台令牌 name * @param {string} secretKey 平台令牌 secret_key * @returns {string} 签名后的 JWT */ function generate(payload, name, secretKey) { const claims = { ...payload, iss: name, // Issuer - 平台令牌 name iat: Math.floor(Date.now() / 1000), // IssuedAt - 当前 UNIX 时间戳(秒) } return jwt.sign(claims, secretKey, { algorithm: 'HS256' }) }JWT 详细介绍请参考官方文档。
将 JWT Claims 的 issueAt 字段赋值为当前 UNIX 时间戳。 如果该时间与服务器时间相差超过 2 分钟,调用接口会返回签名过期错误。
接口返回
换票接口请求成功后,返回 24 小时有效的临时票据,可用于调用 OpenAPI 接口。
OpenAPI 接口详情请参照 云原生构建 OpenAPI 接口文档(在新窗口打开)。
请求示例
curl 请求示例:
curl -X POST 3rd.cnbprod.alpha.qq.com/platform-token/-/user/someone \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoiIiwic2NvcGUiO"返回结果示例:
{ "token": "bHaDbC6esm88116aZOGDbpH26fL" }