---
title: "マスターキーと署名鍵のローテーション、緊急アクセス"
description: "保存済み認証情報を保護するマスターキーをローテーションし、緊急アクセスを使います。"
image: "https://docs.quirelms.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.quirelms.com/ja/llms.txt
> Use this file to discover all available pages before exploring further.

# マスターキーと署名鍵のローテーション、緊急アクセス

<span id="master-key-and-signing-key-rotation-and-break-glass-access"></span>

監査人が名前を挙げて確認する管理項目です。このページは手順であり、実行によって作成される記録が証拠になります。

## 鍵 <!--quire:the-keys-->

保存される認証情報はすべて、新しいデータ暗号化鍵 (DEK) で封印されます。DEK はマスター鍵 (KEK) でラップされ、マスター鍵の参照先は隣接する場所 (`key_ref` またはパック値内の参照) に保存されます。マスターキーのローテーションでは DEK を再ラップします。認証情報そのものを復号して再暗号化することはありません。

| 設定 | 意味 |
| --- | --- |
| `QUIRE_MASTER_KEY` | 現行のマスターキー。32 バイト、base64。新しいシークレットはすべてこれでラップ |
| `QUIRE_MASTER_KEY_VERSION` | バージョンラベル。未設定時は `v1`。鍵を変更するたびに更新 |
| `QUIRE_MASTER_KEY_RETIRED` | シークレットの暗号化に使われた可能性がある旧鍵。`v1=<base64>,v0=<base64>` 形式。読み取り専用 |

Web 層、worker、`bun run kek:rotate` コマンドは同じ 3 つの設定を読み込みます。値をそろえないと、一方が封印したデータをもう一方で開けません。

`QUIRE_MASTER_KEY` がない場合、各サブシステムは `QUIRE_SECRET_KEY` から派生した鍵を使い続けます。これは動作しますが、System health ページでは劣化状態になります。マスターキーを設定してもデータは読めるため、最初のローテーションでこの鍵からすべてを移せます。プロセス環境を読める人なら保存済み認証情報を復号できるため、本番環境ではマスターキーをシークレットストアに保存してください。データベースのバックアップと同じ場所に置かないでください。

## ローテーション <!--quire:rotating-->

鍵の使用期間は Platform console の Security、Master key と、メトリクス `quire.secrets.master_key.age` (日数) に表示されます。毎日 03:41 UTC の `platform.key_age` スケジュールは、鍵が 365 日に達するとプラットフォーム監査チェーンにリマインダーを記録し、ローテーションされるまで 30 日ごとに再通知します。通知を受けたとき、または鍵が漏れた可能性があるときにローテーションしてください。

1. 新しい鍵を生成します: `openssl rand -base64 32`。
2. `QUIRE_MASTER_KEY` に設定し、`QUIRE_MASTER_KEY_VERSION` を次のラベル (`v2`) にします。古い鍵を `QUIRE_MASTER_KEY_RETIRED` の `v1=<old base64>` として移します。両方の鍵のコピーを別の場所に保管してください。
3. 新しい設定で Web 層と worker をデプロイします。新しいシークレットは `env:QUIRE_MASTER_KEY:v2` でラップされ、旧シークレットは廃止鍵を使って開けます。
4. 監査記録に残す理由を添えてローテーションを要求します。
   - コンソール: Security、Master key、Rotate the master key。
   - 同じ環境を使うシェル: `bun run kek:rotate request --reason "Annual rotation, ticket SEC-114"`。
5. worker は `platform.key_rotation` スケジュールで毎分一部を再ラップし、再起動後も続きから処理します。一度に完了するには `bun run kek:rotate run` を実行します。`bun run kek:rotate status` で状態を確認します。
6. 記録の状態が完了で、未解決と失敗が **ゼロ** になったら、`QUIRE_MASTER_KEY_RETIRED` から旧鍵を削除して再デプロイします。それまでは保持してください。移動できなかった値は旧鍵でラップされたままです。

### ジョブが処理する範囲 <!--quire:what-the-job-walks-->

DEK をラップした値が保存されているすべてのストア、つまり `SEALED_STORES` (`apps/worker/src/key-rotation.ts`) に記載されたものを処理します。制御 DB のストアは制御 DB 上で、組織ストアは行レベルセキュリティのもと組織ごとに処理します。組織がある DB で処理されるため、専用 DB に固定されたテナントのローテーションもその DB で行われます。スキーマにラップ鍵の列が追加されたのに一覧で指定されていない場合に失敗するテストと、認証情報レビューで一覧にない封印済み列が分類された場合に失敗するテストがあります。

### 記録 <!--quire:the-record-->

- `ops.key_rotation`: ローテーションごとに 1 行。理由、要求者、状態、再ラップ済み・現行・未解決・失敗の件数を記録。
- `ops.key_rotation_progress`: 処理済みストアとスコープごとに 1 行。読み取れなかった鍵参照と各鍵で封印された値の数を記録。再開時はスキップします。
- プラットフォーム監査チェーン: 理由付きの `platform/key_rotation_request`、各ストアの件数を示す `platform/key_rotation_store`、`platform/key_rotation_complete` または `platform/key_rotation_fail`。リマインダーは `platform/key_age_reminder`。
- メトリクス: `quire.secrets.master_key.age` と `quire.secrets.rewrap.outstanding` (直近のローテーションで移動できなかった値)。

