Power Apps to Azure SQL with Entra ID, not a shared connection: the secure setup
The SQL Server connector signs in four ways and only Microsoft Entra ID Integrated tells the database who the user is; a shared SQL login is client-side security, whatever filters the app has. The setup: an Entra admin on the server, database users from the external provider, row-level security on the signed-in name, secure implicit connections for the apps that must keep a login, and the delegation limits to design around.
Data & storageFix a problem9 min read
When a canvas app reads Azure SQL, the question that matters is who the database thinks is asking. With the Power Apps SQL Server connector set to Microsoft Entra ID Integrated, it's the person using the app, and the database can filter, deny and audit by that name. With a SQL login the maker typed in, it's always the maker, and every filter the app applies is a courtesy the user can walk around. Microsoft's own guidance calls the second pattern client-side security and says plainly that you can't rely on it. This guide sets up the first pattern end to end, explains what to do with the apps that genuinely need a login, and finishes with the delegation limits that shape the design.
Four ways to sign in, two kinds of security
| Authentication type in the connector | How it's shared | Who the database sees |
|---|---|---|
| Microsoft Entra ID Integrated | Explicit: each user signs in as themselves | The user |
| SQL Server Authentication | Implicit, or secure implicit | The login the maker entered |
| Windows Authentication (through a gateway) | Implicit, or secure implicit | The Windows account the maker entered |
| Windows Authentication (non-shared) | Explicit | The user |
An explicit connection authenticates the person using the app. An implicit one reuses the credentials the maker gave when the connection was made, so every user is the maker as far as SQL is concerned. Before January 2024 an implicit connection was also handed to every user the app was shared with, and they could build their own app on it and see everything the login could see, filters or not. Since January 2024 new shared connections are secure implicit: the app talks to a proxy that only talks to that app, and the proxy allows only the actions the app uses (get, post, put or patch, delete) on the tables it uses. That closes the "build your own app on my connection" hole. It does not change who the database sees.
Server-side security means the user signs in to the service, the service knows who they are, and the filtering happens there. Power Apps already does the first half: a user has to sign in to Power Apps with Entra credentials, and the app is shared with named people. The second half only works when the connection carries that identity through to SQL, which is what Entra ID Integrated does. Then row-level security and deny permissions in the database decide what each person gets, and no app or export can get past them.
Step 1: let the server accept Entra sign-ins
- Set a Microsoft Entra admin on the logical server (the server's Microsoft Entra ID page in the portal, or
az sql server ad-admin create). Until there is one, nothing in Entra can sign in, and only Entra identities can create other Entra users in the database: the SQL admin can't. - Connect as that admin (SQL Server Management Studio with Microsoft Entra authentication, or Azure Data Studio; connections with Entra authentication must be encrypted) and create users in the database, not logins on the server:
-- One person
CREATE USER [dana@contoso.com] FROM EXTERNAL PROVIDER;
-- A group: everyone in it can sign in
CREATE USER [Facilities App Users] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [Facilities App Users];
- Grant the least the app needs on views and tables, and nothing on the rest. A new database gives a user Connect and no more.
Things Learn warns about, and you will meet:
CREATE USER ... FROM EXTERNAL PROVIDERfails with error 33134 when a Conditional Access policy stops Azure SQL reading Entra on your behalf. Allow the Microsoft Graph application (00000003-0000-0000-c000-000000000000) in the policy, and run the statement as a person, not a service principal.- Group members don't get their own database user. Someone signing in through a group can read what the group may read, but statements that need an owner, such as creating a schema or a table without a schema, fail. Give the group user a
DEFAULT_SCHEMA, or create individual users for the few people who need it. - More than 2,048 groups on an account, and it can't sign in at all.
- Set the connection timeout to 30 seconds for Entra authentication; the token exchange takes longer than a SQL login.
Step 2: filter on the server
With the user's identity arriving in SQL, use the database's own security rather than the app's. Learn's recipe is row-level security for rows and DENY for columns.
CREATE SCHEMA Security;
GO
-- The signed-in person sees their own requests; the team role sees them all.
CREATE FUNCTION Security.fn_requestsForUser(@OwnerUpn AS nvarchar(256))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS result
WHERE @OwnerUpn = ORIGINAL_LOGIN() OR IS_ROLEMEMBER('facilities_team') = 1;
GO
CREATE SECURITY POLICY Security.RequestsFilter
ADD FILTER PREDICATE Security.fn_requestsForUser(OwnerUpn) ON dbo.Requests
WITH (STATE = ON);
GO
-- Nobody in the app role sees the salary column, whatever the app asks for.
DENY SELECT ON dbo.Employees (Salary) TO [Facilities App Users];
ORIGINAL_LOGIN() returns the user principal name the person signed in with, including when they got in through a group, which is why Learn's own row-level security example uses it. Store the owner's UPN in the row (the User().Email the app already has) and the predicate matches it. The team role is a database role with the Entra group as a member, so membership is managed in Entra, not in SQL.
Two more points from the same page: put the filtering in views where a predicate isn't enough, and connect the app to the views; and remember that stored procedures appear to the app as actions, not tables, so a procedure that filters by caller can feed a gallery only when it's marked safe for tables and galleries.
Step 3: the connection in the app
- In the app, add the SQL Server data source and choose Microsoft Entra ID Integrated. The maker's identity is used while editing, which means the maker needs a database user too.
- Share the app with users or a group. Don't share the connection; with Entra ID Integrated there's nothing to share, because each user's own sign-in creates their session.
- In a solution, use a connection reference and an environment variable for the server and database, so the same app points at the test and production servers in each environment.
- Each user consents to the connection on first run; the consent dialog shows the server and database names, which Learn notes aren't hidden.
If someone sees "You do not have correct permissions to use this connection", the app has an old implicit connection that isn't secure implicit (convert it; see the next section) or a secure implicit one that needs the app republished.
When you must keep a login
Some databases can't accept Entra sign-ins yet, and some apps are deliberately a shared view where everybody may see everything. For those, Microsoft's instruction since January 2024 is strong: convert every implicit connection to a secure implicit one and revoke the connections you shared.
- Open the app, select Settings, search for Secure, turn the secure implicit connections setting on, save and publish.
- In Share, untick Co-owner for anyone who shouldn't hold the connection, then remove users' rights to the connection itself (the X beside Can use).
- Check it worked: share the app with someone who isn't an owner and look at their Connections list; the connection shouldn't be there.
What it limits, from Learn's list: tabular connections are restricted to the create, read, update and delete actions the app uses (and a user who can put can also post); action connectors are limited to the APIs the app calls; column names aren't hidden; publishing to the whole tenant isn't supported; importing a secure implicit connection through a connection reference has a known issue with the target environment's security, and importing with a service principal can fail unless the connection is shared with that principal. The sharing panel may still show the old warning about implicit connections; Learn says the connection is secure despite it.
A shareable service principal is the admin-enabled alternative for a service account: every user gets the same rights, so it belongs with secure implicit connections and a database that holds nothing user-specific.
Delegation: what SQL filters for you
Identity settles who may see a row; delegation settles whether the app asks the server or filters the first 500 rows on the device. SQL Server is a delegable source for Filter, Search, SortByColumns, LookUp and the comparison operators in Learn's list, but not for functions such as Mid or Len inside a filter. The sign is the yellow warning on the gallery: with fewer rows than the data row limit (500 by default, up to 2,000) the formula works perfectly, and past it the rows simply aren't there. Push anything complex into a view, and for the rest use the Monitor to see the OData the app actually sends.
If the database sits behind a private endpoint, the connector can't reach it from the public cloud; Power Platform's managed virtual network support is the route, and that's an environment-level decision for the admin.
Sources
- Use Microsoft SQL Server securely with Power Apps, Microsoft Learn (explicit, implicit and secure implicit connections; client and server security; row-level security and deny)
- Overview of connectors for canvas apps, Microsoft Learn (authentication types, the January 2024 change, enabling secure implicit connections, unsharing, limitations)
- Use SQL Server with canvas apps, Microsoft Learn (the reference architecture, stored procedures as actions, the shareable service principal)
- Configure and manage Microsoft Entra authentication with Azure SQL, Microsoft Learn (the Entra admin, creating principals, error 33134)
- Microsoft Entra authentication for Azure SQL, Microsoft Learn (limitations: group members, 2,048 groups, the 30-second timeout)
- CREATE USER (Transact-SQL), Microsoft Learn (
FROM EXTERNAL PROVIDER) - Apply row-level security on Azure SQL external tables, Microsoft Learn (the
ORIGINAL_LOGIN()predicate with Entra users) - Query limitations: delegation and query limits, Microsoft Learn
- Managed virtual network support for Power Platform, Microsoft Learn
Did this fix it?
Comments
No comments yet. Share what worked for you.
Sign in to comment. Comments show under a display name you choose, never your email.