Thanks for the clarification, @kayu! π Sharing what I have built since posting, in case it is useful for others.
I have a working LLM chat POC/MVP for embedded Power BI with tenant isolation via RLS π:
- π οΈ Backend authenticates as SPN (minimum Build access on semantic model)
- π€Each request sets effectiveUserName to a generic per-tenant identity (this needs to be added at RLS role on semantic model)
- πTenant key is passed via customData, and RLS roles filter on CUSTOMDATA()
- π€The LLM never sees credentials, raw schema, or other tenants' metadata. It only gets a curated schema slice and few-shot examples
- β
DAX is generated, validated against a deny-list, then executed. (Can be used with multi LLM)
It works reliably in production against an F-capacity model. π― A few notes that might help others:
On Microsoft's remote Power BI MCP server: β οΈ I evaluated it first and had to drop it. The hosted ExecuteQuery tool only accepts artifactId, daxQueries and maxRows. No way to pass effectiveUserName or customData, so RLS cannot propagate through it. GetSemanticModelSchema also runs as the SPN identity and returns the full model, which leaks metadata across tenants even when row-level data is protected. π« Blocker for multi-tenant embedded SaaS.
That is why I built my own backend module instead. ποΈ It owns SPN auth, schema curation, DAX validation, audit logging and execution, and is transport-agnostic so it can be exposed as an MCP server later if needed.
I have also done a separate POC writing AI metadata (descriptions and custom annotations like AI_Description and VerifiedAnswer_*) directly into the semantic model via TMDL + XMLA π§ , fully programmatic with SPN auth, then read back via INFO.VIEW.* and INFO.ANNOTATIONS(). This gives the LLM authoritative business context owned by the model rather than the app. π
Net result: π‘ SPN + effectiveUserName + customData is a viable foundation for secure embedded LLM chat today. The biggest gap is tooling. It would be very valuable if the new Execute DAX Queries API and Microsoft's MCP server both exposed effectiveUserName / customData so this scenario can be properly supported end to end. π
Marius