All modern AI solutions eventually need agents to query or mutate data in Microsoft SQL. Deciding how to do this safely, for example, how to handle NL2SQL, will be an important choice. Next come the twins: authentication and authorization. In this article, we discuss pass-through agentic authentication with the express goal of ensuring operational logs reflect not the agent, not the MCP server, but the user. In future articles, we will discuss the broad array of authorization controls available in Data API builder (DAB) 2.0 with SQL MCP Server.
There are three approaches to SQL authentication in SQL MCP Server.
The first is a username and password. Although it is slowly waning in popularity, it remains a viable option for certain customers. In this case, the audit logs show the identity provided through the connection string, not the user invoking the operation.
User -(any authentication approach)-> Agent
Agent -(any authentication approach)-> MCP server
MCP server -(passes username and password)-> SQL db
SQL db -(logs username as operator)-> Logs
The second is managed identity (MI), which eliminates the password but produces the same logging outcome: the logs identify the application, not the user invoking the data operation.
User -(any authentication approach)-> Agent
Agent -(any authentication approach)-> MCP server
MCP server -(passes MCP server identity)-> SQL db
SQL db -(logs MCP server identity as operator)-> Logs
The third approach is On-Behalf-Of (OBO), also known as pass-through authentication, using Microsoft Entra ID. It is more sophisticated to set up, but when enabled, services exchange the incoming user token for downstream tokens, forwarding them from service to service.
User -(authenticates with Microsoft Entra ID)-> Agent
Agent -(forwards user token)-> MCP server
MCP server -(exchanges token and connects as user)-> SQL db
SQL db -(logs user as operator)-> Logs
Ultimately, Azure SQL authenticates the actual calling user, not the application, not the agent, and not the MCP server. When a query or mutation occurs in the database, the resulting audit logs identify the user who invoked the operation.
Data API builder (DAB) 2.0 with SQL MCP Server OBO support
Data API builder (DAB) 2.0 with SQL MCP Server supports On-Behalf-Of (OBO) authentication for Microsoft SQL databases using Microsoft Entra ID. When enabled, it changes your audit story for agentic apps. Instead of asking “which service queried the database?” SQL can answer “which user caused this query?” Let’s take a look.
Agents need accountability
AI agents can reason, plan, and call tools. But when an agent reaches into production data, the enterprise question is not only “did the agent have permission?” The better question is “whose permission did the agent use?”
SQL MCP Server exposes SQL tables, views, and stored procedures through MCP tools. This gives agents a controlled way to interact with data without exposing the database directly. With OBO, that controlled path can also preserve the signed-in user’s identity all the way to Azure SQL.
Configuring OBO
OBO is configured in the DAB data source. The connection string must be a bare Azure SQL connection string. Don’t include User ID, Password, or Authentication. DAB injects the per-user access token when it opens the SQL connection.
{
"data-source": {
"database-type": "mssql",
"connection-string": "@env('MSSQL_CONNECTION_STRING')",
"user-delegated-auth": {
"enabled": true,
"provider": "EntraId",
"database-audience": "https://database.windows.net"
}
}
}
Because each user receives a distinct database connection, caching might be an initial concern. However, DAB has a hard configuration validation rule that makes response caching and OBO/user-delegated authentication mutually exclusive. The validator rejects any configuration that enables both simultaneously. The OBO token cache itself is scoped per user.
Validating the identity
The online documentation OBO sample uses a small WhoAmI view to prove the point. This view returns the identity SQL sees on the active connection.
CREATE VIEW [dbo].[WhoAmI] AS
SELECT SUSER_NAME() AS [UserName];
Expose it through DAB for authenticated users.
{
"WhoAmI": {
"source": {
"object": "dbo.WhoAmI",
"type": "view",
"key-fields": [ "UserName" ]
},
"rest": {
"enabled": true
},
"permissions": [
{
"role": "authenticated",
"actions": [ { "action": "read" } ]
}
]
}
}
With this, an authenticated request to WhoAmI returns the user principal name SQL sees. In the app, the user signs in to the browser with Microsoft Entra ID, sends a bearer token to Data API builder (DAB) 2.0 with SQL MCP Server, and DAB exchanges that token for an Azure SQL token for the signed-in user.
const headers = await getAuthHeaders();
const response = await fetch(`${API_URL}/api/WhoAmI`, {
method: "GET",
headers
});
const payload = await response.json();
const sqlUserName = payload.value[0].UserName;
console.log(`SQL sees this request as: ${sqlUserName}`);
The sample’s UI displays the result as “SQL Server sees you as: [user@example.com](mailto:user@example.com).” The README describes the point plainly: SQL sees the real user, not a service account.
What this means for MCP
One configuration for all the endpoints
The same DAB runtime can expose REST, GraphQL, and MCP.In the OBO sample, MCP is enabled with the /mcp path in the same configuration that enables Entra ID authentication and user-delegated auth.
A conceptual MCP tool request can read the same WhoAmI entity.
{
"tool": "read_records",
"arguments": {
"entity": "WhoAmI"
}
}
The agent is still using a tool. DAB is still enforcing its entity permissions. Azure SQL still authenticates the user behind the request.
That is the key distinction.
The agent performs the action, but SQL records the user context that authorized the action.
Auditing the result
Azure SQL auditing tracks database events and can write them to Blob storage, Event Hubs, or Log Analytics. The audit schema includes fields such as database_principal_name, server_principal_name, statement, and obo_middle_tier_app_id, which identifies the middle-tier app that connected using OBO access.
In Log Analytics, a simple query can show who SQL saw.
AzureDiagnostics
| where Category == "SQLSecurityAuditEvents"
| where database_name_s == ""
| project
event_time_t,
action_name_s,
database_principal_name_s,
server_principal_name_s,
obo_middle_tier_app_id_s,
statement_s
| order by event_time_t desc
That gives you a better audit frontier for agentic systems. You can see the user, the SQL action, the statement, and the middle-tier app involved in the OBO path.
Conclusion
OBO pass-through authentication makes Data API builder (DAB) 2.0 with SQL MCP Server more than a convenient bridge between agents and data. It makes the bridge accountable. For simple apps, connecting with a managed identity or service credential can be enough. For enterprise agents touching sensitive data, the database often needs to know the real caller. With SQL MCP Server and DAB OBO authentication, Azure SQL can audit the signed-in user behind the agent action. That means your agent can call tools, DAB can enforce permissions, and SQL can still answer the most important audit question: who did this?
0 comments
Be the first to start the discussion.