### 未解決の値がある場合 <!--quire:when-values-are-unresolved-->

未解決の値とは、このインストールが持たない鍵参照でラップされている値、または列の想定形式ではない値です。進捗記録に参照が表示されます (例: `env:QUIRE_MASTER_KEY:v0 (unreadable)`)。その鍵を `QUIRE_MASTER_KEY_RETIRED` に戻して再度ローテーションします。鍵を完全に失った場合は、組織の管理者に認証情報を再入力してもらいます。現行鍵で封印されます。ローテーション失敗の記録にはエラーが表示されるため、原因を修正して再度要求してください。

## 署名鍵 <!--quire:signing-keys-->

マスターキーとは別に、各組織は独自の RSA 鍵で OpenID Connect トークンと LTI メッセージに署名し、`/.well-known/jwks.json` で公開します。運用者による操作は不要です。1 時間ごとの `platform.signing_keys` スケジュールが、現在の鍵の 90 日期限の 7 日前に後継鍵を公開します。1 週間後に後継鍵が署名を始め、旧鍵は廃止予定になります。その 90 日後に旧鍵を削除し、鍵セットから取り除きます。各段階はプラットフォーム監査チェーンの `platform/signing_key_advance` に記録されます。

漏えい後など、予定より早く組織の鍵を変更する手順です。

- コンソールで新しい署名鍵を発行します (`platform/keys_manage`)、または
- worker の環境を使うシェルから `bun run kek:rotate signing-keys rotate
  --tenant <slug or id> --reason "Key exposed, INC-3310"`. `bun run kek:rotate
  signing-keys status` では各組織の鍵の状態を確認できます。

新しい鍵はすぐに公開され、現行鍵の廃止から 7 日後に署名を開始します。鍵セットをキャッシュする利用側への余裕を設けるため、この 1 週間の重複期間が必要です。期間が短いとすべてのツールで署名に失敗するおそれがあります。廃止された鍵もさらに 90 日間鍵セットに残り、すでに署名したトークンを検証できます。漏えいのため、より早く信頼対象から外す必要がある場合は、運用者が変更記録に従って自分の DB アクセスで行を削除します (緊急アクセスは読み取り専用)。その鍵で署名したトークンは検証できなくなります。強制ローテーションは理由とともに `platform/signing_key_rotate` として監査チェーンに記録されます。新しい鍵をラップする worker には Web 層と同じ `QUIRE_MASTER_KEY` 設定が必要です。マスターキーの `bun run kek:rotate` は署名鍵も含めて再ラップします (`oauth_signing_key` は `SEALED_STORES` に含まれます)。

## 本番環境の緊急アクセス <!--quire:break-glass-production-access-->

本番環境に常時アクセスできる人はいません。待てない問題が起きた場合、所有者は Platform console の Security、Break-glass access で緊急アクセスを許可します。

- 許可範囲は 1 組織またはプラットフォームレジストリ、理由はインシデントまたはチケット番号を含む 20 文字以上、期間は 5～240 分です。各ステートメントで時刻を確認し、自動失効します。
- 発行した所有者自身、または別の所有者に付与できます (二者承認方式)。使えるのは指定された本人だけです。発行には `platform/break_glass_issue`、利用には `platform/break_glass_use` が必要です。既定ではどちらも所有者専用です。
- ステートメントは DB ログインではなくゲートウェイ経由で実行します。読み取り専用で、1 件ずつ実行し、組織または制御レジストリ内に限定します。タイムアウトは 5 秒、最大 500 行です。バイナリ値はサイズだけ表示されます。
- プラットフォーム監査チェーンには、発行 (理由付き)、取り消し、実行前の各ステートメント (`platform/break_glass_statement`。拒否した場合は結果 `denied`)、各結果 (`platform/break_glass_result`) が記録されます。`ops.break_glass_statement` には監査エントリー ID があり、発行記録と監査記録を照合できます。
- 書き込みはできません。リリースを待てない変更は、製品外で運用者自身が DB アクセスを使い、独自の変更記録に従って実施します。その記録にはここで使ったインシデント参照を記載してください。

DB 認証情報を発行しないのは、Postgres ログインが依頼者のセッションより長く残り、アプリケーションが使う行レベルセキュリティを迂回し、この製品の監査チェーンにも記録できないためです。ステートメントの記録は、サーバーログを保存した範囲に限られてしまいます。ゲートウェイを使うことで、監査証跡を運用上の慣行ではなく、アクセス自体の一部にできます。

監査請求に回答するには、対象期間の許可を一覧表示し (Break-glass access)、許可の履歴からステートメントと監査エントリー ID を確認し、プラットフォーム監査チェーンの記録を読みます (`bun run audit:verify --platform` でチェーンの完全性を検証)。

Source: https://docs.quirelms.com/ja/ops/key-rotation/index.mdx
