Skip to content

Setup: tenant settings, identity, and provisioning

Do these once, in order, before running the collector.

1. Fabric / Power BI tenant settings (Admin portal)

Setting Where Why
Fabric data agent Admin portal → Tenant settings Allows FDA to exist/run
Power BI semantic models via XMLA endpoints Tenant settings → Integration NL2DAX executes over XMLA
Cross-geo processing / storing for AI Tenant settings → AI and Copilot Required by FDA
Allow Microsoft Purview to secure AI interactions Tenant settings → Information protection Enables FDA audit/DSPM capture (preview)
Service principals can use Fabric APIs Tenant settings → Developer settings Collector SP calls Fabric/Kusto

2. Workspace monitoring (the GA DAX source)

On the workspace that hosts the semantic model the FDA queries:

  1. Workspace → Settings → Monitoring → Enable. This provisions a read-only monitoring Eventhouse (KQL DB).
  2. Confirm the SemanticModelLogs table populates (ask a question through the FDA, then query it).
  3. Note the monitoring KQL database Query URI — the collector reads executed DAX from here.

You may host the observability tables in this same Eventhouse or a dedicated one. A dedicated observability Eventhouse is recommended so retention/permissions are independent of the monitoring store.

3. Provision the observability Eventhouse

  1. In your observability workspace: + New item → Eventhouse, name it e.g. FDA_Observability_EH.
  2. Open its KQL database, note the Query URI (looks like https://<cluster>.<region>.kusto.fabric.microsoft.com + database name). The WinForms app and collector both use it.
  3. Run fabric/kql/01_tables.kql, then fabric/kql/02_policies.kql in the query editor.

4. Register the collector app (Entra ID)

Create one app registration, e.g. FDA-Observability-Collector.

API permissions (application, admin-consented):

API Permission Purpose
Microsoft Graph AiEnterpriseInteraction.Read.All Export Copilot prompt/response text
Microsoft Graph GroupMember.Read.All Expand FDA_USER_GROUP_ID into the per-user Graph export set (only if using group expansion)
Office 365 Management APIs ActivityFeed.Read Pull CopilotInteraction audit records
(Power BI Service) Tenant.Read.All (optional) Resolve workspace/model names

Fabric data-plane access: add the app's service principal as Member/Contributor on the observability workspace so it can ingest into the Eventhouse, and grant it Database Ingestor + Database Viewer on the KQL database. Database Ingestor is what lets the collector use queued ingestion (USE_QUEUED_INGESTION=True, the default — it streams via the DM endpoint https://ingest-<cluster>… and scales to large batches). Also grant Viewer on the monitoring KQL database (to read executed DAX).

Choosing the Graph user set: set FDA_USERS to an explicit UPN list, or set FDA_USER_GROUP_ID to an Entra group object id and the collector expands its transitive members automatically (de-duplicated, paged). If both are set they are merged. Put your FDA end users in a security group and point the collector at it so the set stays current without redeploying the notebook.

Create a client secret (or, preferred, a certificate) and store it in the workspace's Key Vault-backed connection or a Fabric notebook secret. Never hardcode it.

5. Office 365 Management API subscription

The audit content feed must be subscribed once per content type. The collector calls POST .../subscriptions/start?contentType=Audit.General automatically on first run, but the SP needs ActivityFeed.Read. Verify the tenant's unified audit log is turned on (Purview → Audit).

6. WinForms app identity

The review app uses interactive AAD (the reviewer's own identity) via MSAL — no secret on the client. Register a second public client app, e.g. FDA-Observability-Review, with:

  • Platform: Mobile and desktop, redirect URI http://localhost (and https://login.microsoftonline.com/common/oauth2/nativeclient).
  • Delegated permission: the Kusto/Fabric scope https://kusto.fabric.microsoft.com/user_impersonation (the app requests https://<cluster>.kusto.fabric.microsoft.com/.default at runtime).
  • Reviewers must have Viewer on the observability KQL database.

Record the Client ID and Tenant ID; you enter them in the app's Configuration dialog (or appsettings.json).

7. Quick verification

# After schema + collector run, in the KQL query editor:
FdaInteractions | take 50
FdaInteractions | summarize count() by MatchConfidence, bin(Timestamp, 1h)

If FdaInteractions has rows with GeneratedDax populated and MatchConfidence != "Unmatched", the pipeline works.