---
url: /zh/paas/platform-token.md
---
## 概述

平台令牌提供给外部第三方服务使用，支持第三方服务通过调用换票接口来获得 `云原生构建` OpenAPI 的临时访问票据。

## 平台令牌申请

前往 admin 管理平台，为第三方服务创建平台令牌，得到 **name** 和 **secret\_key**。

## 服务地址

服务请求地址为 `3rd.cnb.share.ralphlauren.cn`。

## 接口

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

### 基于仓库全路径的换票

* 接口地址: `/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 列表

    ```json
    {
      "id": ["123"]
    }
    ```

### 查找绑定码或认证手机号码对应的对象信息

* 接口地址: `/platform-token/-/bind/user`
* 接口方法: "POST"
* 系统授权: system-bind:r
* 功能描述: 查找绑定码或认证手机号码对应的对象信息
* 参数:
  * body: 请求 json 内容

    ```json
    {
      "type": "code",
      "user": "someone",
      "code": "123456"
    }
    ```

    * type: 码类型，支持 `code` 绑定码, `phone` 手机号码
    * code: 码内容，如 123456, 或者 1581xxx
    * user: CNB 账户用户名
* 返回: 用户信息

  ```json
  {
    "id": "1293243433212",
    "username": "someone"
  }
  ```

### 绑定用户

* 接口地址: `/platform-token/-/bind/user/{openid:string}`
* 接口方法: "POST"
* 系统授权: system-bind:rw
* 功能描述: 绑定用户
* 参数:
  * openid: 第三方平台用户唯一ID
  * body: 请求 json 内容

    ```json
    {
      "type": "code",
      "code": "123456",
      "user": "someone",
      "metadata": {
        "name": "hello"
      }
    }
    ```

    * type: 码类型，支持 `code` 绑定码, `phone` 手机号码
    * code: 码内容，如 123456, 或者 1581xxx
    * user: CNB 账户用户名
    * metadata: 自定义元数据
* 返回: 用户信息

  ```json
  {
    "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 内容

    ```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 内容

    ```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 内容

    ```json
    {
      "name": "someone",
      "nick": "someone",
      "email": "someone@cnb.com"
    }
    ```

    * name: 用户名
    * nick: 用户昵称
    * email: 用户邮箱

### 基于邮箱查询用户信息

* 接口地址: `/platform-token/-/user`
* 接口方法: "POST"
* 系统授权: system-userinfo:r
* 功能描述: 基于邮箱查询用户信息
* 参数:
  * body: 请求 email 邮箱列表

    ```json
    {
      "emails": ["test1@tencent.com", "test2@tencent.com"]
    }
    ```

## 资源绑定接口

### 绑定资源

* 接口地址: `/platform-token/-/bind/resource`
* 接口方法: "POST"
* 系统授权: system-bind:rw
* 功能描述: 将第三方平台的实例与 CNB 资源进行绑定
* 参数:
  * body: 请求 json 内容

    ```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
* 返回: 资源绑定信息

  ```json
  {
    "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 内容

    ```json
    {
      "slug": "organization/repo",
      "description": "用于 CI/CD 的部署令牌",
      "scope": "registry-package:r",
      "metadata": {
        "environment": "production"
      }
    }
    ```

    * slug: CNB 资源路径，必须是已绑定的资源
    * description: 可选，令牌描述信息
    * scope: 可选，令牌的权限范围
    * metadata: 可选，令牌的扩展信息
* 返回: 创建成功的令牌

  ```json
  {
    "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 加密示例如下

  ```go
  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 加密示例如下

  ```python
  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 token
  ```

  jwt 更详细的介绍请参考官方文档。

  需要注意的是, 请将 **jwt Claims** 的 **issueAt** 字段赋值为当前 UNIX 时间戳，记录发起 API 请求的时间。
  **注意: 如果该时间与服务器时间相差超过2分钟，调用接口会返回签名过期错误。**

## 接口返回

换票接口请求成功后，会返回**24小时**有效的临时票据，可以使用该票据调用 OpenAPI 接口。

OpenAPI 接口详情请参照 [云原生构建 OpenAPI 接口文档](https://api.cnb.share.ralphlauren.cn)。

## 请求示例

curl 请求示例

```bash
curl -X POST 3rd.cnb.share.ralphlauren.cn/platform-token/-/user/someone \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0eXBlIjoiIiwic2NvcGUiO"
```

返回结果示例

```json
{ "token": "bHaDbC6esm88116aZOGDbpH26fL" }
```
