SQL Database で異なるテナントに対して Geo レプリケーションを設定する場合のメモ。
Contents
異なるテナントの SQL Database に対しての Geo レプリケーション
Geo レプリケーションについては、サブスクリプション間 geo レプリケーション に記載されているように、異なるサブスクリプション間での Geo レプリケーションがサポートされています
この「異なるサブスクリプション間のレプリケーション」については、「異なるテナントのサブスクリプションのサポート」も含まれています。
異なるテナントのサブスクリプションに対しての Geo レプリケーションについては、Entra ID 認証はサポートされておらず、SQL 認証を使用して、同一のユーザー名 / パスワード / SID を使用したミラーアカウントを使用して、SQL Database 間の接続を確立する必要があります。
詳細については、サブスクリプション間 geo レプリケーション に記載されていますが、この方法を使用することで、異なるテナント間の SQL Database でレプリケーションを行うことが可能です。
SQL 認証については、データベース内で完結した認証情報を用いた認証ですので、テナントを跨いでも問題ありません。
Geo レプリケーション先のサーバーに対しての認証方法
異なるテナントに構築した Geo レプリケーション先のサーバーに対して、SQL 認証を使用するのであれば、接続については問題にならないかと思います。
しかし、Entra ID 認証を使用する場合には、いくつかの考慮が必要となります。
ユーザーを使用した認証
SQL Database は他のテナントのユーザーを使用して認証させることができるようになっています。
他のテナントのユーザーを使用して認証をさせる場合、Microsoft Entra ゲスト ユーザーを作成し、Microsoft Entra 管理者として設定する に記載されているように、ゲストユーザーとして Entra ID に登録し、そのユーザーに対して SQL Database のユーザーを作成する必要があります。
Geo レプリケーション先の異なるテナントの SQL Database に対して、Entra ID ユーザーを使用して接続をする場合も同様の考え方となるのですが、通常の方法とは少しだけ異なる対応となり、次のような設定が必要となるという認識です。
- Geo レプリケーション先のテナントのゲストユーザーとして、異なるテナントの Entra ID のユーザーを招待する
- Geo レプリケーション先のテナントで参加させたユーザーの「オブジェクト ID」を控える
- Geo レプリケーション元の SQL Database で以下のクエリを実行して、SID に使用可能なバイナリ値を生成する
- DECLARE @EntraIdObjectId uniqueidentifier = ‘<「2.」で確認したオブジェクト ID>’
SELECT CONVERT(varbinary(32), @EntraIdObjectId , 1)
- DECLARE @EntraIdObjectId uniqueidentifier = ‘<「2.」で確認したオブジェクト ID>’
- Geo レプリケーション元のデータベース (プライマリデータベースとして読み書きが可能なデータベース) で、SID を使用した CREATE USER を実行する。
- CREATE USER [<任意の名称>]
WITH SID = <「3.」で生成した SID>, Type=E
- CREATE USER [<任意の名称>]
Entra ID のユーザーを使用した認証については、SQL Database にログインしようとしたユーザーのオブジェクト ID が SID に設定されたユーザーがデータベースプリンシパルとして設定されている必要があります。
レプリケーション元のテナントでは、テナント内にログインしたいユーザーの Entra ID が存在しているため、通常の FROM EXTERNAL PROVIDER で SQL Database 上にユーザーを作成すれば問題ありません。
この際に作成したユーザーの情報については、別のテナントに作成した SQL Database に対しても同期が行われます。
しかし、このユーザーは別のテナントには存在していませんので、そのユーザーでレプリケーション先の別のテナントの SQL Database にアクセスをしようとしても、ユーザーが存在していないためアクセスを行うことができません
これを回避するために、最初にレプリケーション先の別テナントに対して、レプリケーション元のユーザーをゲストユーザーとして Entra ID に追加を行います。
これにより、異なるテナントに対しても同一のユーザーが作成された状態となりますが、このユーザーはゲスト参加したユーザーとなり、元のテナントとはオブジェクト ID が異なっているため、別のユーザーとして認識されている状態となります。
この別のユーザーとして認識されているユーザーを SQL Database に登録する必要があります。
SQL Database の Entra ID ユーザーの登録は「プライマリデータベースでしか作成できないため、他のテナントのユーザーを認識できない」「レプリケーション先でアクセスを行うためにはゲストユーザーとして登録されている Entra ID ユーザーで SQL Database にユーザーを作成する必要がある」という、少しややこしい状態となっています。
今回は、「プライマリデータベースで他のテナントでゲストユーザーとして登録されているユーザーを SQL Database のユーザーとして登録する」を実現するために、他のテナントでゲストユーザーとして参加させた際のオブジェクト ID を直接使用して、ユーザーを作成するという少しトリッキーな方法を使用しています。
サービスプリンシパルを使用した認証
サービスプリンシパルについては、サービスプリンシパルの制限事項 に次の記載があります。
サービス プリンシパルは、テナントの境界を越えて認証することはできません。 別のテナントで作成された Microsoft Entra アプリケーションを使用して SQL Database または SQL Managed Instance にアクセスしようとすると失敗します。
異なるテナント間で Geo レプリケーションを設定した場合、データベースプリンシパルについてはデータベース内のオブジェクトとなるため、各レプリケーション対象に同期は行われますが、テナントを跨いでサービスプリンシパルで認証をすることはできないため、サービスプリンシパルを使用した認証については Geo レプリケーション先ではエラーとなり接続を行うことができません。
マネージド IDを使用した認証
SQL Database へのアクセスについては、アクセス元の Azure リソースに割り当てられているマネージド ID を使用して接続を行うことができます。
マネージド ID を使用したアクセスについては、Azure リソースのマネージド ID に関するドキュメント のチュートリアルから確認することができます。
マネージド IDのリソース自体のテナント間 (クロステナント / クロスディレクトリ) のサポート状況については、マネージド ID を使って違うディレクトリやテナント内のリソースへアクセスできますか? に次のように記載されています。
マネージド ID を使って違うディレクトリやテナント内のリソースへアクセスできますか?
いいえ。現在、マネージド ID ではクロスディレクトリのシナリオはサポートされていません。
Azure Data Explorer (ADX) のようなマルチテナントに対応したリソースであれば、異なるテナントのマネージド ID を使用したアクセス権付与 を行うことができます。Key Vault についてもフェデレーション ID 資格情報を使用することでテナント間間で信頼されたアクセスを行うことができます。
レプリケーション元で設定したマネージド ID で、異なるテナントの Geo レプリケーション先の SQL Database にアクセスを行おうとすると、「Login failed for user ‘<token-identified principal>’. The server is not currently configured to accept this token.」となってしまい、アクセスを行うことができませんでした。
マルチテナントに対応したリソースが明記されているドキュメントが見当たらなかったのですが、SQL Database はマルチテナントに対応していない雰囲気がありますね。
Key Vault へのアクセス
SQL Database では、次の暗号化で Key Vault を使用することができます。
- TDE (透過的データ暗号化)
- Always Encrypted
これらについても、異なるテナントではどのような対応が必要となるかをまとめておきたいと思います。
TDE で異なるテナントの Key Vault に対してのアクセス
SQL Database では TDE (透過的データ暗号化) で Key Vault を使用した暗号化設定を行うことができます。
TDE では異なるテナントの Key Vault へのアクセスをサポートしており、ユーザー割り当てマネージド ID と TDE 用のテナント間 CMK を使用して構成されたサーバーを作成する の設定を行うことで、異なるテナントの Key Vault を使用して、TDE を設定することができます。
この設定は、Geo レプリケーション元で、TDE を Key Vault を使用して実施しており、異なるテナントの SQL Database に対して Geo レプリケーションを実施する際には、異なるテナントに対しての Key Vault のアクセスが必須となります。
異なるテナントの Key Vault に対してアクセスを行うためには次の設定が必要となります。(Geo レプリケーション元に Key Vault があり、レプリケーション先の異なるテナントからアクセスすることを想定しています)
- レプリケーション先の SQL Database でユーザー割り当てマネージド ID を設定
- レプリケーション先の Entra ID でアプリの登録から、マルチテナントを対象としたアプリケーションを作成
- 作成したアプリケーション の「証明書とシークレット」の「フェデレーション資格情報」から「カスタムマネージドキー」のシナリオのフェデレーション資格情報を「1.」で設定したユーザー割り当てマネージド ID を選択して作成する
- レプリケーション先の SQL Database のフェデレーションクライアント ID として、「3.」で設定したフェデレーションクライアント ID を設定
- レプリケーション元で「2.」で作成したアプリケーション ID を使用したサービスプリンシパルを作成
- レプリケーション元の Key Vault に「5.」で作成したアプリケーションのアクセス権を設定
- レプリケーション先の SQL Database で TDE を設定する際に、レプリケーション元の Key Vault をキー識別子で指定
少し手間はかかるのですが、このような設定を行うことで、フェデレーションクライアント ID を使用して、異なる Key Vault のキーを使用して TDE を設定することができます。
Always Encrypted で異なるテナントの Key Vault に対してアクセス
Always Encrypted という暗号化機能では、列の暗号化を行うキー (CEK) を保護するための列マスターキー (CMK) に Key Vault を使用することができます。
CMK には、ローテーション (回転) という概念があり、キーを最大で 2 つ登録した状態にすることができ新しいキーに CMK を置き換えるという操作がサポートされています。
- SQL Server Management Studio を使用して Always Encrypted キーを交換する
- PowerShell を使用して Always Encrypted キーをローテーションする
CMK を SQL Database と異なるテナントに設定しておくこと自体は問題ないのですが、CMK にキーを追加する際に最初に登録した Key Vault とは異なるテナントの Key Vault をローテーションのために追加するということが機能的に難しそうな雰囲気がありました
「列マスターキーに複数のテナントの Key Vault を登録する」という操作自体は問題なく実施することができます。
しかし、異なるテナントのキーにローテーションを行おうとすると、「AdditionallyAllowedTenants」の指定の要求が発生してしまいました。
To enable acquiring tokens for this tenant add it to the AdditionallyAllowedTenants on the credential options, or add "*" to AdditionallyAllowedTenants to allow acquiring tokens for any tenant. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/multitenant/troubleshoot (Azure.Identity)
SSMS でキーをローテーションする際の Key Vault へのアクセスは InteractiveBrowserCredential が使用されているのですが、 この際に InteractiveBrowserCredentialOptions で AdditionallyAllowedTenants / TenantId を SSMS から指定するためのインタフェースは提供されていないようで、EnvironmentCredential を使用するように切り替えることも難しそうなので複数のテナントに CMK を配置して使用することは機能的に厳しいのではと感じています。
Always Encrypted については「異なるテナントの Key Vault を使用することはできるが、複数のテナントを使用するように CMK を構成するのはできない」というようになるのではないでしょうか。