Forum Discussion
Query Firewall Violation
- 1 year ago
Hi rpiboy_1,
Thank you for the follow-up question. To clarify having a web call inside a function doesn’t by itself violate the firewall rules.
The firewall is triggered when:
• A value from one data source (e.g. admin API) is used to dynamically build or drive a request to another data source (e.g. object API).
• Power Query can’t guarantee that sensitive information from one source isn’t being sent to the other.
So technically, whether the Web.Contents is inside a function, or a “stand-alone” query doesn’t matter what matters is how the privacy levels are configured for the sources you’re combining. https://learn.microsoft.com/en-us/powerquery-m/web-contents
Function per server: You can safely parameterize the base URL (US, CA, etc.) in your function. If each function only calls one domain, the firewall won’t block it.
Separate queries per server, then roll up: This also works, but it’s more verbose. You’d then combine those queries later.
Both approaches are valid. The key is: if the endpoints are trusted and belong to the same system, set their Privacy Level to the same scope (e.g. Organizational). That way, the firewall won’t block cross-source logic whether it’s inside a function or separate queries.So the choice of “function vs. separate queries” is mostly about maintainability of your code rather than avoiding the firewall. The firewall decision is based on privacy settings, not function structure.
Hope this clears it up. Let us know if you have any doubts regarding this. We will be happy to help.
Thank you for using the Microsoft Fabric Community Forum.
Short answer: you’re hitting the privacy/combination firewall because that step calls different hosts per row (https://adm-us…, https://adm-ca…, https://api-us…, https://api-ca…). In the Service, a single query that mixes multiple data sources (different domains) will be blocked unless you stage them or give them the same privacy level. Fix by staging each host separately, then append.
What to change (minimal pattern)
Create one staged query per host (load = Off).
Use RelativePath/Query only; no concatenated URLs.
// US admin
Admin_US = (relative as text, optional qry as nullable record) as any =>
Json.Document(
Web.Contents(
"https://adm-us.drofus.com",
[ RelativePath = relative, Query = if qry=null then [] else qry, Headers=[Accept="application/json"] ]
)
);
// CA admin
Admin_CA = (relative as text, optional qry as nullable record) as any =>
Json.Document(
Web.Contents(
"https://adm-ca.drofus.com",
[ RelativePath = relative, Query = if qry=null then [] else qry, Headers=[Accept="application/json"] ]
)
);
// US api
Api_US = (relative as text, optional qry as nullable record) as any =>
Json.Document(
Web.Contents(
"https://api-us.drofus.com",
[ RelativePath = relative, Query = if qry=null then [] else qry ]
)
);
// CA api
Api_CA = (relative as text, optional qry as nullable record) as any =>
Json.Document(
Web.Contents(
"https://api-ca.drofus.com",
[ RelativePath = relative, Query = if qry=null then [] else qry ]
)
);
Branch your processing by host, call the proper function, then append:
USRows = Table.SelectRows(CombinedForProcessing, each [ServerCodes] = "US");
CARows = Table.SelectRows(CombinedForProcessing, each [ServerCodes] = "CA");
US_Data =
Table.AddColumn(
USRows, "Data",
each Api_US(
[database_id] & "/" & [no] & "/" & [ObjectTypes],
[#"${top}"= PaginationValue, #"${skip}"= PaginationSkipVal, $"select"= Text.Combine(ColumnIDs, ",")]
)
);
CA_Data =
Table.AddColumn(
CARows, "Data",
each Api_CA(
[database_id] & "/" & [no] & "/" & [ObjectTypes],
[#"${top}"= PaginationValue, #"${skip}"= PaginationSkipVal, $"select"= Text.Combine(ColumnIDs, ",")]
)
);
ObjectDataWithFunction = Table.Combine({US_Data, CA_Data});
In the Service, set Privacy Level = Organizational (or the same level) for each of these four roots:
https://adm-us.drofus.com, https://adm-ca.drofus.com, https://api-us.drofus.com, https://api-ca.drofus.com.
Do not use dynamic hosts in a single Web.Contents call.
Alternatives
Put each host in a dataflow and have the dataset read the dataflows (single source).
Use a small proxy/Azure Function so the dataset calls one domain.
As a last resort, enable “Allow combining data from multiple sources” (Privacy: Ignore) — acceptable only if your org permits it.
Why the error: your ObjectDataWithFunction step evaluates different domains row-by-row; the firewall can’t verify safe combination, so it blocks it. Staging per host (or same privacy level) resolves it.
- rpiboy_11 year ago
Helper V
Ugh, thanks, so basically I need a query per host/static URL. That is unfortunate makes management a bit more of a pain and also makes it 'harder' to do some other things I had hoped to do in the future. I was aware of the need to stay away from dynamic (concatended) URLs and make sure to use the arguements of the Web.Contents function to build dynamic queries. Privacy levels are not a concern in this case and everything has been set to Organizational.
- rpiboy_11 year ago
Helper V
Will having a web call in a function itself violate the firewall rules? I.E. can I have a function per server, or do I need to have a seperate, stand-alone query for each Server that I then roll-up the data from? Its a bit pandentic as I still have to have 'something' for each server, just impacts how I approach the full solution.