Fabric data agent governance for query language choice
Fabric Data Agents Choosing Query Language by Context: The Governance Implications
Fabric data agents just turned query-language choice into a governance problem.
If your agent can decide between a semantic model, SQL, KQL, a notebook, or an external tool, you do not have a convenience feature. You have a control plane.
Microsoft has already made the direction obvious. Fabric data agent is described by Microsoft as a generally available capability for conversational Q&A with generative AI, though the feature is still marked as preview in parts of the documentation, and Microsoft explicitly calls out governance as part of the concept per the Fabric data agent docs. That matters because the same product guidance says the agent can generate and run code against data sources and use multiple tools, including Fabric sources, external sources, and Microsoft Graph per the create data agent guidance.
That is the whole ballgame.
The question is not “can the user ask in natural language?” The question is “which execution path is the agent allowed to take, under which policy, with which audit trail, against which semantic boundary?”
I had a customer in Q1 walk through a finance KPI mismatch where 14 regional leaders got two different gross margin answers from the same agent because one path hit a curated semantic model and another path generated direct SQL against a warehouse table with a different returns filter. That was not an AI hallucination story. That was a governance design failure.
Why query-language choice is now a governance decision
A lot of teams still treat language selection as implementation detail. DAX here, SQL there, KQL for telemetry, Python when the prompt gets weird. Fine for a human analyst. Dangerous for an agent.
Once the agent is free to choose the path, governance scope expands fast:
- semantic definitions may or may not be honored
- permissions may be enforced through different surfaces
- lineage may stop at different layers
- outbound access may suddenly matter
- generated code becomes part of the evidence chain
That last point gets ignored until audit shows up.
Here is the mental model I use with teams: the prompt is not the execution plan. Policy has to sit between the prompt and the path selection.

