Log Analyticsワークスペースは運用チームで共有したい一方、SigninLogsやSecurityEvent、個人情報を含むカスタムログなど、一部のテーブルだけは閲覧者を厳しく限定したい。この要件には、ワークスペースを分割する前に、Azure Monitorのプレビュー機能であるProtected Tablesを検討するのが現実的です。
基本設計は、通常の運用テーブルをGeneralのまま共有し、機微情報を含むテーブルだけをProtectedに変更します。保護されたテーブルには、組み込みロールのPrivileged Monitoring Data Reader、またはテーブル名と保護レベルを条件にしたカスタムロールでアクセスを許可します。さらに厳格にする場合は、ワークスペースをDataActionsOnlyモードへ移行し、ログデータへのアクセスをデータプレーンの権限だけで管理します。
ただし、Azure RBACは権限を加算して評価します。制限付きロールを追加しても、上位スコープに広い読み取りロールが残っていれば、意図した制限にならないことがあります。したがって、Log Analytics権限の再設計では、設定変更より先に、サブスクリプション、リソースグループ、ワークスペース、個別リソースから継承される既存RBACを棚卸しすることが重要です。2026年7月時点で、Protected Tablesはプレビューとして公式の設定手順が公開されています。(Microsoft Learn)
生成AI以外にも使える新しいテーブル単位アクセス制御
Protected Tablesは、特定のテーブルに対して「明示的に許可された利用者以外にはデータを見せない」という、拒否を既定とするアクセスモデルを適用します。
生成AIのプロンプトや応答ログだけでなく、次のようなデータにも利用できます。
- Microsoft Entra IDのサインインログ
- セキュリティイベントやインシデント調査ログ
- 個人情報を含むアプリケーションログ
- 医療、金融、決済に関係する監査ログ
- 管理者の操作履歴
- 問い合わせ本文やユーザー入力を保存したカスタムテーブル
- AIエージェントが参照、生成した機密データ
Microsoftの公式ドキュメントでも、個人情報、医療情報、金融記録、AIのプロンプトや応答などが、Protected Tablesの対象例として挙げられています。(Microsoft Learn)
重要なのは、テーブル名だけで機密性を判断しないことです。たとえばAppTracesは通常のエラーログだけを保存している環境もあれば、メールアドレス、問い合わせ本文、アクセストークンの断片などが混入している環境もあります。
次のように、実際に保存されるデータを基準に分類します。
| 分類 | データの例 | 推奨する保護レベル | 主な閲覧者 |
|---|---|---|---|
| 一般運用ログ | 稼働状況、CPU、メモリ、Heartbeat、通常のエラー | General | 運用、開発、ヘルプデスク |
| 制限付き運用ログ | サインイン履歴、管理操作、セキュリティイベント | Protected | IAM、SOC、セキュリティ管理者 |
| 高機密ログ | 個人情報、金融情報、AI入出力、調査対象データ | Protected | 限定グループ、監査担当者 |
| 緊急時のみ必要なログ | インシデント調査用の証跡 | Protected | PIMで一時昇格した担当者 |
Log Analytics権限の再設計で採用すべき構成
「機微テーブルだけを厳しく制限し、その他のログは従来どおり共有する」という要件では、次の構成が分かりやすく、運用もしやすくなります。
Log Analyticsワークスペース
├─ Generalテーブル
│ └─ 運用チームや開発チームへ通常の読み取り権限を付与
│
└─ Protectedテーブル
├─ 全保護テーブルの閲覧者
│ └─ Privileged Monitoring Data Reader
│
├─ 特定テーブルだけの閲覧者
│ └─ DataActions+ABAC条件を持つカスタムロール
│
└─ 緊急時の閲覧者
└─ Microsoft Entra PIMによる期限付きアクセス
通常テーブルへのアクセスと、保護テーブルへのアクセスを分けることで、運用担当者の作業性を維持したまま、機微情報への最小権限を実現できます。
Protected Tablesでは、テーブルのprotectionLevelをProtectedにすると、一般的な読み取りロールからそのテーブルのデータが見えなくなります。アクセスを許可する場合は、保護テーブル向けの組み込みロール、またはDataActionsとABAC条件を持つロールを明示的に割り当てます。(Microsoft Learn)
Protected Tablesと既存のテーブル単位RBACの違い
Log Analyticsには複数のテーブル単位アクセス制御方式がありますが、新規設計ではProtected TablesまたはGranular RBACが推奨されています。従来の二重ロール方式や、NotActionsを使うレガシー方式は、設定が複雑で、権限の追跡も難しくなります。(Microsoft Learn)
| 方式 | 特徴 | 適するケース | 新規採用 |
|---|---|---|---|
| Protected Tables | テーブルを拒否既定で保護する | 少数の機微テーブルだけ厳格に制限したい | 推奨 |
| Granular RBAC | ABAC条件でテーブルまたは行を制限する | 部署、地域、顧客単位で細かく分けたい | 推奨 |
| 二重ロール方式 | ワークスペース用とテーブル用の2ロールを割り当てる | 既存環境の継続利用 | 原則として新規採用しない |
| レガシー方式 | query/<table>/readやNotActionsを使用する | 過去の構成との互換性維持 | 原則として新規採用しない |
| ワークスペース分割 | データを物理的に別ワークスペースへ保存する | 法規制や組織分離で強い境界が必要 | 要件に応じて継続 |
今回の要件では、一般利用者向けのロールに「このテーブル以外は許可」という複雑な条件を設定するより、機微テーブル自体をProtectedにして、必要な利用者にだけ追加権限を与える方が管理しやすくなります。
行単位の制御も必要な場合は、Granular RBACを併用します。Granular RBACでは、テーブル名だけでなく、ログの列と値を使った条件も設定できます。たとえば、部署コードやサブスクリプションID、アプリケーションIDが一致する行だけを閲覧させる設計が可能です。(Microsoft Learn)
設定変更前に既存RBACを棚卸しする
確認すべきスコープ
ワークスペースのIAM画面だけを確認しても、権限の全体像は把握できません。次のスコープを順番に確認します。
| スコープ | 主な確認対象 |
|---|---|
| 管理グループ | 全社共通のReader、Monitoring Reader、カスタムロール |
| サブスクリプション | Reader、Contributor、監視系の共通ロール |
| リソースグループ | 運用グループや委託先へ付与したロール |
| Log Analyticsワークスペース | Log Analytics Reader、Data Reader、カスタムロール |
| 個別テーブル | 従来方式のReader割り当て |
| ログ送信元リソース | リソースコンテキストでのログ閲覧権限 |
| PIM | 常時割り当てと有資格割り当て |
| Microsoft Entraグループ | ネストされたグループと間接メンバー |
| マネージドID | アラート、Logic Apps、Functions、Workbookなど |
特に確認したいのは、次の権限を含むロールです。
*/read
Microsoft.Insights/logs/*/read
Microsoft.OperationalInsights/workspaces/query/*/read
Microsoft.OperationalInsights/workspaces/tables/data/read
Microsoft.Insights/logs/data/read
Azure CLIでロール割り当てを出力する
次の例では、ワークスペースに対する直接割り当てと継承された割り当てをJSONへ出力します。
subscriptionId="<subscription-id>"
resourceGroupName="<resource-group-name>"
workspaceName="<workspace-name>"
workspaceId="/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.OperationalInsights/workspaces/$workspaceName"
az role assignment list \
--scope "$workspaceId" \
--all \
--include-inherited \
--query "[].{
principalName:principalName,
principalType:principalType,
role:roleDefinitionName,
scope:scope,
condition:condition,
conditionVersion:conditionVersion
}" \
--output json > log-analytics-role-assignments.json
カスタムロールの定義も別ファイルへ出力します。
az role definition list \
--custom-role-only true \
--output json > custom-role-definitions.json
出力したファイルでは、次の項目を確認します。
ActionsNotActionsDataActionsNotDataActionsAssignableScopes- ロール割り当ての
condition - ロール割り当ての
scope - 上位スコープからの継承有無
az role assignment listでは、--allと--include-inheritedを使って、リソーススコープの割り当てや継承された割り当てを確認できます。(Microsoft Learn)
制限付きロールを追加するだけでは不十分
Azure RBACとGranular RBACは、原則として権限を加算して評価します。
たとえば、同じユーザーに次の2つのロールが割り当てられているとします。
- テーブルを限定した条件付きロール
- 上位リソースグループから継承した広範な読み取りロール
この場合、条件付きロールが広いロールを打ち消すわけではありません。アクセス条件は明示的な拒否ではなく、そのロール割り当てから付与される権限を絞り込む仕組みです。別のロールから同じデータアクセス権限を得ていれば、制限を回避する結果になります。(Microsoft Learn)
そのため、棚卸しでは「新しく何を付与するか」だけでなく、どの広域ロールを削除または置き換えるかまで決めます。
機微テーブルだけを保護する設定手順
アクセスマトリクスを先に作る
設定を始める前に、少なくとも次の一覧を作成します。
| テーブル | 保護レベル | 通常閲覧者 | 特権閲覧者 | アラート利用 | 外部出力 |
|---|---|---|---|---|---|
Heartbeat | General | 運用チーム | - | あり | なし |
AzureActivity | General | 運用チーム | 監査担当 | あり | あり |
SigninLogs | Protected | なし | IAM、SOC | あり | 要確認 |
SecurityEvent | Protected | なし | SOC | あり | 要確認 |
| 機密カスタムテーブル | Protected | なし | 指定グループ | なし | なし |
テーブルごとに、Workbook、アラート、検索ジョブ、データエクスポート、API、Microsoft Sentinelなどから参照されていないかも確認します。
テーブルの保護レベルをProtectedへ変更する
Azureポータルでは、次の順に操作します。
- Log Analyticsワークスペースを開く
- 「設定」から「テーブル」を開く
- 対象テーブルのメニューから「テーブルの管理」を開く
- 保護レベルを
Protectedに変更する - 保存する
Azure CLIでは、REST APIを経由して設定できます。次は公式ドキュメントに基づく例です。
subscriptionId="<subscription-id>"
resourceGroupName="<resource-group-name>"
workspaceName="<workspace-name>"
tableName="SigninLogs"
apiEndpoint="https://management.azure.com"
path="/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName"
provider="Microsoft.OperationalInsights/workspaces/$workspaceName/tables/$tableName"
url="$apiEndpoint$path/providers/$provider?api-version=2025-02-01"
az rest \
--method patch \
--url "$url" \
--body '{"properties":{"protectionLevel":"Protected"}}'
APIバージョンは将来変更される可能性があるため、実行前にMicrosoftのREST APIリファレンスで最新バージョンを確認してください。テーブルの保護レベル変更には、Microsoft.OperationalInsights/workspaces/tables/protectionLevel/writeが必要です。(Microsoft Learn)
すべてのProtectedテーブルを閲覧させる場合
すべての保護テーブルを閲覧する必要があるSOC管理者や監査担当者には、組み込みロールのPrivileged Monitoring Data Readerを利用できます。
ただし、このロールをサブスクリプション全体へ常時割り当てると、対象範囲が広くなりすぎます。原則としてワークスペーススコープで割り当て、緊急対応者にはMicrosoft Entra PIMを使った期限付きアクセスを検討します。
assigneeObjectId="<group-or-user-object-id>"
az role assignment create \
--assignee-object-id "$assigneeObjectId" \
--role "Privileged Monitoring Data Reader" \
--scope "$workspaceId"
Privileged Monitoring Data Readerは、割り当てたスコープ内のすべてのProtectedテーブルへアクセスできるため、個別テーブルだけを許可したい利用者には使用しません。(Microsoft Learn)
特定のProtectedテーブルだけを閲覧させる場合
特定テーブルだけを許可する場合は、DataActionsを持つカスタムロールを作成し、ロール割り当て時にABAC条件を追加します。
カスタムロールの例は次のとおりです。
{
"Name": "Log Analytics Protected Table Reader",
"IsCustom": true,
"Description": "ABAC条件で許可されたProtectedテーブルだけを読み取るロール",
"Actions": [
"Microsoft.OperationalInsights/workspaces/read",
"Microsoft.OperationalInsights/workspaces/query/read"
],
"NotActions": [],
"DataActions": [
"Microsoft.OperationalInsights/workspaces/tables/data/read"
],
"NotDataActions": [],
"AssignableScopes": [
"/subscriptions/<subscription-id>"
]
}
ファイル名をprotected-table-reader.jsonとして保存し、ロールを作成します。
az role definition create \
--role-definition @protected-table-reader.json
次に、SigninLogsだけを許可するABAC条件を付けてロールを割り当てます。
assigneeObjectId="<group-object-id>"
condition="(
(
!(ActionMatches{'Microsoft.OperationalInsights/workspaces/tables/data/read'})
)
OR
(
@Resource[Microsoft.OperationalInsights/workspaces/tables:name] StringEquals 'SigninLogs'
AND
@Resource[Microsoft.OperationalInsights/workspaces/tables:protectionLevel] StringEquals 'Protected'
)
)"
az role assignment create \
--assignee-object-id "$assigneeObjectId" \
--assignee-principal-type Group \
--role "Log Analytics Protected Table Reader" \
--scope "$workspaceId" \
--condition "$condition" \
--condition-version "2.0"
複数テーブルを許可する場合は、テーブル名に対してForAllOfAnyValues:StringEqualsを使う方法があります。条件には、テーブル名だけでなくprotectionLevelがProtectedであることも含めます。(Microsoft Learn)
通常の運用ログは従来どおり共有する
一般運用ログを閲覧する利用者には、必要に応じてLog Analytics Data Readerなどのデータ読み取りロールをワークスペーススコープで割り当てます。
Protected Tablesを使用すれば、通常の利用者はGeneralテーブルを閲覧しながら、Protectedテーブルのデータ行にはアクセスできません。保護テーブルを閲覧する利用者にだけ、追加の特権ロールまたは条件付きロールを与えます。
この構成では、一般ログ用と機微ログ用のMicrosoft Entraグループを分けると管理しやすくなります。
grp-la-general-readers
grp-la-signinlogs-readers
grp-la-securityevent-readers
grp-la-protected-jit-admins
利用者個人へ直接ロールを付与するより、用途別グループに割り当て、メンバー変更でアクセスを管理する方が監査しやすくなります。
DataActionsOnlyモードで暗黙のアクセス経路を閉じる
Protected Tablesの効果をさらに明確にするには、ワークスペースのデータ認可モードをDataActionsOnlyへ変更します。
通常の構成では、ReaderやMonitoring Readerなど、コントロールプレーンのロールがログデータへの暗黙的な読み取りアクセスを提供する場合があります。DataActionsOnlyを有効にすると、ログデータへのアクセスはDataActionsだけで判定されます。(Microsoft Learn)
Azureポータルでは、次の順に設定します。
- Log Analyticsワークスペースを開く
- 「設定」から「プロパティ」を開く
- データ認可モードを「データアクションのみ」に変更する
Azure CLIでは次のように設定できます。
subscriptionId="<subscription-id>"
resourceGroupName="<resource-group-name>"
workspaceName="<workspace-name>"
apiEndpoint="https://management.azure.com"
path="/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName"
provider="Microsoft.OperationalInsights/workspaces/$workspaceName"
url="$apiEndpoint$path/providers/$provider?api-version=2025-02-01"
az rest \
--method patch \
--url "$url" \
--body '{"properties":{"features":{"dataAuthorizationMode":"DataActionsOnly"}}}'
ただし、DataActionsOnlyを最初に有効化すると、ReaderやMonitoring Readerなどの暗黙的なアクセスに依存していた利用者、Workbook、アプリケーションがログを読めなくなる可能性があります。
安全な順序は次のとおりです。
- 既存の閲覧者と実行IDを棚卸しする
- 必要な利用者へ
DataActionsを持つロールを割り当てる - Protectedテーブルを設定する
- 権限あり、権限なしの両方でテストする
- 最後に
DataActionsOnlyを有効化する
設定後に実施する動作確認
Protected Tablesでは、権限のない利用者がクエリを実行しても、必ずしも403エラーになるわけではありません。クエリ自体は成功し、結果が0件になる場合があります。
そのため、エラーの有無だけではアクセス制御を確認できません。(Microsoft Learn)
| テスト | 期待する結果 |
|---|---|
| 一般利用者がGeneralテーブルを検索 | データが表示される |
| 一般利用者がProtectedテーブルを検索 | クエリは成功するが0件 |
| 特権利用者がProtectedテーブルを検索 | データが表示される |
| 特定テーブル用ロールで別のProtectedテーブルを検索 | 0件 |
| ロール削除後に再検索 | Protectedテーブルは0件 |
| Workbookを実行 | 許可されたテーブルだけ表示 |
| アラートを実行 | マネージドIDの権限に応じて動作 |
| APIで検索 | 呼び出し元サービスプリンシパルの権限に応じて動作 |
テスト用のクエリは単純なもので構いません。
SigninLogs
| take 10
保護対象ではないテーブルも確認します。
Heartbeat
| take 10
ロール条件の反映には時間がかかる場合があります。Azure RBACの条件は通常短時間で反映されますが、最大数分程度待ってから再テストすることが推奨されています。(Microsoft Learn)
アラート、エクスポート、横断クエリへの影響
Protected Tablesを設定すると、Azureポータルからの手動検索だけでなく、自動処理への影響も確認する必要があります。
ログアラート
保護テーブルを参照するアラートでは、マネージドIDを使用し、そのIDへ必要なロールとABAC条件を付与します。
ユーザーには権限があっても、アラートの実行IDに権限がなければ、アラートは保護テーブルのデータを取得できません。Microsoftの公式ドキュメントでは、保護テーブルへアクセスするアラートにマネージドIDを使用することが案内されています。(Microsoft Learn)
データエクスポートと検索ジョブ
保護テーブルからデータを移動する処理では、対象テーブルに対する十分なアクセスが必要です。
次の処理を利用している場合は、事前検証が必要です。
- データエクスポート
- 検索ジョブ
- 共有処理
- 長期保存データの復元
- Logic AppsやFunctionsによる定期取得
- 外部SIEMへの転送
- バックアップ処理
保護テーブルの一部しか閲覧できない利用者や実行IDでは、データ移動を伴う処理が失敗する場合があります。(Microsoft Learn)
クロスワークスペースクエリ
プレビュー期間中は、workspace()やapp()を使うクロスワークスペースクエリでProtected Tablesがサポートされていません。
複数ワークスペースを横断するWorkbookや調査クエリが業務上必須の場合は、次のいずれかを検討します。
- 横断クエリの対象テーブルを当面
Generalのままにする - 機微データ用の別ワークスペースを維持する
- Protected Tablesの正式リリースや制約変更を待つ
- クエリやデータ配置を再設計する
また、Protectedに設定しても、テーブル名、列名、データ型などのスキーマ情報は表示されます。データ行は保護されますが、テーブルの存在自体を秘匿する機能ではありません。(Microsoft Learn)
リソースコンテキストのアクセスにも注意する
Log Analyticsには、ワークスペースからログを検索する方法と、VMやWeb Appsなどの各Azureリソースからログを開く方法があります。
Granular RBACだけで制限を設計する場合、ワークスペースのアクセス制御モードが「リソースまたはワークスペースのアクセス許可を使用する」になっていると、リソース側の読み取り権限によってログへアクセスでき、ワークスペース側のABAC条件が意図どおり適用されない場合があります。
リソースコンテキストでもGranular RBAC条件を確実に適用する場合は、関連ワークスペースのアクセス制御モードと、リソース側のMicrosoft.Insights/logs/*/readを確認します。(Microsoft Learn)
失敗しやすい設計と改善方法
条件付きロールを追加しただけで完了とする
上位スコープに広いロールが残っていると、条件が実質的に無効になることがあります。
改善方法: 制限対象ユーザーについて、サブスクリプション、リソースグループ、ワークスペース、リソースの全スコープを確認します。
Privileged Monitoring Data Readerを広範囲に付与する
このロールは、割り当てたスコープ内のすべてのProtectedテーブルへアクセスできます。
改善方法: ワークスペーススコープで付与し、個別テーブルだけ必要な利用者にはABAC条件付きカスタムロールを使用します。
DataActionsOnlyを先に有効化する
既存利用者や自動処理が、暗黙的なログ読み取り権限に依存している可能性があります。
改善方法: 先にLog Analytics Data Readerなどのデータプレーンロールを割り当て、動作確認後に切り替えます。
403エラーだけを確認する
権限のないProtectedテーブルへのクエリは、エラーではなく0件になることがあります。
改善方法: 権限あり、権限なし、Generalテーブルの3パターンで結果件数を確認します。
人間の利用者だけを棚卸しする
アラート、Workbook、API、Logic Appsなどは、ユーザーとは別のマネージドIDやサービスプリンシパルで実行されます。
改善方法: 人、グループ、サービスプリンシパル、マネージドIDを同じアクセスマトリクスで管理します。
テーブル名だけで保護対象を決める
標準的なテーブルでも、アプリケーションの実装によって個人情報や秘密情報が保存されていることがあります。
改善方法: KQLで列ごとのデータ例を確認し、ログ設計、マスキング、収集時変換も含めて見直します。
安全に移行するための展開順序
| 段階 | 実施内容 | 完了条件 |
|---|---|---|
| 棚卸し | RBAC、グループ、実行ID、参照機能を確認 | 権限一覧と利用一覧が完成 |
| 分類 | GeneralとProtectedに分ける | テーブル台帳が完成 |
| 検証 | 検証用テーブルまたは1テーブルで試行 | 権限あり・なしの動作確認完了 |
| ロール移行 | DataActionsを持つロールへ置き換える | 一般利用者のログ閲覧を確認 |
| テーブル保護 | 機微テーブルをProtectedへ変更 | 一般利用者には0件となる |
| 自動処理対応 | アラートやAPIの実行IDへ権限付与 | 自動処理が正常動作 |
| 強化 | DataActionsOnlyを有効化 | 暗黙のアクセス経路を解消 |
| 整理 | 不要な旧ロールを削除 | 広域ロールとレガシー設定を解消 |
| 監査 | Activity Logとクエリ監査を確認 | 変更者と利用状況を追跡可能 |
ロール割り当ての変更はAzure Activity Logへ記録されます。また、Log Analyticsワークスペースの診断設定を有効にしてLAQueryLogsを収集すると、ConditionalDataAccess列から、ABAC条件が適用されたクエリを確認できます。(Microsoft Learn)
まず実施すべきこと
Log Analytics権限の再設計では、いきなりProtected TablesやDataActionsOnlyを有効にするのではなく、次の順序で着手します。
- ワークスペースのロール割り当てを継承込みで出力する
- カスタムロールの
ActionsとDataActionsを確認する - テーブルごとにGeneralかProtectedかを分類する
- アラート、Workbook、API、エクスポートの利用状況を確認する
- 検証対象の機微テーブルを1つ選ぶ
- 一般利用者用と特権利用者用のテストグループを作る
- テーブルをProtectedにして、権限あり・なしの双方で確認する
- 問題がなければ対象テーブルを段階的に増やす
- 最後にDataActionsOnlyへの移行を検討する
今回のように「同じワークスペースを共有しながら、一部の機微テーブルだけを制限する」場合は、Protected Tablesをアクセス境界にし、ABAC条件付きロールを例外許可として使う構成が分かりやすい設計です。
一般ログを共有する利便性を残しつつ、機微ログへのアクセスを限定できます。ただし、プレビュー機能であること、既存RBACが加算されること、自動処理やクロスワークスペースクエリに制約があることを踏まえ、1テーブルずつ段階的に導入することが重要です。

コメント