管理密钥和秘钥

本页内容

使用此清单来决定哪些值属于运行时环境、哪些在数据库中生成、哪些由插件存储。每个部分说明了轮换如何影响运行中的站点。

在 Node.js 上,将运行时秘钥放在托管平台的秘钥管理器中,使其在进程启动时进入 process.env。对于 Worker,使用 wrangler secret put。不要在 astro.config.mjswrangler.jsoncimport.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_IDEMDASH_OAUTH_GOOGLE_CLIENT_SECRET(或无前缀别名)
GitHub 登录EMDASH_OAUTH_GITHUB_CLIENT_IDEMDASH_OAUTH_GITHUB_CLIENT_SECRET(或无前缀别名)
Marketplace 发布(CI)EMDASH_MARKETPLACE_TOKEN
Turnstile(评论)EMDASH_TURNSTILE_SECRET_KEY(或 TURNSTILE_SECRET_KEY
S3 兼容存储S3_ACCESS_KEY_IDS3_SECRET_ACCESS_KEYS3_ENDPOINTS3_BUCKETS3_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 将其移除;每次调用时,--tokenEMDASH_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_DIDEMDASH_PUBLISHER_HANDLEEMDASH_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 密钥在提供商处轮换,在插件的管理设置中重新输入