Look at the control points in that flow. The useful pattern is not “agent chooses best tool.” The useful pattern is “agent chooses from an approved set after governance checks.” If you do not insert that gate, you are delegating policy to model behavior.
Fabric already signals a multi-path execution model
Microsoft is not hiding this. Copilot in Fabric is positioned around authoring queries in the context that best fits the workflow, whether that means a queryset or tuning visuals directly in dashboards per the Copilot in Fabric overview. That is product direction, not accident.
Operationally, “best context” means very different things depending on the path:
- A semantic model path usually carries curated business meaning.
- A SQL path gets you closer to physical tables, joins, and engine behavior.
- A KQL path often prioritizes event and telemetry exploration.
- A notebook or Python tool path widens the execution and review boundary.
- An external tool path turns network posture into part of your data governance story.
I wrote about this from the API angle in Fabric Data Agent API Turns Governance Into Product Design. The same principle applies here: once tool choice becomes dynamic, architecture and governance collapse into the same decision.
The governance surface widens across semantic, SQL, KQL, and notebooks
Here is the blunt version.
Semantic model is the safest default for business Q&A
If the question is “gross margin by region last quarter,” I want the agent biased toward the semantic model first. That path is where your governed measures, shared definitions, row-level controls, and business naming conventions are most likely to live.
That does not make semantic models magic. It makes them the most business-governed starting point.
SQL and KQL are different beasts
Direct SQL is powerful, but it is also where agents can bypass curated meaning and operate closer to raw structures. Same with KQL when the question drifts into event data or operational telemetry. Those paths are valid. They just need different guardrails because they expose different failure modes.
An agent that answers from a semantic measure called Gross Margin is not equivalent to an agent that writes SQL over FactSales, DimDate, and a hand-rolled cost calculation. Same answer shape, different governance reality.
Notebooks and Python tools widen the blast radius
The Fabric guidance matters here because the agent can generate and run code. Once generated code enters the path, your review boundary expands from “what data was read” to “what code was executed, which tool was invoked, and what outbound routes were available.”
This is exactly why I keep pushing teams to treat observability as a first-class design input, not a logging afterthought. I laid that out in How AI agent observability should influence Fabric data product design.
A simple example helps. This kind of audit record is the minimum bar I want to see for every governed agent interaction:
# Pseudo-audit record for a Fabric data agent execution path
from dataclasses import dataclass, asdict
from datetime import datetime
import json
@dataclass
class AgentAuditRecord:
prompt: str
selected_tool: str
execution_path: list[str]
source_objects: list[str]
policy_decision: str
timestamp_utc: str
record = AgentAuditRecord(
prompt="Show gross margin by region for the last quarter.",
selected_tool="DAX",
execution_path=["intent:analytics", "policy:semantic-model-preferred", "tool:dax"],
source_objects=["SemanticModel/Sales", "Table/Date", "Measure/Gross Margin"],
policy_decision="allowed",
timestamp_utc=datetime.utcnow().isoformat() + "Z",
)
print(json.dumps(asdict(record), indent=2))
What should you notice? The prompt alone is useless for governance. The selected tool, execution path, source objects, and policy decision are the evidence. If you cannot reconstruct those fields after the fact, you are not running a governed agent.
Ontology raises the bar for what governed answers should mean
This is where the conversation gets more interesting.
Microsoft Fabric IQ is part of Microsoft IQ, which Microsoft describes as an enterprise intelligence layer, and the ontology item in Fabric IQ preview is meant to represent enterprise vocabulary and a semantic layer that unifies meaning across domains and OneLake sources per the Fabric IQ overview and the ontology overview.
That is a big deal.
If Microsoft is building toward a shared business model across teams, agents, and applications, then agent autonomy should not casually bypass that layer whenever a lower-level path looks easier. The existence of ontology changes the standard. A “good” answer is no longer just factually plausible. A good answer is aligned to governed enterprise meaning.
That is why I think query-language policy belongs in the governance stack, not in UX preferences.
A practical rule set looks like this:
- executive BI and board metrics: semantic-first, no exceptions without approval
- operational analytics: SQL allowed against approved warehouses and lakehouses
- telemetry and incident analysis: KQL allowed for approved event workloads
- notebook or Python tool use: explicit exception path, extra logging, tighter review
- external connectors and Graph access: workspace-level approval only
If that sounds strict, good. Governance should be strict where meaning matters.
Least privilege now includes tool choice and outbound path control
Least privilege used to mean “who can read which dataset.” That is still necessary. It is no longer sufficient.
The Fabric data agent guidance says outbound calls to external data sources are governed by the workspace’s data connection rules, and requests to Microsoft Graph are also subject to workspace data connection rules when outbound access protection is enabled, with explicit allow requirements in that case per the data agent creation guidance.
That means your security model now includes:
- which tools the agent may invoke
- which connectors are allowed from that workspace
- whether outbound access is restricted or open
- whether Graph calls are explicitly permitted
- which path is allowed for which class of question
I would not let an agent-enabled workspace drift into “open outbound” and call that acceptable because the datasets themselves are permissioned. That is not least privilege. That is partial privilege with wishful thinking.
Here is a lightweight PowerShell-style posture check I use to explain the point to platform teams:
# Validate outbound access posture for agent-enabled workspaces
param(
[string[]]$WorkspaceNames = @("Finance-Agents", "Sales-Agents")
)
$workspacePosture = @(
[pscustomobject]@{ Name = "Finance-Agents"; AgentEnabled = $true; OutboundAccess = "Restricted"; ApprovedConnectionRules = $true }
[pscustomobject]@{ Name = "Sales-Agents"; AgentEnabled = $true; OutboundAccess = "Open"; ApprovedConnectionRules = $false }
)
$workspacePosture |
Where-Object { $_.Name -in $WorkspaceNames -and $_.AgentEnabled } |
Select-Object Name, OutboundAccess, ApprovedConnectionRules,
@{Name="Compliant";Expression={ $_.OutboundAccess -eq "Restricted" -and $_.ApprovedConnectionRules }} |
Format-Table -AutoSize
This is illustrative, not production automation. What matters is the operating model behind it: agent-enabled workspaces should have a visible outbound posture, approved connection rules, and a compliance check you can review in minutes.
Failure modes you should expect before you scale
Teams do not need more vague “AI risk” lists. They need the actual failure modes.
1) Inconsistent answers across paths
Same user question, different result, because one path uses governed measures and another uses generated SQL or KQL with different assumptions.
2) Bypassed semantic definitions
The agent answers correctly enough to pass casual inspection, but it skipped the curated business layer that finance, sales, or operations actually signed off on.
3) Audit gaps
You captured the conversation transcript but not the exact tool invocation, generated code, source objects, or outbound call. That is not auditability. That is theater.
4) Cost and performance surprises
Agents optimize for getting an answer. Enterprises need optimization for approved answers, predictable cost, and acceptable latency. Those are not the same objective function.
A compact policy gate is enough to show how deterministic this can be:
# Minimal policy evaluator for approved tools and source sensitivity
def evaluate_policy(selected_tool: str, source_objects: list[str]) -> dict:
sensitive = any("HR" in obj or "PII" in obj for obj in source_objects)
approved_tools = {"SQL", "DAX", "KQL"}
if selected_tool not in approved_tools:
return {"decision": "deny", "reason": "tool_not_approved"}
if sensitive and selected_tool == "Python":
return {"decision": "deny", "reason": "sensitive_data_python_blocked"}
return {"decision": "allow", "reason": "policy_pass"}
result = evaluate_policy(
selected_tool="DAX",
source_objects=["SemanticModel/Finance", "Table/Region", "Measure/Net Sales"],
)
print(result)
The point is not the toy evaluator. The point is that tool approval and source sensitivity can be treated as policy inputs before execution, not debated after the answer ships to a VP.
What deterministic control should look like in Fabric
If I were standing up this pattern today, I would implement five controls immediately.
1) Define path tiers by use case
Do not let every prompt choose from every tool.
- Tier 1: semantic-only for executive and regulated reporting
- Tier 2: semantic + SQL for approved analyst workflows
- Tier 3: KQL for telemetry and operations
- Tier 4: notebook/Python/custom tools only with explicit exception handling
2) Make language selection policy-driven
This is the core design move. Put policy between intent classification and tool selection.
# Context-based query language selection with simple governance gates
def choose_language(prompt: str, sources: list[str], outbound_allowed: bool) -> str:
text = prompt.lower()
if "telemetry" in text or any("eventhouse" in s.lower() for s in sources):
return "KQL"
if "measure" in text or any("semanticmodel" in s.lower() for s in sources):
return "DAX"
if "join" in text or any("warehouse" in s.lower() or "lakehouse" in s.lower() for s in sources):
return "SQL"
if outbound_allowed and "python" in text:
return "Python"
return "SQL"
prompt = "Use the semantic model measure for revenue by month."
sources = ["Workspace/Finance", "SemanticModel/Revenue"]
print({"prompt": prompt, "selected_language": choose_language(prompt, sources, outbound_allowed=False)})
Again, this is illustrative. What to observe is the order of operations: detect context, inspect available sources, check outbound posture, then choose from an approved language set. That is governance by design.
3) Require execution-path observability
For every answer, capture:
- prompt
- selected tool or language
- policy decision
- source objects touched
- whether semantic or ontology-backed assets were used
- outbound calls, if any
- generated code artifact when applicable
4) Treat new tools and MCP-style integrations as control-plane changes
The Power BI MCP servers are in preview and expose specialized tools through Model Context Protocol for agents to interact with Power BI per the MCP servers overview. That is exactly the kind of feature teams love to enable casually and regret later. New tool surfaces change what the agent can do. That is a governance review event, full stop.
I touched the same issue from the metadata angle in Microsoft Fabric Graph Just Redefined AI Data Context. More context is useful. More context also expands the control plane.
5) Review outbound posture at the workspace level
Agent controls do not stop at the dataset boundary. The workspace is now part of your trust boundary.
The executive stance
Here is my position.
Agent autonomy is valuable only when bounded by deterministic controls. In Fabric, query-language selection is not a UX flourish. It is a policy decision about meaning, access, lineage, and accountability.
If your team cannot answer these five questions clearly, you are not governing the agent yet:
- Which execution paths are allowed for this use case?
- When must the agent stay inside semantic or ontology-backed meaning?
- Which outbound routes and tools are permitted from this workspace?
- What evidence do you retain for every answer?
- Who approves a new tool, connector, or agent capability?
That is the standard I would hold.
Rate your team’s current state on execution-path governance for Fabric agents from 1 to 5.
#MicrosoftFabric #Datagovernance #EnterpriseAI
Sources & References
- Fabric data agent creation - Microsoft Fabric
- What is Fabric IQ? - Microsoft Fabric
- What Is Ontology (Preview)? - Microsoft Fabric
- Introduction to end-to-end analytics using Microsoft Fabric - Training
- Create a Fabric data agent - Microsoft Fabric
- Overview of Copilot in Fabric - Microsoft Fabric
- Study guide for Exam AB-620: Designing and Building Integrated AI Solutions in Copilot Studio
- What are the Power BI MCP servers? - Power BI
- What's new in Copilot Studio - Microsoft Copilot Studio
- Study guide for Exam AB-100: Agentic AI Business Solutions Architect
Try it yourself
Run this tutorial as a Jupyter notebook: Download runbook.ipynb (24 cells, 23 KB).