管理金鑰與機密

本頁內容

使用此清單來判斷哪些值屬於執行階段環境、哪些由系統產生到資料庫中,以及哪些由外掛儲存。每個小節都說明了輪替會如何影響正在執行的網站。

在 Node.js 上,請將執行階段機密放入代管平台的機密管理器,使其在程序啟動時進入 process.env。對於 Worker,請使用 wrangler secret put。不要將機密值放入 astro.config.mjs、wrangler.jsonc 或 import.meta.env;Vite 可能會將建置時的值嵌入伺服器套件中。

概覽

機密來源儲存位置金鑰遺失的影響
EMDASH_ENCRYPTION_KEY維運人員(emdash secrets generate)僅限環境變數 / Worker 機密在還原相符的金鑰之前,無法讀取已加密的外掛設定
預覽機密自動產生(可用環境變數覆寫)options 資料表(emdash:preview_secret)已發出的預覽連結失效;新連結不受影響
IP 鹽自動產生(可用環境變數覆寫)options 資料表(emdash:ip_salt)過去的留言速率限制連續性被重設
工作階段與 API 權杖每個工作階段/權杖各自產生工作階段儲存區 / 資料庫(僅雜湊)無影響——明文從不儲存
OAuth 提供者憑證你(Google、GitHub 或 Microsoft Entra 主控台)環境變數透過該提供者登入會停止,直到替換
Turnstile 機密你(Cloudflare 儀表板)環境變數留言 CAPTCHA 驗證失敗
S3 憑證你(儲存提供者)執行階段環境媒體上傳/下載失敗,直到替換
外掛機密你(管理介面設定畫面)加密的資料庫設定還原相符的加密金鑰,或重新輸入該值
CLI 憑證emdash login 裝置流程~/.config/emdash/auth.json(權限 0600)再次執行裝置流程
註冊表 CLI 憑證emdash-plugin atproto OAuth~/.emdash/oauth/、~/.emdash/credentials.json(權限 0600)重新登入;身分保存在你的 PDS 上

加密金鑰

EMDASH_ENCRYPTION_KEY 用於加密以 type: "secret" 宣告的外掛設定。EmDash 使用 AES-GCM,並以外掛 ID 和設定鍵作為驗證資料。格式錯誤的值會產生面向維運人員的啟動訊息,需要加密外掛設定的操作會以關閉方式失敗。與之無關的網站請求仍可正常運作。

以下指令會產生格式正確的值。若你的部署使用此變數,請將其存放在執行階段環境中,或作為 Worker 機密存放。

npx emdash secrets generate
# emdash_enc_v1_<43 base64url chars>

# Cloudflare:
wrangler secret put EMDASH_ENCRYPTION_KEY

格式為 emdash_enc_v1_ 後接 32 個隨機位元組,以無填充的 base64url 表示。該值由維運人員提供,不會儲存在資料庫中。請將其保存在機密管理器中,並另存一份用於還原的備份。

若要輪替金鑰,請在前面加入新值,並在逗號後保留舊值:

EMDASH_ENCRYPTION_KEY=emdash_enc_v1_<new-key>,emdash_enc_v1_<old-key>

EmDash 使用第一把金鑰加密新值和重新儲存的值,並根據已儲存的 kid 指紋選擇較舊的金鑰來讀取。在移除舊金鑰之前,請重新儲存每個外掛機密,然後在僅包含新金鑰的部署中驗證這些整合。EmDash 目前不會回報哪些金鑰 ID 仍在使用,因此請為你重新儲存的憑證維護一份清單,並在每個整合都通過驗證之前不要移除舊金鑰。

產生的網站機密

有兩個機密會在首次使用時自動產生,並持久化在 options 資料表中,因此在請求、部署和隔離環境之間保持穩定。產生是原子性的——並行的冷啟動會收斂到同一個值。

預覽機密

