初始化
This commit is contained in:
+272
@@ -0,0 +1,272 @@
|
||||
# 第三方服务、接口及密钥说明
|
||||
|
||||
本文档记录第三方服务实际使用的网址、接口和密钥字段。
|
||||
完整明文密钥不得提交到版本库;下文的密钥值使用登记占位符,真实值分别保存在生产环境文件或管理后台加密存储中。
|
||||
|
||||
## 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 邮箱 | `<邮箱>` | `<填写>` | `<填写>` | `<填写>` |
|
||||
|
||||
轮换登记只用于识别凭证,不填写完整密钥。
|
||||
Reference in New Issue
Block a user