環境間のデータ分離
KeenAuth の各環境(プロジェクトごとの development、staging、production)は、それぞれ独立したテナントです。ある環境のユーザー、組織、アプリケーション、セッション、キー、ログ、イベントは、アカウント内の別の環境を含め、他の環境からは参照できません。このページでは、この境界がどのように適用されるかを説明します。
独立した 2 つの防御層
環境はデータベーススキーマを共有しており、環境に属するすべての行には、その環境の識別子が付与されています。分離は 2 段階で適用されており、データが境界を越えるには両方のチェックが同時に失敗する必要があります。
- アプリケーションにおける型付きの環境スコープ。 すべてのリクエストは、データを読み取る前に、ホスト名または認証情報から必ず 1 つの環境に解決されます。環境データを読み書きするコードは、そのスコープなしにデータベーストランザクションを開始できません。スコープなしの呼び出しは、クエリが実行される前に拒否されます。
- PostgreSQL の行レベルセキュリティ。 環境データを保持するすべてのテーブルでは、行レベルセキュリティが有効化され、強制されています。そのため、ポリシーはテーブルの所有者にも適用されます。各トランザクションで現在の環境を設定し、行は環境が一致する場合にのみ参照できます。環境を設定していないトランザクションには、行が一切見えません。アプリケーション用またはメンテナンス用のロールであっても、行レベルセキュリティを回避することは許可されていません。
環境スコープのすべてのテーブルは、主キーとインデックスの先頭を環境識別子で始めているため、分離の条件によってクエリに別途の検索が追加されることはありません。
トークンまたはキーによる検索
一部のリクエストは、認可コード、リフレッシュトークン、API キーなど、秘密の値だけを伴って届きます。KeenAuth は、このような値をダイジェストのみを使った検索で見つけ、保存されているレコードの環境とリクエストの環境を比較します。両者が異なる場合、その値は無効として扱われます。
境界を越えた場合の応答
| 試行 | 応答 |
|---|---|
| 別の環境に属するリソースを読み取る | 404 Not Found。応答からリソースの存在は分からないようになっています |
| 別の環境が発行したアクセストークンを使用する | 401 Unauthorized。各環境は独自の発行者と署名キー(JWKS)を持ちます |
| 別の環境に登録されたクライアントで認証する | invalid_client |
データベース以外の領域
同じ境界は、環境データが存在する他のすべての場所にも適用されます。
- キャッシュ: すべてのキャッシュキーは、環境識別子で始まります。
- イベントとジョブ: 内部イベントはすべて、その環境の情報を持ちます。コンシューマーは、そこからデータベースのスコープを設定します。キューに入るジョブはすべて、所属する環境の情報を持ちます。
- キー: 暗号化キーと署名キーは、環境ごとに分けられています。
- ログ: ログの各行は、環境をフィールドとして持ちます。環境ログ API は、呼び出し元の環境のエントリのみを返します。
- バックグラウンド処理: メンテナンスジョブ(保持期間に基づく削除、データの削除など)は、環境ごとに実行され、それぞれが独自のスコープ付きトランザクションで処理されます。
設定をある環境から別の環境へ移行する(設定のプロモーション)場合、コピーされるのは設定のみです。シークレット、エンドユーザーのデータ、組織のデータは、プロモーションのバンドルに含まれることはありません。
分離の検証方法
テナント間の分離をテストするスイートは、KeenAuth の継続的インテグレーションで実行され、失敗した場合は変更をブロックします。このスイートは次の点を検証します。
- 環境データを保持するすべてのテーブルで、行レベルセキュリティが有効化され、強制されていること。
- 各 API サーフェスが、別の環境のリソース、トークン、クライアントに対して
404または401を返すこと。 - バックグラウンドジョブ、ならびにログとイベントのパイプラインが、入力で指定された環境にのみ作用すること。
また、スキーマチェックにより、環境識別子の列を持たない新しい環境データテーブルは拒否されます。