用於對預覽 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 上為檔案系統)。未設定儲存區的配接器(如 Vercel)需要在 astro.config.mjs 中設定工作階段驅動程式;若沒有,登入會失敗,並給出說明需要工作階段驅動程式的錯誤。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(或無前綴別名)
Microsoft 登入EMDASH_OAUTH_MICROSOFT_CLIENT_ID、EMDASH_OAUTH_MICROSOFT_CLIENT_SECRET、EMDASH_OAUTH_MICROSOFT_TENANT_ID(或無前綴別名)
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 不需要存取金鑰變數,因為繫結會授予執行階段存取權。請參閱媒體儲存。

在 Node 上,EmDash 會在請求抵達時從伺服器的程序環境讀取 Turnstile 金鑰,而 astro dev 和建置後的伺服器都不會將 .env 載入其中。請在主機環境中設定該金鑰,在執行 astro dev 的 shell 中匯出它,或使用 node --env-file=.env ./dist/server/entry.mjs 啟動建置後的伺服器。

外掛機密

外掛以 type: "secret" 宣告的設定(電子郵件提供者的 API 金鑰、表單驗證碼等)在管理介面中輸入,並加密儲存在 options 資料表的 plugin:<id>:settings:<key> 下。即使相符的加密金鑰無法使用,管理介面也只會收到該機密是否已設定,因此管理員可以替換無法讀取的憑證。外掛程式碼在其隔離的執行階段內透過 ctx.settings 讀取明文。儲存在已宣告的設定 schema 之外的值,包括任意外掛 KV 和狀態項目,不使用此加密路徑。

  • 憑證輪替: 在提供者處輪替憑證,並將新值貼到外掛的設定頁面。儲存時會寫入新的加密信封。
  • 明文遷移: 由早期 EmDash 版本儲存的機密仍可讀取。請重新儲存每個值以對其加密。
  • 如果加密金鑰遺失: 從單獨的金鑰備份中還原相符的 EMDASH_ENCRYPTION_KEY。如果沒有任何副本,請在提供者處替換每個受影響的憑證,並在設定新的加密金鑰後輸入替換值。

CLI 憑證

emdash CLI 將網站權杖儲存在 ~/.config/emdash/auth.json(遵循 XDG_CONFIG_HOME)中,並設為僅擁有者可存取的權限(0600)。emdash login 透過 OAuth 裝置流程向你的 EmDash 執行個體驗證,並以執行個體 URL 為鍵儲存權杖。emdash logout 會將其刪除;每次呼叫時,--token 或 EMDASH_TOKEN 會覆寫已儲存的權杖。

遺失該檔案無妨:再次執行 emdash login 即可。

外掛註冊表 CLI 憑證

獨立的 emdash-plugin CLI(套件 @emdash-cms/plugin-cli)面向實驗性的 AT Protocol 註冊表。在那裡發布與你的 AT Protocol 身分(你的發布者 DID)綁定——網站本身不持有任何發布憑證,安裝時會根據歸屬於該 DID 的發布記錄中的檢查碼來驗證成品。

  • 它透過 atproto OAuth 驗證。OAuth 工作階段/狀態資料位於 ~/.emdash/oauth/,發布者身分(DID、handle、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 auth。

輪替速查

我想要……這樣做
輪替外掛設定的加密在前面加入新金鑰,重新儲存外掛機密,然後移除舊金鑰
使所有預覽連結失效刪除 emdash:preview_secret 列(或變更環境變數覆寫),重新部署
重設留言速率限制的雜湊變更 EMDASH_IP_SALT(或刪除 emdash:ip_salt 選項列),重新部署
撤銷已外洩的 API 權杖Admin → Users → API tokens → 撤銷,然後建立替代權杖
終止所有工作階段清空工作階段儲存區(Workers KV 命名空間 / 工作階段目錄)
替換提供者憑證在提供者處輪替,更新環境變數,重新部署
替換外掛 API 金鑰在提供者處輪替,在外掛的管理介面設定中重新輸入