How it works
The Fabric SQL endpoint is a SQL Server-compatible endpoint. Bag of words acquires an Entra access token, then connects with the Microsoft ODBC Driver 18 for SQL Server using that token (Encrypt=yes, TrustServerCertificate=no).
- Service principal — a client-credentials token for
https://database.windows.net/.default. - Per-user — a delegated token for
https://database.windows.net/user_impersonation offline_access, obtained by user sign-in or by an on-behalf-of exchange from the user’s Entra login.
INFORMATION_SCHEMA.COLUMNS for the configured database, skips the sys, INFORMATION_SCHEMA, and queryinsights schemas, and — importantly — filters to objects the connecting principal actually has SELECT on (HAS_PERMS_BY_NAME). INFORMATION_SCHEMA alone lists objects whose existence is visible, which is broader than read access, so without this filter a principal with DENY SELECT would still see tables listed. Table and column descriptions come from MS_Description extended properties when readable; otherwise a simpler introspection runs.
Each object is exposed to the agent as schema.table.
Fabric SQL endpoints are serverless and can be slow to answer the first connection after the capacity has been idle. Bag of words allows a 60-second login timeout and retries transient connection failures up to three times, so a cold start surfaces as a slow first query rather than an error.
Before you start
- A Fabric Warehouse or Lakehouse, and its SQL endpoint hostname (for example
abc123.datawarehouse.fabric.microsoft.com) — copy it from the item’s settings in Fabric. - Permission to create an app registration in Microsoft Entra ID, and an administrator who can grant admin consent.
- The identity you connect with needs access to the workspace and read access to the warehouse or lakehouse. Discovery only lists objects it holds
SELECTon, so missing grants show up as missing tables rather than as an error. - The Microsoft ODBC Driver 18 for SQL Server must be present on the backend host. The official Bag of words container image already includes it.
Step 1 — Register an Entra ID application
In the Azure Portal → Microsoft Entra ID → App registrations → New registration.1
Create the app registration
Name it (for example
Bag of words - Fabric). Under Supported account types, choose Accounts in this organizational directory only unless you specifically need multi-tenant.2
Copy the Tenant ID and Client ID
From the app’s Overview page, copy the Directory (tenant) ID and the Application (client) ID.
3
Create a client secret
Certificates & secrets → New client secret. Copy the secret value immediately — it is shown only once.
4
Add the Azure SQL Database permission
API permissions → Add a permission → APIs my organization uses → Azure SQL Database, then add the delegated user_impersonation permission and grant admin consent for the directory. This is what makes the issued token acceptable to the Fabric SQL endpoint.
5
(Per-user only) Add the redirect URI
Under Authentication, add a Web redirect URI:Keep offline_access among the delegated scopes so the token can be refreshed without asking the user to sign in again.
Step 2 — Grant the identity access in Fabric
Add the service principal (or the security group containing it) to the Fabric workspace, and grant it read access to the warehouse or lakehouse you want to query. Do the same for the user accounts that will sign in per-user.Connect in Bag of words
Go to Data Sources → Add data source → Microsoft Fabric and fill in the form.
Test Connection acquires a token, opens the ODBC connection, and runs
SELECT 1.
Authentication modes
Service Principal (Azure AD)
One shared application identity discovers and queries Fabric for everyone. Simplest to operate; every user sees the same tables. System scope.
Sign in with Microsoft
Each user signs in with their own Microsoft account. Discovery and queries run with that user’s own permissions on the warehouse. Per-user scope.
Per-user authentication on database-style connectors requires an Enterprise license. See Authentication.
Querying
Fabric uses T-SQL, and the agent writes it accordingly:SELECT TOP n rather than LIMIT, + for string concatenation, GETDATE(), ISNULL()/COALESCE(), DATEPART()/DATEADD()/DATEDIFF(), and square brackets around reserved words. Tables are addressed as schema.table.
Troubleshooting
Login error 18456 when a token was obtained
Login error 18456 when a token was obtained
The token has the wrong audience. Add the Azure SQL Database → user_impersonation delegated permission to the app registration and grant admin consent; a Fabric/Power BI API scope produces tokens the SQL endpoint rejects.
Login timeout expired (HYT00) on the first attempt
Login timeout expired (HYT00) on the first attempt
A cold-starting serverless endpoint. Bag of words already retries with a 60-second login timeout; if it persists across retries, the endpoint or the capacity is unavailable rather than idle.
The connection tests fine but shows zero tables
The connection tests fine but shows zero tables
Discovery lists only objects the identity has
SELECT on. Grant the service principal (or user) access to the workspace and read access on the warehouse/lakehouse, and check the schema field is not excluding them.An admin sees zero tables on a per-user connection they just created
An admin sees zero tables on a per-user connection they just created
On a connection that runs queries with each user’s own credentials, the creating admin has no delegated token yet, so the table list is empty and Reload tables cannot help. Click Connect on the data source and sign in with Microsoft; the tables appear once the token is stored. The same applies to any member opening the tables view before connecting.
Descriptions are missing from the schema
Descriptions are missing from the schema
Table and column comments come from
MS_Description extended properties. When that enriched query fails — commonly on a low-privilege principal — discovery falls back to names and data types only.Reference
- Service principal token scope:
https://database.windows.net/.default - Per-user (delegated) scope:
https://database.windows.net/user_impersonation offline_access - OAuth redirect URI:
https://<your-bow-host>/api/connections/oauth/callback
