シークレットと鍵管理

このページ

EmDashはプレビュー、コメント、認証、ストレージ、プラグインにわたって少数のシークレットを使用します。このページは完全なインベントリです:各シークレットの出所、保存場所、ローテーション方法、紛失時に何が壊れるか。

概要

シークレットソース保存先紛失時の影響
EMDASH_ENCRYPTION_KEYオペレーター (emdash secrets generate)環境変数 / Workerシークレットのみ暗号化されたプラグインシークレットが復旧不能に(保存時暗号化リリース後)
プレビューシークレット自動生成(envオーバーライド)optionsテーブル (emdash:preview_secret)発行済みのプレビューリンクが無効に;新しいものは問題なし
IPソルト自動生成(envオーバーライド)optionsテーブル (emdash:ip_salt)コメントのレート制限の連続性がリセット
セッション&APIトークンセッション/トークンごとに生成セッションストア / DB(ハッシュのみ)影響なし — プレーンテキストは保存されない
OAuthプロバイダー資格情報ユーザー(Google/GitHubコンソール)環境変数そのプロバイダーでのサインインが置換まで停止
Turnstileシークレットユーザー(Cloudflareダッシュボード)環境変数コメントCAPTCA検証が失敗
S3資格情報ユーザー(ストレージプロバイダー)環境変数または設定メディアのアップロード/ダウンロードが置換まで失敗
プラグインシークレットユーザー(管理設定UI)データベース(プラグイン設定/ストレージ)管理画面で再入力
CLI資格情報emdash login / emdash plugin publish デバイスフロー~/.config/emdash/auth.json(モード0600)デバイスフローを再実行
レジストリCLI資格情報emdash-plugin atproto OAuth~/.emdash/oauth/~/.emdash/credentials.json(モード0600)再ログイン;IDはPDSに存在

暗号化キー

EMDASH_ENCRYPTION_KEYはプラグインシークレットの保存時暗号化のためのサイトキーです。オペレーターが提供し、データベースには保存されません — データベースには暗号文のみが含まれるため、バックアップが漏洩してもキーは公開されません。

キーを生成し、環境変数(またはWorkerシークレット)として設定します:

npx emdash secrets generate
# emdash_enc_v1_<43文字のbase64url>

# Cloudflare:
wrangler secret put EMDASH_ENCRYPTION_KEY

形式はemdash_enc_v1_の後に32バイトのランダムデータをパディングなしのbase64urlでエンコードしたものです。キーはランタイム起動時に検証されます。不正な値はオペレーター向けのエラーをログに記録しますが、リクエストパスは停止しません。

ローテーション

変数はカンマ区切りのキーリストを受け付けます。最初のエントリがプライマリで、新しい書き込みに使用されます。すべてのエントリが復号化のために試行されます。暗号化された各値には8文字のキーフィンガープリント(kidemdash secrets fingerprint <key>で表示可能)がタグ付けされているため、ランタイムは正しいキーを自動的に選択します。

ローテーション方法:新しいキーを生成し、リストの先頭に追加(EMDASH_ENCRYPTION_KEY="新キー,旧キー")、再デプロイし、既存の値が再暗号化されたら古いキーを削除。

生成されたサイトシークレット

2つのシークレットが初回使用時に自動生成され、optionsテーブルに永続化されます。これによりリクエスト、デプロイメント、アイソレート間で安定します。生成はアトミックです — 並行するコールドスタートは1つの値に収束します。

プレビューシークレット

プレビューURL(HMAC)に署名します。emdash:preview_secretとして保存;32バイトのランダムデータ、base64url。

  • オーバーライド: 複数のプロセスで同じシークレットが必要な場合や監査目的で固定したい場合はEMDASH_PREVIEW_SECRET(レガシーエイリアス:PREVIEW_SECRET)を設定します。環境変数は常に保存値に優先します。
  • ローテーション: emdash:preview_secret行を削除(またはenv変数を変更)して再デプロイ。影響:以前発行されたプレビューリンクの検証が停止。他には何も壊れません — 次のプレビューリクエスト時に新しいシークレットが生成されます(またはenvから読み込まれます)。
  • 紛失時: 復旧不能なものはありません。プレビューリンクは設計上短命です。

プレビューURLの構築と検証についてはプレビューガイドを参照してください。

IPソルト

