アプリケーションキーと暗号化
このページでは、KolleKを運用するうえで最も重要なたった一つのルールを説明します。インスタンスに関するその他のことは、時間さえかければたいてい復旧できます。しかしこの設定だけは、データを取り返しのつかない形で失わせる可能性があります。
このキーが何をするか
KolleKは、.env内のAPP_KEYの値、つまりインスタンスのアプリケーションキーを使って、機密フィールドを保存時に暗号化します。名前、アイテムの詳細、カスタムフィールドの値、ファイル名、メールの記録、Webhookのシークレットなど、およそ30のモデルが暗号化されたカラムを持っています。これらのフィールドについてデータベースに保存されるのは暗号文であり、キーがなければ読み取れません。同じキーは、ユーザーセッションの保護にも使われています。
これはデータの保護についてがユーザー視点で説明している内容です。運用の観点から見ると、このキーは単なる設定項目のひとつではありません。データそのものの半分と言ってよいものです。
ルール
アプリケーションキーは初回起動前に一度だけ設定し、稼働中のインスタンスでは絶対に変更しないでください。キーが失われたり変更されたりすると、暗号化されたすべてのカラムとすべてのセッションが恒久的に読み取れなくなります。復旧方法もサポートも、データを取り戻す手段も一切ありません。
実務上、3つの結論が導かれます。
- キーはデータと一緒にバックアップする。 対応するキーのないデータベースバックアップは、暗号文のまま復元されます。キーはサーバーとは別に、パスワードマネージャーやシークレット管理ツールに保管してください。
- どこでも同一のキーを保つ。 3つのアプリケーションコンテナ(web、queue、scheduler)はすべて同じキーで動作する必要があります。提供されているComposeファイルは1つの
.envを共有することでこれを実現しています。独自のデプロイ構成でも、この性質は維持してください。 - 「念のため」に再生成しない。 稼働中のインスタンスに対して
key:generateを実行することは、典型的な自滅行為です。インスタンスはキーがなければ起動を拒否しますが、これはまさに、誰かが誤ってキーなしで起動し、稼働の途中で新しいキーを生成してしまうことを防ぐためです。
意図的にキーをローテーションする
方針上、定期的にキーをローテーションしなければならない運用者もいます。KolleKは「以前のキー」という仕組みでこれをサポートしています。現在のAPP_KEYが新しいデータをすべて暗号化する一方で、APP_PREVIOUS_KEYS(カンマ区切り)に列挙されたキーは、既存のデータを引き続き復号できます。
APP_KEY=base64:NEW_KEY_HERE
APP_PREVIOUS_KEYS=base64:OLD_KEY_HERE
php artisan key:generate --showで新しいキーを生成し(稼働中のキーを上書きしてしまう、引数なしのkey:generateは絶対に使わないでください)、古いキーをAPP_PREVIOUS_KEYSに移し、新しいキーをAPP_KEYとして設定してから、コンテナを再作成します。
そのキーで暗号化されたデータが存在する限り、APP_PREVIOUS_KEYSからキーを削除しないでください。データは再度書き込まれたときにだけ新しいキーで再暗号化されるため、古いレコードはいつまでも古いキーに依存し続けることがあります。
ローテーションが求められていない場合、最も安全でシンプルな方針は、キーを1つだけ用意し、一度だけ設定し、確実にバックアップしておくことです。
次に読むべきもの
- キーがバックアップと復元の計画に含まれていることを確認しましょう。
- 暗号化についてユーザー視点で説明したデータの保護についてを読みましょう。