Files
JuYou/文档/第三方说明及密钥.md
2026-08-25 17:59:42 +08:00

273 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第三方服务、接口及密钥说明
本文档记录第三方服务实际使用的网址、接口和密钥字段。
完整明文密钥不得提交到版本库;下文的密钥值使用登记占位符,真实值分别保存在生产环境文件或管理后台加密存储中。
## 1. 第三方服务总览
| 第三方服务 | 用途 | 网址或接口入口 | 所需凭证 | 凭证保存位置 |
| --- | --- | --- | --- | --- |
| AP 渠道 | 文本、图片、视频任务及余额查询 | `https://api.apimart.ai/v1` | 渠道 API Key | PostgreSQL `channels.api_key_ciphertext` |
| 腾讯云 COS | 上传、读取和删除图片、音频、视频等媒体文件 | `https://cos.ap-chengdu.myqcloud.com` | SecretId、SecretKey | `/etc/juyou_ai/juyou_ai.env` |
| 腾讯云 COS 公开域名 | 向前端及第三方渠道提供可访问的媒体 URL | `https://cos.youjuhui.xyz` | 无单独运行时密钥 | `/etc/juyou_ai/juyou_ai.env` |
| Let's Encrypt | 申请和续期 HTTPS 证书 | `https://acme-v02.api.letsencrypt.org/directory` | 证书联系邮箱,不使用 API Key | `/opt/juyou_ai/deploy/.deploy.conf` |
| jsDelivr | 按需更新部署目录中的 `acme.sh` | `https://cdn.jsdelivr.net/gh/acmesh-official/acme.sh@master/acme.sh` | 无 | 不保存凭证 |
| Hugging Face 下载源 | 首次在本地准备离线语音识别文件 | 由 `faster-whisper` 下载工具访问 | 当前未配置访问令牌 | 不保存凭证 |
## 2. AI 渠道
### 2.1 当前渠道登记
| 渠道名称 | 渠道 URL | API Key |
| --- | --- | --- |
| AP | `https://api.apimart.ai/v1` | `<在管理后台维护>` |
渠道只需要登记基础网址和 API Key,具体模型不在本文档记录。
管理后台配置位置:
```text
ADMIN → 渠道管理 → 新增或编辑渠道 → 渠道 URL、API Key
```
### 2.2 认证方式
所有渠道请求使用 Bearer Token
```http
Authorization: Bearer <渠道 API Key>
```
提交异步任务时还会根据任务请求编号发送:
```http
Idempotency-Key: <请求编号>
X-Request-ID: <请求编号>
Content-Type: application/json
```
`Idempotency-Key``X-Request-ID` 是任务标识,不是密钥。
### 2.3 项目调用的接口路径
项目会在渠道 URL 后拼接下列路径:
| 请求 | 完整接口 | 用途 |
| --- | --- | --- |
| `POST` | `https://api.apimart.ai/v1/chat/completions` | 提交文本类请求,项目强制使用非流式响应 |
| `POST` | `https://api.apimart.ai/v1/images/generations` | 提交图片生成任务 |
| `POST` | `https://api.apimart.ai/v1/videos/generations` | 提交视频生成任务 |
| `GET` | `https://api.apimart.ai/v1/tasks/{task_id}` | 查询异步任务状态和结果地址 |
| `GET` | `https://api.apimart.ai/v1/user/balance` | 同步渠道余额 |
渠道至少需要兼容以上接口、Bearer 认证以及 JSON 请求和响应。图片或视频接口可以直接返回结果网址,也可以返回任务 ID 后由项目轮询。
### 2.4 渠道密钥如何保存
1. 管理员在管理后台输入渠道 API Key。
2. API 使用 `CONFIG_ENCRYPTION_KEY` 对明文密钥进行 AES-256-GCM 加密。
3. 密文写入 PostgreSQL 的 `channels.api_key_ciphertext`
4. 密钥末四位写入 `channels.api_key_last4`,用于无法解密时识别密钥。
5. 管理端查询渠道时不会返回完整明文,只显示前后部分字符的掩码。
6. Worker 执行任务或同步余额时,才在服务器内存中解密并放入 Authorization 请求头。
因此,数据库备份中的渠道密钥是密文,但同时取得数据库备份和 `CONFIG_ENCRYPTION_KEY` 的人员仍可恢复明文,两者必须分开保管。
### 2.5 新增或更换渠道密钥
新增渠道:
1. 在渠道服务商处创建 API Key。
2. 在管理后台新增渠道。
3. 填写渠道名称、基础网址和 API Key。
4. 保存后确认后台显示的掩码尾号与新密钥一致。
5. 通过渠道余额同步或一项低成本任务验证权限。
更换密钥:
1. 先在渠道服务商处创建新密钥,不要立即删除旧密钥。
2. 在管理后台编辑渠道,选择“更换 API Key”并保存。
3. 确认余额同步和任务提交正常。
4. 再到渠道服务商处撤销旧密钥。
5. 更新本文档中的密钥尾号和轮换记录,不记录明文。
## 3. 腾讯云 COS
### 3.1 当前存储配置
| 配置项 | 当前值或登记值 | 是否敏感 |
| --- | --- | --- |
| 腾讯云控制台 | `https://console.cloud.tencent.com/cos` | 否 |
| `COS_SECRET_ID` | `<腾讯云子账号 SecretId>` | 是 |
| `COS_SECRET_KEY` | `<腾讯云子账号 SecretKey>` | 是,禁止泄露 |
| `COS_BUCKET` | `juyouai-1451538162` | 否 |
| `COS_REGION` | `ap-chengdu` | 否 |
| `COS_ENDPOINT` | `https://cos.ap-chengdu.myqcloud.com` | 否 |
| `COS_PUBLIC_BASE_URL` | `https://cos.youjuhui.xyz` | 否 |
生产环境中的真实凭证保存在:
```text
/etc/juyou_ai/juyou_ai.env
```
本地开发凭证保存在:
```text
API/.env
```
### 3.2 使用的 COS 接口
项目通过 AWS S3 兼容协议访问 COS,区域使用 `ap-chengdu`,并使用虚拟主机寻址。实际执行的操作包括:
| S3 操作 | 用途 |
| --- | --- |
| `PutObject` | 上传用户文件、抽帧、识别结果、任务原始响应和生成结果 |
| `GetObject` | 后端读取已存储对象 |
| `DeleteObject` | 删除业务数据时清理对应对象 |
腾讯云子账号至少需要目标存储桶的对象读取、写入和删除权限。若缺少删除权限,业务记录可以删除,但 COS 对象清理会失败并产生遗留文件。
### 3.3 公开访问域名
`COS_PUBLIC_BASE_URL` 必须是外部可以访问的 HTTPS 地址。项目会按以下形式生成媒体地址:
```text
https://cos.youjuhui.xyz/juyou_ran/<业务对象键>
```
该网址会提供给:
- WEB 和 ADMIN 页面展示媒体;
- 第三方渠道读取参考图片、音频或视频;
- 服务端重新下载上游生成结果。
公开域名不使用 SecretKey,但必须正确绑定 `juyouai-1451538162` 存储桶。第三方渠道无法访问该域名时,带参考媒体的任务会失败。
### 3.4 COS CORS
COS 存储桶需要允许实际 WEB 域名执行 `GET``HEAD`。建议规则:
```json
[
{
"AllowedOrigins": [
"https://实际WEB域名"
],
"AllowedMethods": [
"GET",
"HEAD"
],
"AllowedHeaders": [
"*"
],
"ExposeHeaders": [
"Accept-Ranges",
"Content-Length",
"Content-Range",
"Content-Type",
"ETag"
],
"MaxAgeSeconds": 3600
}
]
```
缺少 CORS 时,媒体可能仍能直接打开或播放,但浏览器中的抽帧、Blob 下载等功能会被拦截。
### 3.5 更换 COS 密钥
1. 在腾讯云 CAM 中为程序子账号创建新的 API 密钥。
2. 备份 `/etc/juyou_ai/juyou_ai.env`
3. 更新 `COS_SECRET_ID``COS_SECRET_KEY`
4. 重启 `juyou_ai` 服务。
5. 验证上传、读取和删除操作。
6. 确认新密钥正常后撤销旧 API 密钥。
```bash
sudo systemctl restart juyou_ai
sudo journalctl -u juyou_ai -n 100 --no-pager
```
## 4. Let's Encrypt 与 acme.sh
### 4.1 服务信息
| 项目 | 值 |
| --- | --- |
| 正式 ACME 接口 | `https://acme-v02.api.letsencrypt.org/directory` |
| 认证方式 | ACME HTTP-01 |
| API Key | 不需要 |
| 必需登记信息 | 证书联系邮箱、域名 |
| 验证目录 | `/var/www/jcf-acme` |
| 证书目录 | `/etc/nginx/ssl` |
域名和邮箱保存在:
```text
/opt/juyou_ai/deploy/.deploy.conf
```
部署脚本先让 Nginx 提供 `/.well-known/acme-challenge/`,再调用项目内的 `API/acme/acme.sh` 申请证书。证书申请要求域名已解析到服务器,并且公网可以访问 TCP 80。
已有匹配域名的证书和私钥时,部署脚本直接复用,不会重复申请。
## 5. 部署阶段使用的无密钥第三方来源
### 5.1 jsDelivr
只有手动执行以下脚本时才访问 jsDelivr:
```bash
sudo bash /opt/juyou_ai/deploy/update_acme.sh
```
下载地址:
```text
https://cdn.jsdelivr.net/gh/acmesh-official/acme.sh@master/acme.sh
```
该请求不使用 API Key。脚本下载后会检查内容中是否存在 `VER=` 版本标识,再替换项目中的 `acme.sh`
### 5.2 Hugging Face 下载源
当服务器缺少离线语音识别文件时,`push.bat` 会在 Windows 本机调用 Python 下载工具准备文件,然后上传服务器。当前代码未读取或配置 Hugging Face Access Token,服务器部署和运行阶段不会访问该下载源。
如果以后使用需要授权的资源,应通过受保护的本机环境变量或 Hugging Face 凭证存储配置,不得把令牌写入部署脚本或本文档。
## 6. 不是第三方接口密钥的项目安全配置
下列配置同样敏感,但不属于第三方 API 凭证:
| 配置项 | 用途 | 保存位置 |
| --- | --- | --- |
| `CONFIG_ENCRYPTION_KEY` | 加密和解密渠道 API Key | 生产环境文件 |
| `JWT_SECRET_KEY` | 签发和校验用户、管理员登录令牌 | 生产环境文件 |
| `DATABASE_PASSWORD` | PostgreSQL 应用账号密码 | 生产环境文件 |
| `REDIS_PASSWORD` | Redis 密码,当前为空时不启用认证 | 生产环境文件 |
| `ADMIN_BOOTSTRAP_PASSWORD` | 数据库没有管理员时创建初始管理员 | 生产环境文件 |
其中 `CONFIG_ENCRYPTION_KEY` 必须是 32 字节随机值的标准 Base64 编码。丢失该密钥后,数据库中已有的渠道密钥无法解密,只能逐个重新录入;更换它时也不能只修改环境变量,必须先完成渠道密文重加密方案。
## 7. 密钥存放与权限要求
- 生产第三方密钥只保存在 `/etc/juyou_ai/juyou_ai.env` 或数据库加密字段中。
- `/etc/juyou_ai/juyou_ai.env` 权限应为 `root:root``600`
- `API/.env` 不得提交到 Git,也不得通过普通聊天、邮件或工单正文传递。
- Markdown 文档只记录密钥负责人、用途、尾号和轮换时间,不记录完整明文。
- 渠道密钥、COS 密钥和 `CONFIG_ENCRYPTION_KEY` 不应由同一个公开位置统一保存。
- 日志中不得打印 Authorization 请求头、COS SecretKey 或解密后的渠道密钥。
- 人员离职、权限范围变化或怀疑泄露时,应立即轮换对应密钥。
## 8. 密钥轮换登记
| 服务 | 密钥标识或尾号 | 最近轮换时间 | 负责人 | 下次计划时间 |
| --- | --- | --- | --- | --- |
| AP 渠道 | `7MNC` | `<填写>` | `<填写>` | `<填写>` |
| 腾讯云 COS | `<SecretId 尾号>` | `<填写>` | `<填写>` | `<填写>` |
| Let's Encrypt 邮箱 | `<邮箱>` | `<填写>` | `<填写>` | `<填写>` |
轮换登记只用于识别凭证,不填写完整密钥。