コメントのレート制限に使用されるコメンター IPアドレスのSHA-256ハッシュ(コメントのip_hash)をソルトします。emdash:ip_saltとして保存。サイト固有のため、ハッシュはEmDashインストール間で相関できません。

  • オーバーライド: EMDASH_IP_SALTを設定。後方互換性のため、EMDASH_AUTH_SECRET / AUTH_SECRETも参照されます — 歴史的にこれらからソルトを導出したインストールは安定したハッシュを維持します。
  • ローテーション: env変数を変更するかemdash:ip_salt行を削除。影響:新しいコメント送信は異なるハッシュ値を生成するため、全員のレート制限カウントが再開されます。既存のコメントとその保存済みハッシュは影響を受けません。
  • 紛失時: データ損失なし。レート制限の連続性のみがリセットされます。

セッションとAPIトークン

  • セッションはAstroのセッションストア(CloudflareではWorkers KV、NodeではファイルシステGI)を使用します。CookieはオペークなセッションIDを持ち、管理すべき署名シークレットはありません。ログアウトでセッションを終了するか、セッションストア(例:KVネームスペース)をクリアして全員に再ログインを強制します。
  • APIトークンec_pat_ec_oat_ec_ort_プレフィックス)はオペークな256ビットのランダム値です。SHA-256ハッシュのみが保存されます。プレーンテキストは作成時に1回だけ表示されます。管理画面で取り消して再作成することでローテーションします。
  • 招待、マジックリンク、リカバリートークンは単一目的で、auth_tokensにSHA-256ハッシュとして保存され、時間制限付き(招待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に配置。バインディング経由のR2は資格情報不要 — アクセスはwrangler.jsoncのバインディングで許可されます。これがWorkersでの推奨セットアップです。ストレージオプションを参照してください。

プラグインシークレット

プラグインがtype: "secret"で宣言する設定(メールプロバイダーのAPIキー、フォームCAPTCHAなど)は管理UIで入力され、データベースに保存されます — optionsテーブルのplugin:<id>:settings:<key>下、またはプラグインのキーバリューストレージ。保存されたシークレットが管理UIに返されるかはプラグイン次第です。適切に作られたプラグインはシークレット自体ではなく「値が設定済み」フラグのみを返します(バンドルされたフォームプラグインはこれを行います)。

  • ローテーション: プロバイダーでキーをローテーションし、新しい値をプラグインの設定ページに貼り付けます。即座に反映されます。
  • 紛失時: 管理画面で値を再入力します。他に依存するものはありません。

CLI資格情報

emdash CLIは2種類の資格情報を保持し、どちらも~/.config/emdash/auth.jsonXDG_CONFIG_HOMEを尊重)にオーナーのみの権限(0600)で作成されます:

  • サイトトークンemdash loginはOAuthデバイスフローを通じてEmDashインスタンスに対して認証し、結果のトークンをインスタンスURLをキーとして保存します。emdash logoutで削除されます。呼び出しごとに--tokenまたはEMDASH_TOKENが保存トークンを上書きします。
  • Marketplaceトークンemdash plugin publishはGitHubデバイスフローを通じてEmDash Marketplaceに認証し、結果のJWTをmarketplace:<origin>としてインデックス付きで保存します。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セッション/ステートブロブは~/.emdash/oauth/に、パブリッシャーアイデンティティ(DID、ハンドル、PDS)は~/.emdash/credentials.jsonにキャッシュされます。どちらもオーナーのみの権限で書き込まれます。
  • CIではEMDASH_PUBLISHER_DIDEMDASH_PUBLISHER_HANDLEEMDASH_PUBLISHER_PDSでアイデンティティを提供します。EMDASH_REGISTRY_URLはレジストリホストをオーバーライドします。CIからの自動publishにはランナー上の~/.emdash/oauth/にOAuthセッションファイルが必要です — env変数だけではOAuthセッションを持ち運べません。
  • 公開アクセスのローテーションや取り消しは、EmDashではなくAT Protocolアカウント(例:アプリパスワード)で行います。Atmosphere authを参照してください。

ローテーションクイックリファレンス

したいことやること
暗号化キーのローテーション新しいキーを先頭に追加:EMDASH_ENCRYPTION_KEY="新,旧"、再デプロイ、後で旧を削除
すべてのプレビューリンクを無効化emdash:preview_secretオプション行を削除(またはenvオーバーライドを変更)
コメントのレート制限ハッシュをリセットEMDASH_IP_SALTを変更(またはemdash:ip_saltオプション行を削除)
漏洩したAPIトークンを取り消し管理画面 → ユーザー → APIトークン → 取り消し、代替を作成
すべてのセッションを終了セッションストアをクリア(Workers KVネームスペース / セッションディレクトリ)
プロバイダー資格情報を置換プロバイダーでローテーション、env変数を更新、再デプロイ
プラグインAPIキーを置換プロバイダーでローテーション、プラグインの管理設定で再入力