Forum Discussion

SylviaFeng's avatar
SylviaFeng
Microsoft Employee
11 months ago
Solved

Why is RLS using FALSE() still showing blank instead of error shows up in Power BI and Excel?

We're implementing RLS on a semantic model sourced from a Fabric Lakehouse. For one fact table, we assigned a security filter as FALSE() to fully restrict access to that table for a specific group. ...
  • tayloramy's avatar
    11 months ago

    Hi SylviaFeng

     

    You are seeing the expected behavior.

    RLS filters rows; it does not throw access errors. When a role’s filter evaluates to FALSE() on a table, that table simply returns zero rows for that user, so visuals render blank in both Power BI and Excel. That is by design: RLS is a row filter, not an object permission system, and DAX cannot detect that RLS is in effect. See Microsoft’s guidance: RLS “filters table rows; [it] can’t be configured to restrict access to model objects,” and a rule that evaluates to FALSE returns no rows. DAX also “can’t even determine that RLS is enforced.” (docs) RLS is also honored in Analyze in Excel and the Excel Power BI add-in, so blanks there are expected too (docs; see Considerations and limitations where it confirms RLS/OLS are supported).

    If you want a visible message instead of silent blanks, you have a few options:

    1. Show a friendly “no access” banner
      Create a tiny Security table that RLS filters to the current user, then drive visuals and a message off of it.
      • Table: Security with one row per allowed user (or mapping to your group logic), column UserUPN.
      • Role filter: Security[UserUPN] = USERPRINCIPALNAME() (or USERNAME() as appropriate; both are supported by Power BI RLS docs).
      • Measures:
        IsAuthorized = IF ( COUNTROWS ( Security ) > 0, 1, 0 )
        
        AccessMessage =
        IF ( [IsAuthorized] = 0,
        "You do not have access to this data. Please contact the owner if you believe this is an error.",
        BLANK()
        )
      • Add visual-level (or page-level) filter [IsAuthorized] is 1 to every analytic visual.
      • Add a Card visual bound to [AccessMessage] that appears only when [IsAuthorized] = 0.
      Note: This distinguishes “no access” from “legitimately no data” if your Security table reliably indicates entitlement. Also, Microsoft recommends placing RLS on a dimension/entitlement table rather than the fact table for performance and propagation reasons (docs).
    2. Use Object-Level Security (OLS) for a hard deny
      If your requirement is an explicit permission block instead of blanks, secure the table or sensitive columns with OLS. For users without permission, secured objects “simply do not exist,” and visuals that reference them will be blocked, surfacing a visible error instead of empty results. OLS is defined in model roles (commonly via Tabular Editor) and is supported in Pro and Premium capacities. See: docs and the GA announcement blog.
    3. Excel specifically
      Excel honors RLS the same way, so pivots will show blanks if all rows are filtered out. You can surface the same message by adding the [AccessMessage] measure to a PivotTable or by using a CUBEVALUE cell bound to that measure, and directing users accordingly. Microsoft confirms RLS support for Analyze in Excel in the considerations section of the Excel article (docs).

     

     

    If you found this helpful, consider giving some Kudos. If I answered your question or solved your problem, mark this post as the solution.