使用此清单来决定哪些值属于运行时环境、哪些在数据库中生成、哪些由插件存储。每个部分说明了轮换如何影响运行中的站点。
在 Node.js 上,将运行时秘钥放在托管平台的秘钥管理器中,使其在进程启动时进入 process.env。对于 Worker,使用 wrangler secret put。不要在 astro.config.mjs、wrangler.jsonc 或 import.meta.env 中放置秘钥值;Vite 可能会将构建时的值嵌入服务器包。
概览
| 秘钥 | 来源 | 存储位置 | 丢失密钥的影响 |
|---|---|---|---|
EMDASH_ENCRYPTION_KEY | 运营者 (emdash secrets generate) | 仅环境 / Worker 秘钥 | 对当前数据无影响;EmDash 仅检查其格式 |
| 预览秘钥 | 自动生成(环境变量覆盖) | options 表 (emdash:preview_secret) | 已签发的预览链接失效;新的正常 |
| IP 盐值 | 自动生成(环境变量覆盖) | options 表 (emdash:ip_salt) | 评论速率限制连续性重置 |
| 会话和 API 令牌 | 按会话/令牌生成 | 会话存储 / 数据库(仅哈希) | 无影响 — 明文从不存储 |
| OAuth 提供商凭证 | 你(Google/GitHub 控制台) | 环境 | 该提供商的登录停止直到替换 |
| Turnstile 秘钥 | 你(Cloudflare 仪表板) | 环境 | 评论 CAPTCHA 验证失败 |
| S3 凭证 | 你(存储提供商) | 运行时环境 | 媒体上传/下载失败直到替换 |
| 插件秘钥 | 你(管理设置 UI) | 数据库(插件设置/存储) | 在管理面板重新输入 |
| CLI 凭证 | emdash login / emdash plugin publish 设备流 | ~/.config/emdash/auth.json(模式 0600) | 重新运行设备流 |
| 注册表 CLI 凭证 | emdash-plugin atproto OAuth | ~/.emdash/oauth/、~/.emdash/credentials.json(模式 0600) | 重新登录;身份在您的 PDS 上 |
加密密钥
EMDASH_ENCRYPTION_KEY 当前不会加密插件秘钥或任何其他存储数据。如果设置了该变量,EmDash 在启动时检查其格式。格式错误的值会产生面向运营者的日志消息,但站点继续处理请求。
以下命令生成格式正确的值。如果您的部署使用此变量,请将其存储在运行时环境中或作为 Worker 秘钥。
npx emdash secrets generate
# emdash_enc_v1_<43个 base64url 字符>
# Cloudflare:
wrangler secret put EMDASH_ENCRYPTION_KEY
格式为 emdash_enc_v1_ 后跟 32 个随机字节的无填充 base64url。该值由运营者提供,不存储在数据库中。丢失它对数据恢复没有影响,因为没有存储数据依赖于它。
生成的站点秘钥
两个秘钥在首次使用时自动生成并持久化到 options 表中,因此在请求、部署和 isolate 之间保持稳定。生成是原子的 — 并发的冷启动会收敛到一个值。
预览秘钥
签署预览 URL(HMAC)。存储为 emdash:preview_secret;32 个随机字节,base64url。
- 覆盖: 如果需要在多个进程间使用相同秘钥,或出于审计原因固定它,请设置
EMDASH_PREVIEW_SECRET(旧版别名:PREVIEW_SECRET)。环境变量始终优先于存储值。 - 轮换: 删除
emdash:preview_secret行(或更改环境变量)并重新部署。影响:先前签发的预览链接不再有效。其他不受影响 — 下次预览请求时会生成(或从环境读取)新秘钥。 - 如果丢失: 没有不可恢复的内容。预览链接设计上是短期的。
有关预览 URL 的构建和验证,请参见预览指南。
IP 盐值
为评论速率限制使用的评论者 IP 地址的 SHA-256 哈希(评论上的 ip_hash)添加盐值。存储为 emdash:ip_salt。站点特定,因此哈希在 EmDash 安装之间不可关联。
- 覆盖: 设置
EMDASH_IP_SALT。为了向后兼容,也会参考EMDASH_AUTH_SECRET/AUTH_SECRET— 历史上从这些派生盐值的安装保持稳定的哈希。 - 轮换: 更改环境变量或删除
emdash:ip_salt行。影响:新的评论提交会哈希为不同的值,因此所有人的速率限制计数重新开始。现有评论及其存储的哈希不受影响。 - 如果丢失: 无数据丢失。仅速率限制连续性重置。
会话和 API 令牌
- 会话使用 Astro 的会话存储(Cloudflare 上为 Workers KV,Node 上为文件系统)。Cookie 携带不透明的会话 ID;没有需要管理的签名秘钥。注销以结束会话,或清除会话存储(如 KV 命名空间)以强制所有人重新登录。
- API 令牌(
ec_pat_、ec_oat_、ec_ort_前缀)是不透明的 256 位随机值;仅存储其 SHA-256 哈希。明文在创建时显示一次。通过在管理面板撤销并重新创建进行轮换。 - 邀请、魔术链接和恢复令牌是一次性的,以 SHA-256 哈希存储在
auth_tokens中,并有时间限制(邀请 7 天,魔术链接 15 分钟)。
无需主动备份或轮换:数据库泄露仅暴露哈希,每个令牌都可以从管理面板撤销或重新签发。
用户提供的服务凭证
外部服务的凭证从环境读取,从不写入数据库。在提供商处轮换,更新变量,重新部署。
| 服务 | 变量 |
|---|---|
| Google 登录 | EMDASH_OAUTH_GOOGLE_CLIENT_ID、EMDASH_OAUTH_GOOGLE_CLIENT_SECRET(或无前缀别名) |
| GitHub 登录 | EMDASH_OAUTH_GITHUB_CLIENT_ID、EMDASH_OAUTH_GITHUB_CLIENT_SECRET(或无前缀别名) |
| Marketplace 发布(CI) | EMDASH_MARKETPLACE_TOKEN |
| Turnstile(评论) | EMDASH_TURNSTILE_SECRET_KEY(或 TURNSTILE_SECRET_KEY) |
| S3 兼容存储 | S3_ACCESS_KEY_ID、S3_SECRET_ACCESS_KEY、S3_ENDPOINT、S3_BUCKET、S3_REGION |
在 Cloudflare 上,使用 wrangler secret put 设置;本地开发时放在 .env 中。Wrangler 读取 .dev.vars 或 .env(不是两者),.dev.vars 存在时优先。通过绑定的 R2 不需要访问密钥变量,因为绑定在运行时授予访问权限。参见媒体存储。
插件秘钥
插件以 type: "secret" 声明的设置(电子邮件提供商的 API 密钥、表单 CAPTCHA 等)在管理 UI 中输入并存储在数据库中 — 在 options 表的 plugin:<id>:settings:<key> 下,或在插件的键值存储中。存储的秘钥是否返回给管理 UI 取决于插件;良好实现的插件仅返回”值已设置”标志而非秘钥本身(内置的表单插件这样做)。
- 轮换: 在提供商处轮换密钥,并将新值粘贴到插件的设置页面。立即生效。
- 如果丢失: 在管理面板重新输入值。没有其他内容依赖于它。
CLI 凭证
emdash CLI 持有两种凭证,都在 ~/.config/emdash/auth.json(遵守 XDG_CONFIG_HOME)中,以仅所有者权限(0600)创建:
- 站点令牌 —
emdash login通过 OAuth 设备流对您的 EmDash 实例进行认证,并以实例 URL 为键存储结果令牌。emdash logout将其移除;每次调用时,--token或EMDASH_TOKEN覆盖存储的令牌。 - Marketplace 令牌 —
emdash plugin publish通过 GitHub 设备流对 EmDash Marketplace 进行认证,并以marketplace:<origin>为键存储结果 JWT。CI 发布时,设置EMDASH_MARKETPLACE_TOKEN— 它优先于存储的凭证。
丢失文件是无害的:重新运行 emdash login(或重新运行设备流的 emdash plugin publish)。
插件注册表 CLI 凭证
独立的 emdash-plugin CLI(包 @emdash-cms/plugin-cli)面向实验性的 AT Protocol 注册表。在那里发布与您的 AT Protocol 身份(您的发布者 DID)绑定 — 站点本身不持有发布凭证,安装会根据归属于该 DID 的发布记录的校验和验证工件。
- 通过 atproto OAuth 认证。OAuth 会话/状态 blob 在
~/.emdash/oauth/中,发布者身份(DID、句柄、PDS)缓存在~/.emdash/credentials.json中;两者都以仅所有者权限写入。 - 在 CI 中,通过
EMDASH_PUBLISHER_DID、EMDASH_PUBLISHER_HANDLE和EMDASH_PUBLISHER_PDS提供身份;EMDASH_REGISTRY_URL覆盖注册表主机。CI 中的自动publish仍需要运行器上~/.emdash/oauth/中的 OAuth 会话文件 — 仅环境变量无法携带 OAuth 会话。 - 轮换或撤销发布访问权限在您的 AT Protocol 帐户(如应用密码)中进行,不在 EmDash 中。参见 Atmosphere 认证。
轮换快速参考
| 我想要… | 这样做 |
|---|---|
| 使所有预览链接失效 | 删除 emdash:preview_secret 选项行(或更改环境变量覆盖) |
| 重置评论速率限制哈希 | 更改 EMDASH_IP_SALT(或删除 emdash:ip_salt 选项行) |
| 撤销泄露的 API 令牌 | 管理 → 用户 → API 令牌 → 撤销,然后创建替代 |
| 终止所有会话 | 清除会话存储(Workers KV 命名空间 / 会话目录) |
| 替换提供商凭证 | 在提供商处轮换,更新环境变量,重新部署 |
| 替换插件 API 密钥 | 在提供商处轮换,在插件的管理设置中重新输入 |