Fabric データ ウェアハウスでの行レベルのセキュリティ
適用対象:✅ Microsoft Fabric の SQL 分析エンドポイントおよびウェアハウス
行レベルのセキュリティ (RLS) では、グループ メンバーシップや実行コンテキストを使用して、データベース テーブル内の行へのアクセスを制御することができます。 たとえば、作業者が自分の部署に関連するデータ行にしかアクセスしないようにすることができます。 別の例として、マルチテナント アーキテクチャで顧客のデータ アクセスをその顧客の会社に関連するデータだけに制限することがあります。 この機能は、SQL Server の行レベルのセキュリティに似ています。
データ レベルでの行レベルのセキュリティ
行レベルのセキュリティにより、アプリケーションでのセキュリティの設計やコーディングが簡略化されます。 行レベルのセキュリティは、データ行アクセスに対して制限を実装するのに役立ちます。
アクセス制限ロジックは、単一のアプリケーション層ではなく、データベース層にあります。 Power BI を含む任意のアプリケーションまたはレポート プラットフォームからデータ アクセスが試行されるたびに、データベースによってアクセス制限が適用されます。 これによりセキュリティ システムの外部からのアクセスが減り、そのシステムの信頼性と堅牢性が向上します。 行レベルのセキュリティは、Fabric のウェアハウスまたは SQL 分析エンドポイントのクエリにのみ適用されます。 Direct Lake モードのウェアハウスに対する Power BI クエリは、行レベルのセキュリティに準拠するために Direct Query モードにフォールバックします。
特定の行へのアクセスを特定のユーザーに制限する
CREATE SECURITY POLICY Transact-SQL ステートメントを使用して RLS を実装すると、インライン テーブル値関数として述語が作成されます。
基になるデータ ソースが変更されていないため、行レベルのセキュリティは、共有ウェアハウスまたはレイクハウスに適用されます。
述語ベースの行レベルのセキュリティ
Fabric Synapse Data Warehouse の行レベルのセキュリティでは、述語ベースのセキュリティがサポートされています。 フィルター述語は、読み取り操作が可能な行を通知なしにフィルター処理します。
テーブルの行レベルのデータへのアクセスは、インライン テーブル値関数として定義されたセキュリティ述語によって制限されます。 関数が呼び出され、セキュリティ ポリシーによって適用されます。 フィルター述語の場合、結果セットからフィルター処理されている行はアプリケーションによって認識されません。 すべての行がフィルター処理されると、null セットが返されます。
フィルター述語は、ベース テーブルからのデータの読み取り中に適用されます。 SELECT
、DELETE
、UPDATE
など、すべての取得操作に影響します。 各テーブルには、独自の行レベル セキュリティが個別に定義されている必要があります。 行レベル セキュリティ ポリシーなしでテーブルにクエリを実行するユーザーには、フィルター処理されていないデータが表示されます。
ユーザーは、フィルター処理される行を選択または削除できません。 ユーザーは、フィルター処理される行を更新できません。 しかし、後でフィルター処理されるようにすれば行を更新できます。
フィルター述語とセキュリティ ポリシーには、次の動作があります。
別のテーブルとの結合や関数の呼び出しを実行する述語関数を定義できます。 セキュリティ ポリシーが
SCHEMABINDING = ON
(既定) を使用して作成されている場合、結合または関数にはクエリからアクセスでき、追加のアクセス許可の確認を必要とせず、期待どおりに動作します。セキュリティ述語は定義されているが無効になっているテーブルに対してクエリを発行できます。 フィルター処理またはブロックされている行には影響しません。
dbo ユーザー、
db_owner
ロールのメンバー、またはテーブルの所有者が、セキュリティ ポリシーが定義され有効になっているテーブルに対してクエリを実行すると、セキュリティ ポリシーでの定義に従って行がフィルター処理またはブロックされます。スキーマ バインドされたセキュリティ ポリシーによってバインドされているテーブルのスキーマを変更しようとすると、エラーが発生します。 ただし、述語で参照されていない列は変更できます。
指定された操作に対する述語が既に定義されているテーブルに述語を追加しようとすると、エラーが発生します。 これは、述語が有効になっているかどうかを問わず発生します。
スキーマ バインドされたセキュリティ ポリシー内のテーブルで述語として使用されている関数を変更しようとすると、エラーが発生します。
重複しない述語が含まれる複数のアクティブなセキュリティ ポリシーの定義は、行うことができます。
フィルター述語の動作は次のとおりです。
- テーブルの行をフィルター処理するセキュリティ ポリシーを定義します。 アプリケーションは、
SELECT
、UPDATE
、DELETE
操作用にフィルター処理された行を認識しません。 これには、すべての行がフィルター処理された状況も含まれます。アプリケーションでは、他の操作中にフィルター処理される場合でも、行のINSERT
を行うことができます。
アクセス許可
セキュリティ ポリシーの作成、変更、削除には、ALTER ANY SECURITY POLICY
アクセス許可が必要です。 セキュリティ ポリシーの作成や削除には、スキーマに対する ALTER
アクセス許可が必要です。
また、追加される各述語に関しては次のアクセス許可も必要になります。
SELECT
アクセス許可とREFERENCES
アクセス許可 (述語として使用される関数)。REFERENCES
アクセス許可 (ポリシーへのバインド対象となるテーブル)。REFERENCES
アクセス許可 (対象テーブル内の、引数として使用されるすべての列)。
セキュリティ ポリシーは、データベースの dbo ユーザーを含めてすべてのユーザーに適用されます。 dbo ユーザーはセキュリティ ポリシーを変更したり削除したりできますが、セキュリティ ポリシーに加えた変更は監査することができます。 管理者、メンバー、共同作成者などのロールのメンバーが、データのトラブルシューティングや検証を行うためにすべての行を表示する必要がある場合は、セキュリティ ポリシーを作成して許可する必要があります。
SCHEMABINDING = OFF
でセキュリティ ポリシーが作成された場合、ユーザーは、対象テーブルにクエリを実行するために、述語関数とその述語関数で使用される追加のテーブル、ビュー、または関数に対する SELECT
アクセス許可または EXECUTE
アクセス許可が必要です。 SCHEMABINDING = ON
(既定) でセキュリティ ポリシーが作成された場合、ユーザーが対象テーブルに対してクエリを実行すると、これらの権限チェックは迂回されます。
セキュリティに関する考慮事項: サイド チャネル攻撃
次の 2 つのシナリオを検討し、準備します。
悪意のあるセキュリティ ポリシー マネージャー
悪意のあるセキュリティ ポリシー マネージャーを監視することが重要です。これは、機密性の高い列にセキュリティ ポリシーを作成する十分な権限と、インライン テーブル値関数を作成したり、変更したりする権限がそのセキュリティ ポリシー マネージャーにある場合、テーブルで選択権限を持つ別のユーザーと共謀し、サイドチャネル攻撃を使ってデータを推測するインライン テーブル値関数を作成して、悪意を持ってデータを流出させることも可能になるためです。 このような攻撃では、共謀 (または過剰な権限を悪意のあるユーザーに与えること) が必要で、ポリシーの変更が何度も必要になる可能性が高く (スキーマ バインドを解除するために述語を削除する権限を要求する)、インライン テーブル値関数が変更され、対象のテーブルに対して select ステートメントが繰り返し実行されることになります。 必要に応じてアクセス許可を制限し、疑わしいアクティビティを監視することをお勧めします。 行レベルのセキュリティに関連して、絶えず変化するポリシーやインライン テーブル値関数などのアクティビティを監視する必要があります。
慎重に作成されたクエリ
エラーを使用してデータを流出させる慎重に作成されたクエリを使用して、情報漏えいを引き起こす可能性があります。 たとえば、SELECT 1/(SALARY-100000) FROM PAYROLL WHERE NAME='John Doe';
で、悪意のあるユーザーに John doe さんの給与が正確に 100,000 ドルであることが知らされました。 悪意のあるユーザーが他のユーザーの給与を直接照会するような事態を防ぐため、セキュリティ述語がある場合でも、ゼロ除算の例外がクエリ結果として返されることで、悪意のあるユーザーによって知られてしまいます。
例
Microsoft Fabric で行レベルのセキュリティ ウェアハウスと SQL 分析エンドポイントを示すことができます。
次の例では、Fabric の Warehouse で動作するサンプル テーブルを作成しますが、SQL 分析エンドポイントでは既存のテーブルを使用します。 SQL 分析エンドポイントでは CREATE TABLE
はできませんが、 CREATE SCHEMA
、CREATE FUNCTION
、CREATE SECURITY POLICY
はできます。
この例では、最初にスキーマ sales
、テーブル sales.Orders
を作成します。
CREATE SCHEMA sales;
GO
-- Create a table to store sales data
CREATE TABLE sales.Orders (
SaleID INT,
SalesRep VARCHAR(100),
ProductName VARCHAR(50),
SaleAmount DECIMAL(10, 2),
SaleDate DATE
);
-- Insert sample data
INSERT INTO sales.Orders (SaleID, SalesRep, ProductName, SaleAmount, SaleDate)
VALUES
(1, 'Sales1@contoso.com', 'Smartphone', 500.00, '2023-08-01'),
(2, 'Sales2@contoso.com', 'Laptop', 1000.00, '2023-08-02'),
(3, 'Sales1@contoso.com', 'Headphones', 120.00, '2023-08-03'),
(4, 'Sales2@contoso.com', 'Tablet', 800.00, '2023-08-04'),
(5, 'Sales1@contoso.com', 'Smartwatch', 300.00, '2023-08-05'),
(6, 'Sales2@contoso.com', 'Gaming Console', 400.00, '2023-08-06'),
(7, 'Sales1@contoso.com', 'TV', 700.00, '2023-08-07'),
(8, 'Sales2@contoso.com', 'Wireless Earbuds', 150.00, '2023-08-08'),
(9, 'Sales1@contoso.com', 'Fitness Tracker', 80.00, '2023-08-09'),
(10, 'Sales2@contoso.com', 'Camera', 600.00, '2023-08-10');
Security
スキーマ、関数 Security.tvf_securitypredicate
、セキュリティ ポリシー SalesFilter
を作成します。
-- Creating schema for Security
CREATE SCHEMA Security;
GO
-- Creating a function for the SalesRep evaluation
CREATE FUNCTION Security.tvf_securitypredicate(@SalesRep AS nvarchar(50))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS tvf_securitypredicate_result
WHERE @SalesRep = USER_NAME() OR USER_NAME() = 'manager@contoso.com';
GO
-- Using the function to create a Security Policy
CREATE SECURITY POLICY SalesFilter
ADD FILTER PREDICATE Security.tvf_securitypredicate(SalesRep)
ON sales.Orders
WITH (STATE = ON);
GO
行レベル セキュリティ機能を変更するには、まずセキュリティ ポリシーを削除する必要があります。 次のスクリプトでは、Security.tvf_securitypredicate
で ALTER FUNCTION
ステートメントを発行する前に、ポリシー SalesFilter
を削除します。 次に、ポリシー SalesFilter
を再作成します。
-- Drop policy so we can change the predicate function.
DROP SECURITY POLICY SalesFilter;
GO
-- Alter the function for the SalesRep evaluation
ALTER FUNCTION Security.tvf_securitypredicate(@SalesRep AS nvarchar(50))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS tvf_securitypredicate_result
WHERE @SalesRep = USER_NAME() OR USER_NAME() = 'president@contoso.com';
GO
-- Re-create a Security Policy
CREATE SECURITY POLICY SalesFilter
ADD FILTER PREDICATE Security.tvf_securitypredicate(SalesRep)
ON sales.Orders
WITH (STATE = ON);
GO