はじめに
本記事は any Advent Calendar #2 「マルチテナントSaaSにおけるエンジニアリング大全」 Day15 の記事です。 弊社anyのアドベントカレンダーをひとつ丸ごと占有して、ひとりアドベントカレンダーとして、筆者の「マルチテナントSaaSのエンジニアリング」への経験をすべてアウトプットしていくカレンダーです。
本日は「鍵管理」について取り上げます。マルチテナントSaaSでは、外部APIのシークレットキーやトークンなど、機密性の高いデータを安全に、かつデータ分離を確保しながら管理する必要があります。
鍵管理における基本方針
AWSにおいては、鍵を利用した暗号化/復号の選択肢として、Secrets ManagerやAWS KMSでの鍵管理といったソリューションがあります。今回はAWS KMSを活用したエンベロープ暗号化によって、テナントごとに論理的に分離された鍵管理を実現する方法を解説します💪
下記のような要件を満たしていきたいです。
- 外部APIシークレットなどをデータベースに平文で保存しないこと
- テナント間でデータキーを共有せず、論理的に分離すること
- テナント数が増加しても運用コストが線形に増えないこと
- 鍵の漏洩リスクを最小化し、鍵のローテーションが容易に行えること
そこで重要となる概念の一つであるエンベロープ暗号化について触れていきましょう。
エンベロープ暗号化とは
エンベロープ暗号化は、データキーでプレーンテキストデータを暗号化してから、そのデータキーを別のキーで暗号化する手法のことで、AWS KMSにおける事実上のベストプラクティスです。ここでは二種類の鍵を利用します。
- マスターキー(CMK): AWS KMSで管理される共通鍵。全テナントで共有されるが、直接データの暗号化には使用しない
- データキー: マスターキーから生成される個別の鍵。実際のデータ暗号化に使用し、暗号化された状態でDBに保存される
https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/overview.html
エンベロープ暗号化によって、以下のメリットを得ることができます。
- マスターキーをKMSの外に出さずに済む(実際にエクスポートすることも不可)
- 暗号化処理の都度、新しいデータキーを生成することで最高レベルのセキュリティを実現
- データキー自体も暗号化されて保存されるため、DBが漏洩してもデータを復号できない
- マスターキーのローテーションや管理をAWSに委任してしまうことができる
処理全体の構成について
処理自体は難しくありません。暗号化と復号のときで下記のことを実行します。
暗号化時:
アプリケーションが KMS の GenerateDataKey を呼び出し、その場限りのデータキー(平文および暗号文)を取得して暗号化を行います。
復号時:
DBに保存された「暗号化されたデータキー」を KMS の Decrypt で復号し、平文のデータキーを取得してデータを復号します。
暗号化のたびに新しいデータキーが生成される点が非常に重要で、データキーの使い回しによるリスクを完全に排除できます。
Qastにおいてもこの方式を採用しています。もともとテナント作成時にデータキーを発行し、それ以降の暗号化/復号処理ではそのデータキーを使い回すようなアーキテクチャを検討していたのですが、AWSのSolution Architectの方と会話するなかで、このAWS推奨のパターンを採用しました。
Encryption Contextを使う
さらにマルチテナント文脈において、テナント分離を実現する鍵となるのが、KMSの Encryption Context です。
Encryption Contextは、暗号化時に付与するキーバリューペアのメタデータで、復号時にも同じ値を指定する必要があります。本実装では tenantId をEncryption Contextに含めることで、
- テナントAのデータキーで暗号化されたデータは、テナントAのEncryption Contextでしか復号できない
- 仮にアプリケーションのバグで別テナントのデータキーを取得しようとしても、KMSレベルで拒否される
つまり、データベース層だけでなく、KMS層でもテナント分離が実現 できます。
実運用における考慮事項
キーのローテーションについて
推奨方式では、データを暗号化するたびに新しいデータキー(ユニークな鍵)が生成されます。そのため、データキー単位でのローテーションという概念は不要(常に新しい鍵が使われるため)であり、最もセキュリティ強度が高い状態となります。マスターキー(CMK)については、AWS KMS側の自動ローテーション設定を有効にすることで、アプリケーション側の変更なしに対応可能です。
まとめ
本記事では、AWS KMSを活用したエンベロープ暗号化、Encryption Contextの手法を紹介しました。マルチテナントのアーキテクチャにおいても安全に鍵を利用できるので、ぜひ参考にしてみてください!
