Repository navigation
Proposal: per-team row-level security for hubs, and a "dashboard first" rule for the hub agents #2371
Replies: 2 comments
|
🤖 [AI] Thanks for writing this up before opening PRs. A few thoughts from the maintainer side. Row-level security. We'd see this as an optional add-on, not the default setup:
The practical path: open a feature issue for optional RLS in FinOps hubs with your gotchas (exact "Dashboard first" for agents. Aligning the dashboard queries and the agent query catalog is a fair point. We're not convinced it needs to be a hard rule, because it would constrain both the dashboards and the agents to each other's scope. Please open it as a separate issue so it can be discussed on its own. |
|
Thanks, Roland, that makes sense. I've opened the two issues so each can be discussed on its own:
On your points: RLS is written up as opt-in only, with subscription as the common case and the scoping column configurable. On raw tables, I tested that at the default raw retention (0 days) they hold no data, so Viewer on Happy to open a docs PR for the RLS issue if you're OK with that. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Hi FinOps toolkit team,
I run FinOps hubs (v14, Azure Data Explorer) and have built two things on top of it that I'd like to contribute. Before opening issues and PRs, I'd like your view on whether they fit and in what form.
1. Row-level security: scope hub data by subscription
Problem: anyone with Viewer on the hub databases sees all cost data, so a hub can't be shared across teams who shouldn't see each other's spend.
What I've done: I enabled Azure Data Explorer row-level security on the eight final tables in
Ingestionthat carrySubAccountId(Costs,CommitmentDiscountUsage,Recommendations,Transactions, each_v1_0and_v1_2), one function per table: an allow-all list (admins, the Data Factory identity, alert identities) plus per-team subscription lists. Because it runs in the database, it applies to KQL, dashboards and AI agents that query with the user's identity. I check the blockers first, test withset query_force_row_level_securitybefore enabling, and keep a rollback.Things I learned that would belong in the docs:
SubAccountIdmust be matched exactly (/subscriptions/<id>, lowercase); rows with an emptySubAccountId(billing-level purchases, shared reservations) are only visible to the allow-all list.HubandIngestion: theHubfunctions readIngestionas the caller (withHubonly, queries fail withSEM0056 ... Access denied).*_rawtables, but at the default raw retention (0 days) they hold no data, so Viewer onIngestionexposes nothing unfiltered. Only hubs with raw retention above 0 need restricted view access on them.Proposal: start with a docs page, "Configure row-level security for FinOps hubs", under FinOps hubs (draft ready). Later, if useful, a PowerShell command to generate and apply the functions from a team-to-subscriptions config (I have a working Python version and would port it).
Questions:
*_rawtables the approach you'd recommend, or is there a better one?2. "Dashboard first": let the hub agents use the dashboard's queries
Problem: the hub agents (Copilot instructions, Copilot Studio template, agent plugin) use the 37-query catalog in
src/queries/catalog, while the Data Explorer dashboard (src/templates/finops-hub/dashboard.json) has its own 87 queries. The agent can answer a question with different logic than the dashboard tile the same user looks at, so the numbers may not match. Teams that customize the dashboard (their own tag conventions, egress rules, allocation logic) also don't get those definitions in the agent.What I've done: in my own agent, the dashboard's tiles are exposed through one tool: the model picks a tile, sets its parameters, and can add a scope (subscription, resource group, resource type) that's applied as a filter on
Costs(). The prompt says: if a tile matches the question, run it before writing your own KQL, and name the tile in the answer. Answers now match the dashboard, and team-specific definitions come for free.Proposal:
Build-QueryCatalog.ps1, or a sibling script) that turnsdashboard.jsoninto an agent knowledge file: one entry per tile with its page, title, parameters and defaults, and the KQL with base queries and parameters resolved. It should also run on a customer's exported dashboard, so customized dashboards feed the agent.Lessons from doing this: dashboard parameters need defaults resolved (an "all" multi-select becomes
dynamic(null)), some tiles read tag columns that only exist on some hubs (bag_unpack), and a tile should only be run once per answer.Questions:
I'm happy to open separate issues for each and keep the PRs small. I can also join office hours or the contributor sync to walk through either.
Thanks!
All reactions