# AfterPack API 密钥

创建、限定范围、使用和撤销将本地构建变为 Pro Cloud 构建的密钥。

Source: https://www.afterpack.dev/zh/docs/dashboard/api-keys

API 密钥会把本地构建变成 **Pro Cloud** 构建。没有密钥时，[`npx afterpack@latest`](https://www.afterpack.dev/zh/docs/cli#usage) 和每个[插件](https://www.afterpack.dev/zh/docs/frameworks)都在本地以 [Free](https://www.afterpack.dev/zh/docs/tiers) 保护运行，不上报任何内容。有了密钥，构建的文件会发送到 AfterPack 的云端引擎，按你的工作区计量并记录在控制台中。

## 密钥存放在哪里

密钥存放在**项目**下的 *Keys* 页面：一个密钥绑定到一个项目，它产生的构建也归属该项目，把[构建](https://www.afterpack.dev/zh/docs/dashboard/builds)、[Protection Map](https://www.afterpack.dev/zh/docs/protection-map)和[用量](https://www.afterpack.dev/zh/docs/dashboard/usage)都分组在其下。除此之外，密钥是工作区级别的凭据：它消耗工作区的额度，并受[工作区角色](https://www.afterpack.dev/zh/docs/dashboard/workspaces)限制。

## 创建密钥

只有工作区所有者和管理员可以创建密钥，且只能从控制台创建。密钥不能创建另一个密钥。创建对话框会要求填写：

- **名称**（必填，最多 100 个字符）：说明用途，例如 *CI 流水线*。这是之后区分各行的唯一依据，所以要按用途命名。
- **到期时间**（可选，位于 *高级* 选项下）：一个日期，以当地时间当天结束为准。过去的日期会返回错误。
- **允许的 IP**（可选，位于 *高级* 选项下）：以逗号分隔的列表，例如 `10.0.0.0/8, 203.0.113.7`。

> **密钥只会显示一次**
>
> 原始密钥只会返回一次，且从不存储；系统只保留哈希值和一小段非敏感前缀。关闭对话框前请先复制它。如果丢失了，请撤销它并创建一个新的。它无法再次显示。

密钥的形式是 `ap_v1_` 后跟 40 个随机的 base62 字符，列表中只显示存储的前缀（`ap_v1_` 加六个字符）并附一个 `*`。密钥会把构建归属到它所在的项目，但不会限制构建可以面向哪个项目。[`scope.allowedProjects`](https://www.afterpack.dev/zh/docs/cloud-api) 会返回错误。

## 使用密钥

引擎解析 [`key`](https://www.afterpack.dev/zh/docs/config#key) 的顺序依次是：先看 `--key=`，再看环境变量，最后看 `afterpack.json`。在 [CI](https://www.afterpack.dev/zh/docs/builds) 中把 [`AFTERPACK_key`](https://www.afterpack.dev/zh/docs/config#key) 设为密钥，或者把它写进 `afterpack.json` 做本地试用：

```json
{ "key": "ap_v1_..." }
```

两处都没有密钥，构建就会在本地运行：这是默认情况，也是完整的 [Free 版](https://www.afterpack.dev/zh/docs/deployment-modes)路径。

> **密钥应该放在 CI 里，而不是代码仓库里**
>
> `afterpack.json` 适合本地试用，但提交它会把一个能消耗你工作区额度的凭据公开出去。共享场景下请使用 [`AFTERPACK_key`](https://www.afterpack.dev/zh/docs/config#key)。参见[构建与 CI](https://www.afterpack.dev/zh/docs/builds)。

## 密钥列表

| 列 | 含义 |
| --- | --- |
| **名称** | 你为它起的名字。 |
| **密钥** | 存储的显示前缀，`ap_v1_xxxxxx*`。 |
| **创建时间** | 密钥的创建时间。 |
| **过期时间** | 到期日期，或者*从未*。 |
| **最后使用** | 某次构建最后一次用它认证的时间，可用来找出已经没有构建在用的密钥。 |
| **状态** | *已启用*或*已撤销*。 |

## 轮换

没有原地轮换这回事。轮换始终是**先创建新密钥，再撤销旧密钥**，而且只要创建时没有设置到期时间，密钥就不会自行过期，所以这两步可以在整个上线过程中并存：

1. 创建新密钥。
2. 把它部署到旧密钥曾经使用的每一处（CI 密钥、部署配置）。
3. 通过**最后使用**列确认构建正在用它认证。
4. 撤销旧密钥。

## 撤销

撤销是立即生效且不可撤回的：密钥会在下一次请求时失效。该行会保留可见，标记为*已撤销*，而不是消失，方便你了解它曾经的用途。创建者可以撤销自己的密钥，其所在工作区的任何管理员或所有者也可以，所以即使创建者已经离开，密钥依然可以被撤销。撤销是一个控制台操作：API 密钥本身无法撤销任何密钥，包括它自己。构建过程中被撤销的密钥会导致 CLI 的下一次请求随之失败。

> **密钥泄露时，立即撤销它**
>
> 撤销会在几秒内全局生效，也是完整的解决办法：AfterPack 创建密钥后从不存储原始密钥，只保留一个不透明的 id、非敏感前缀和加盐哈希，所以事后不存在需要清理的缓存或日志。如果无法访问控制台，请发邮件到 **security@afterpack.dev**。

## 使用密钥的构建所受的限制

| | 限制 |
| --- | --- |
| 每个密钥每分钟的请求数 | Free 版 10 次，付费套餐 100 次 |
| 每个 IP 每分钟的请求数 | 100 次 |
| 单文件字节数 | 50 MB |
| 每批文件数 | 200 |
| 每批字节数 | 500 MB |

超出限制的构建会直接[失败](https://www.afterpack.dev/zh/docs/diagnostics#exit-codes)，而不会回退到未混淆的输出。协议细节和错误码参见 [Cloud API](https://www.afterpack.dev/zh/docs/cloud-api)。

## 构建没有出现时

几乎总是以下情况之一：

1. **没有解析到密钥**：构建在本地运行。检查运行构建的地方是否设置了 [`AFTERPACK_key`](https://www.afterpack.dev/zh/docs/config#key)。
2. **密钥已撤销或已过期**：列表会告诉你是哪一种。
3. **你打开的项目不对**：构建会归属到密钥所在的项目，这可能和你当前打开的项目不同。

## 下一步

- [构建](https://www.afterpack.dev/zh/docs/dashboard/builds)：使用密钥的构建会产出什么。
- [用量与账单](https://www.afterpack.dev/zh/docs/dashboard/usage)：它的花费。
- [Cloud API](https://www.afterpack.dev/zh/docs/cloud-api)：密钥用于认证的协议。
- [工作区与项目](https://www.afterpack.dev/zh/docs/dashboard/workspaces)：限定此页面权限的角色。
