Zo zákulisia brány firewall na ochranu osobných údajov

Note

Úrovne ochrany osobných údajov v súčasnosti nie sú k dispozícii v tokoch údajov Power Platformy.

Note

V minulosti brána firewall zabránila oblasti v prístupe k zdrojom údajov a zároveň odkazovaniu na iné oblasti. Toto je jedno z hlavných obmedzení popísaných v článku nižšie. V niektorých produktoch je však toto obmedzenie teraz zmiernené. Ďalšie informácie nájdete v článku: Povolenie oblastí brány firewall pre ochranu údajov, ktoré odkazujú na iné oblasti na prístup aj k zdrojom údajov.

Ak ste Power Query používali dlhší čas, pravdepodobne ste sa s tým stretli. Tu ste, pýtate sa, keď sa zrazu zobrazí chyba, ktorú nedokáže napraviť žiadne množstvo online vyhľadávania, ladenia dotazov alebo búšenia klávesnice. Chyba ako:

Formula.Firewall: Query 'Query1' (step 'Source') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.

Alebo možno:

Formula.Firewall: Query 'Query1' (step 'Source') is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination.

Tieto Formula.Firewall chyby sú výsledkom brány firewall ochrany osobných údajov Power Query (známej aj ako brána firewall), ktorá sa niekedy môže zdať, že existuje len preto, aby frustrovala analytikov údajov na celom svete. Verte tomu alebo nie, firewall však plní dôležitý účel. V tomto článku sa ponoríme pod kapotu, aby sme lepšie pochopili, ako to funguje. Dúfajme, že vyzbrojení väčším porozumením budete v budúcnosti schopní lepšie diagnostikovať a opravovať chyby brány firewall.

Čo je to?

Účel brány firewall na ochranu osobných údajov je jednoduchý: existuje na to, aby zabránil neúmyselnému úniku údajov medzi zdrojmi zo strany Power Query.

Prečo je to potrebné? Myslím tým, že by ste určite mohli vytvoriť nejaké M, ktoré by odovzdalo hodnotu SQL do informačného kanála OData. Išlo by však o úmyselný únik údajov. Autor mashupu by (alebo by aspoň mal) vedel, že to robí. Prečo je potom potrebná ochrana pred neúmyselným únikom údajov?

Odpoveď? Skladací.

Skladací?

Skladanie je termín, ktorý označuje konverziu výrazov v jazyku M (napríklad filtre, premenovania, spojenia atď.) na operácie s nespracovaným zdrojom údajov (napríklad SQL, OData atď.). Veľká časť sily Power Query pochádza zo skutočnosti, že Power Query dokáže previesť operácie, ktoré používateľ vykonáva prostredníctvom svojho používateľského rozhrania, do zložitých jazykov SQL alebo iných backendových zdrojov údajov bez toho, aby používateľ musel tieto jazyky poznať. Používatelia získajú výkonnostnú výhodu operácií s natívnym zdrojom údajov s jednoduchým použitím používateľského rozhrania, kde je možné transformovať všetky zdroje údajov pomocou spoločnej sady príkazov.

V rámci skladania môže Power Query niekedy určiť, že najefektívnejším spôsobom spustenia daného mashupu je prevziať údaje z jedného zdroja a odovzdať ich inému. Ak napríklad pripájate malý súbor CSV k veľkej tabuľke SQL, pravdepodobne nechcete, aby Power Query prečítal súbor CSV, prečítal celú tabuľku SQL a potom ich spojil v lokálnom počítači. Pravdepodobne chcete, aby Power Query vložil údaje CSV do príkazu SQL a požiadal databázu SQL o vykonanie spojenia.

Takto môže dôjsť k neúmyselnému úniku údajov.

Predstavte si, že by ste spájali údaje SQL, ktoré zahŕňali čísla sociálneho poistenia zamestnancov, s výsledkami externého informačného kanála OData a zrazu by ste zistili, že čísla sociálneho poistenia z SQL sa odosielajú do služby OData. Zlé správy, však?

Tomuto scenáru má brána firewall zabrániť.

Ako to funguje?

Brána firewall existuje na to, aby zabránila neúmyselnému odoslaniu údajov z jedného zdroja do iného zdroja. Dosť jednoduché.

Ako teda túto misiu napĺňa?

Robí to rozdelením dotazov M na niečo, čo sa nazýva oddiely, a následným vynútením nasledujúceho pravidla:

  • Oblasť môže buď pristupovať ku kompatibilným zdrojom údajov, alebo odkazovať na iné oblasti, ale nie na oboje.

Jednoduchý... napriek tomu mätúce. Čo je to oddiel? Čo robí dva zdroje údajov "kompatibilnými"? A prečo by sa mal firewall starať o to, či chce oddiel získať prístup k zdroju údajov a odkazovať na oddiel?

Poďme si to rozobrať a pozrieť sa na predchádzajúce pravidlo po častiach.

Čo je to oddiel?

Na najzákladnejšej úrovni je oblasť len kolekciou jedného alebo viacerých krokov dotazu. Najpodrobnejšie možné rozdelenie (aspoň v súčasnej implementácii) je jeden krok. Najväčšie oblasti môžu niekedy zahŕňať viacero dotazov. (Viac o tom neskôr.)

Ak nie ste oboznámení s krokmi, môžete ich zobraziť na pravej strane okna Editor Power Query po výbere dotazu na table Použité kroky . Kroky sledujú všetko, čo robíte, aby ste svoje údaje transformovali do konečnej podoby.

Oblasti, ktoré odkazujú na iné oblasti

Keď sa dotaz vyhodnocuje so zapnutou bránou firewall, brána firewall rozdelí dotaz a všetky jeho závislosti na oddiely (t. j. skupiny krokov). Kedykoľvek jeden oddiel odkazuje na niečo v inom oddiele, firewall nahradí odkaz volaním špeciálnej funkcie s názvom Value.Firewall. Inými slovami, brána firewall neumožňuje priamy prístup oddielov k sebe. Všetky odkazy sú upravené tak, aby prešli bránou firewall. Predstavte si firewall ako strážcu brány. Oddiel, ktorý odkazuje na iný oddiel, musí na to získať povolenie brány firewall a brána firewall kontroluje, či sú odkazované údaje povolené do oddielu.

To všetko sa môže zdať dosť abstraktné, takže sa pozrime na príklad.

Predpokladajme, že máte dotaz s názvom Zamestnanci, ktorý načíta niektoré údaje z databázy SQL. Predpokladajme, že máte aj iný dotaz (EmployeesReference), ktorý jednoducho odkazuje na Zamestnanci.

shared Employees = let
    Source = Sql.Database(…),
    EmployeesTable = …
in
    EmployeesTable;

shared EmployeesReference = let
    Source = Employees
in
    Source;

Tieto dotazy sú nakoniec rozdelené do dvoch oblastí: jedna pre dotaz Zamestnanci a jedna pre dotaz EmployeesReference (ktorá odkazuje na oblasť Zamestnanci). Pri vyhodnotení so zapnutým firewallom sa tieto dotazy prepíšu takto:

shared Employees = let
    Source = Sql.Database(…),
    EmployeesTable = …
in
    EmployeesTable;

shared EmployeesReference = let
    Source = Value.Firewall("Section1/Employees")
in
    Source;

Všimnite si, že jednoduchý odkaz na dotaz Zamestnanci je nahradený volaním , Value.Firewallktoré poskytuje celé meno dotazu Zamestnanci.

Keď sa vyhodnotí EmployeesReference, brána firewall zachytí volanie na Value.Firewall("Section1/Employees"), ktoré má teraz možnosť riadiť, či (a ako) požadované údaje prúdia do oblasti EmployeesReference. Môže robiť ľubovoľný počet vecí: odmietnuť požiadavku, uložiť požadované údaje do vyrovnávacej pamäte (čo zabráni ďalšiemu skladaniu do pôvodného zdroja údajov) a podobne.

Takto si brána firewall udržuje kontrolu nad dátami prúdiacimi medzi oddielmi.

Oblasti, ktoré priamo pristupujú k zdrojom údajov

Povedzme, že definujete dotaz Query1 v jednom kroku (všimnite si, že tento jednokrokový dotaz zodpovedá jednej oblasti brány firewall) a že tento jeden krok pristupuje k dvom zdrojom údajov: tabuľke databázy SQL a súboru CSV. Ako sa s tým vysporiada Firewall, keďže neexistuje žiadna referencia na oddiel, a teda ani volanie na Value.Firewall jeho zachytenie? Pozrime sa na vyššie uvedené pravidlo:

  • Oblasť môže buď pristupovať ku kompatibilným zdrojom údajov, alebo odkazovať na iné oblasti, ale nie na oboje.

Aby bolo možné spustiť dotaz s jedným oddielom, ale dvoma zdrojmi údajov, jeho dva zdroje údajov musia byť "kompatibilné". Inými slovami, musí byť v poriadku, aby sa údaje medzi nimi zdieľali obojsmerne. To znamená, že úrovne ochrany osobných údajov oboch zdrojov musia byť verejné, alebo musia byť organizačné, pretože sú to jediné dve kombinácie, ktoré umožňujú zdieľanie v oboch smeroch. Ak sú oba zdroje označené ako súkromné alebo jeden je označený ako verejný a druhý ako organizačný, alebo ak sú označené pomocou inej kombinácie úrovní ochrany osobných údajov, obojsmerné zdieľanie nie je povolené. Nie je bezpečné, aby boli obe hodnotené v rovnakom oddiele. Mohlo by to znamenať, že by mohlo dôjsť k nebezpečnému úniku údajov (v dôsledku skladania) a brána firewall by tomu nemala žiadny spôsob, ako tomu zabrániť.

Čo sa stane, ak sa pokúsite získať prístup k nekompatibilným zdrojom údajov v rovnakom oddiele?

Formula.Firewall: Query 'Query1' (step 'Source') is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination.

Dúfajme, že teraz lepšie rozumiete jednému z chybových hlásení uvedených na začiatku tohto článku.

Táto požiadavka na kompatibilitu platí iba v rámci daného oddielu. Ak oblasť odkazuje na iné oblasti, zdroje údajov z odkazovaných oblastí nemusia byť navzájom kompatibilné. Je to preto, že brána firewall môže ukladať údaje do vyrovnávacej pamäte, čo zabraňuje ďalšiemu skladaniu proti pôvodnému zdroju údajov. Údaje sa načítajú do pamäte a zaobchádza sa s nimi, akoby prišli z ničoho nič.

Prečo neurobiť oboje?

Povedzme, že definujete dotaz s jedným krokom (ktorý opäť zodpovedá jednej oblasti), ktorý pristupuje k dvom ďalším dotazom (t. j. dvom ďalším oblastiam). Čo ak by ste chceli v rovnakom kroku získať aj priamy prístup k databáze SQL? Prečo oblasť nemôže odkazovať na iné oblasti a priamo pristupovať ku kompatibilným zdrojom údajov?

Ako ste už videli, keď jeden oddiel odkazuje na iný oddiel, firewall funguje ako strážca pre všetky dáta prúdiace do oddielu. Na tento účel musí byť schopný kontrolovať, aké údaje sú povolené. Ak sa v rámci oddielu pristupuje k zdrojom údajov a údaje prúdia z iných oddielov, stráca schopnosť byť strážcom, pretože prúdiace údaje môžu uniknúť do jedného z interne prístupných zdrojov údajov bez toho, aby o tom vedel. Brána firewall teda bráni tomu, aby oddiel, ktorý pristupuje k iným oddielom, mal priamy prístup k akýmkoľvek zdrojom údajov.

Čo sa teda stane, ak sa oddiel pokúsi odkazovať na iné oddiely a tiež priamo pristupovať k zdrojom údajov?

Formula.Firewall: Query 'Query1' (step 'Source') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.

Dúfajme, že teraz lepšie pochopíte ďalšie chybové hlásenie uvedené na začiatku tohto článku.

Priečky do hĺbky

Ako pravdepodobne tušíte z predchádzajúcich informácií, spôsob rozdelenia dotazov je nakoniec neuveriteľne dôležitý. Ak máte niektoré kroky, ktoré odkazujú na iné dotazy, a ďalšie kroky na prístup k zdrojom údajov, dúfajme, že teraz spoznáte, že nakreslenie hraníc oblastí na určitých miestach spôsobuje chyby brány firewall, zatiaľ čo ich nakreslenie na iných miestach umožňuje bezproblémové spustenie dotazu.

Ako presne sa teda dotazy rozdeľujú?

Táto časť je pravdepodobne najdôležitejšia na pochopenie toho, prečo sa zobrazujú chyby brány firewall, a na pochopenie toho, ako ich vyriešiť (ak je to možné).

Tu je súhrn logiky rozdelenia na vysokej úrovni.

  • Počiatočné rozdelenie
    • Vytvorí oblasť pre každý krok v každom dotaze
  • Statická fáza
    • Táto fáza nezávisí od výsledkov hodnotenia. Namiesto toho sa spolieha na štruktúru dotazov.
      • Orezávanie parametrov
        • Orezáva oddiely v štýle parametrov, to znamená všetky tie, ktoré:
          • Neodkazuje na žiadne iné oblasti
          • Neobsahuje žiadne vyvolania funkcií
          • Nie je cyklický (to znamená, že sa nevzťahuje sám na seba)
        • Všimnite si, že "odstránenie" oddielu ho efektívne zahŕňa do akýchkoľvek iných oddielov, ktoré naň odkazujú.
        • Orezanie oblastí parametrov umožňuje fungovanie odkazov na parametre používané vo volaniach funkcií zdroja údajov (napríklad Web.Contents(myUrl)) namiesto vyvolania chýb "oddiel nemôže odkazovať na zdroje údajov a ďalšie kroky".
      • Zoskupenie (statické)
        • Oddiely sa zlučujú v poradí závislostí zdola nahor. Vo výsledných zlúčených oddieloch sú oddelené:
          • Oddiely v rôznych dotazoch
          • Oblasti, ktoré neodkazujú na iné oblasti (a preto majú povolený prístup k zdroju údajov)
          • Oddiely, ktoré odkazujú na iné oddiely (a preto majú zakázaný prístup k zdroju údajov)
  • Dynamická fáza
    • Táto fáza závisí od výsledkov vyhodnotenia vrátane informácií o zdrojoch údajov, ku ktorým pristupujú rôzne oblasti.
    • Orezávanie
      • Orezáva priečky, ktoré spĺňajú všetky nasledujúce požiadavky:
        • Nepristupuje k žiadnym zdrojom údajov
        • Neodkazuje na žiadne oblasti, ktoré pristupujú k zdrojom údajov
        • Nie je cyklický
    • Zoskupovanie (dynamické)
      • Teraz, keď sú nepotrebné oddiely orezané, skúste vytvoriť zdrojové oddiely, ktoré sú čo najväčšie. Toto vytvorenie sa vykonáva zlúčením oddielov pomocou rovnakých pravidiel popísaných v predchádzajúcej fáze statického zoskupovania.

Čo to všetko znamená?

Prejdime si príklad, aby sme ilustrovali, ako funguje predtým stanovená zložitá logika.

Tu je vzorový scenár. Ide o pomerne jednoduché zlúčenie textového súboru (Kontakty) s databázou SQL (Zamestnanci), kde SQL server je parameter (DbServer).

Tri dopyty

Tu je kód M pre tri dotazy použité v tomto príklade.

shared DbServer = "MySqlServer" meta [IsParameterQuery=true, Type="Text", IsParameterQueryRequired=true];
shared Contacts = let

    Source = Csv.Document(File.Contents(
        "C:\contacts.txt"),[Delimiter="   ", Columns=15, Encoding=1252, QuoteStyle=QuoteStyle.None]
    ),

    #"Promoted Headers" = Table.PromoteHeaders(Source, [PromoteAllScalars=true]),

    #"Changed Type" = Table.TransformColumnTypes(
        #"Promoted Headers",
        {
            {"ContactID", Int64.Type}, 
            {"NameStyle", type logical}, 
            {"Title", type text}, 
            {"FirstName", type text}, 
            {"MiddleName", type text}, 
            {"LastName", type text}, 
            {"Suffix", type text}, 
            {"EmailAddress", type text}, 
            {"EmailPromotion", Int64.Type}, 
            {"Phone", type text}, 
            {"PasswordHash", type text}, 
            {"PasswordSalt", type text}, 
            {"AdditionalContactInfo", type text}, 
            {"rowguid", type text}, 
            {"ModifiedDate", type datetime}
        }
    )

in

    #"Changed Type";
shared Employees = let

    Source = Sql.Databases(DbServer),

    AdventureWorks = Source{[Name="AdventureWorks"]}[Data],

    HumanResources_Employee = AdventureWorks{[Schema="HumanResources",Item="Employee"]}[Data],

    #"Removed Columns" = Table.RemoveColumns(
        HumanResources_Employee,
        {
            "HumanResources.Employee(EmployeeID)", 
            "HumanResources.Employee(ManagerID)", 
            "HumanResources.EmployeeAddress", 
            "HumanResources.EmployeeDepartmentHistory", 
            "HumanResources.EmployeePayHistory", 
            "HumanResources.JobCandidate", 
            "Person.Contact", 
            "Purchasing.PurchaseOrderHeader", 
            "Sales.SalesPerson"
        }
    ),

    #"Merged Queries" = Table.NestedJoin(
        #"Removed Columns",
        {"ContactID"},
        Contacts,
        {"ContactID"},
        "Contacts",
        JoinKind.LeftOuter
    ),

    #"Expanded Contacts" = Table.ExpandTableColumn(
        #"Merged Queries", 
        "Contacts", 
        {"EmailAddress"}, 
        {"EmailAddress"}
    )

in

    #"Expanded Contacts";

Tu je zobrazenie vyššej úrovne, ktoré zobrazuje závislosti.

Dialógové okno Závislosti dotazu.

Poďme rozdeliť

Priblížme si trochu a zahrnime kroky do obrázka a začnime prechádzať logikou rozdelenia. Tu je diagram troch dotazov, ktorý zobrazuje počiatočné oblasti brány firewall zelenou farbou. Všimnite si, že každý krok začína vo vlastnej oblasti.

Diagram znázorňujúci počiatočné oblasti brány firewall.

Ďalej orežeme parametrické oddiely. DbServer je teda implicitne zahrnutý do zdrojového oddielu.

Diagram znázorňujúci orezané oblasti brány firewall.

Teraz vykonáme statické zoskupenie. Toto zoskupenie zachováva oddelenie medzi oddielmi v samostatných dotazoch (všimnite si napríklad, že posledné dva kroky Zamestnanci sa nezoskupujú s krokmi Kontakty) a medzi oddielmi, ktoré odkazujú na iné oddiely (napríklad posledné dva kroky Zamestnanci) a tými, ktoré nie sú (napríklad prvé tri kroky Zamestnanci).

Diagram znázorňujúci oddiely brány firewall so statickým zoskupením.

Teraz vstupujeme do dynamickej fázy. V tejto fáze sa vyhodnocujú vyššie uvedené statické oddiely. Oblasti, ktoré nemajú prístup k žiadnym zdrojom údajov, sú orezané. Oddiely sa potom zoskupia tak, aby vytvorili zdrojové oddiely, ktoré sú čo najväčšie. V tomto ukážkovom scenári však všetky zostávajúce oblasti pristupujú k zdrojom údajov a nie je možné vykonať žiadne ďalšie zoskupenie. Oddiely v našej vzorke sa teda počas tejto fázy nemenia.

Predstierajme

Pre ilustráciu sa však pozrime na to, čo by sa stalo, keby bol dotaz Kontakty namiesto toho, aby pochádzal z textového súboru, napevno zakódovaný v jazyku M (možno prostredníctvom dialógového okna Zadať údaje ).

V takom prípade by dotaz Kontakty nemal prístup k žiadnym zdrojom údajov. Počas prvej časti dynamickej fázy by sa teda orezal.

Diagram znázorňujúci oddiel brány firewall po dynamickom orezaní fázy.

Po odstránení oddielu Kontakty už posledné dva kroky Zamestnanci nebudú odkazovať na žiadne oddiely okrem oddielu, ktorý obsahuje prvé tri kroky Zamestnanci. Obe oddiely by sa teda zoskupili.

Výsledný oddiel by vyzeral takto.

Diagram znázorňujúci konečné oddiely brány firewall.

Príklad: Odovzdávanie údajov z jedného zdroja údajov do druhého

Dobre, dosť bolo abstraktného vysvetlenia. Pozrime sa na bežný scenár, v ktorom pravdepodobne narazíte na chybu brány firewall, a na kroky na jej vyriešenie.

Predstavte si, že chcete vyhľadať názov spoločnosti zo služby Northwind OData a potom použiť názov spoločnosti na vykonanie vyhľadávania v Bingu.

Najprv vytvoríte dotaz spoločnosti na načítanie názvu spoločnosti.

let
    Source = OData.Feed(
        "https://services.odata.org/V4/Northwind/Northwind.svc/", 
        null, 
        [Implementation="2.0"]
    ),
    Customers_table = Source{[Name="Customers",Signature="table"]}[Data],
    CHOPS = Customers_table{[CustomerID="CHOPS"]}[CompanyName]
in
    CHOPS

Ďalej vytvoríte vyhľadávací dotaz, ktorý odkazuje na spoločnosť a odovzdá ho do služby Bing.

let
    Source = Text.FromBinary(Web.Contents("https://www.bing.com/search?q=" & Company))
in
    Source

V tomto bode sa dostanete do problémov. Vyhodnotenie vyhľadávania spôsobí chybu brány firewall.

Formula.Firewall: Query 'Search' (step 'Source') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.

Táto chyba sa vyskytuje, pretože krok Zdroj vyhľadávania odkazuje na zdroj údajov (bing.com) a tiež odkazuje na iný dotaz alebo oblasť (Spoločnosť). Porušuje vyššie uvedené pravidlo ("oddiel môže buď pristupovať ku kompatibilným zdrojom údajov, alebo odkazovať na iné oddiely, ale nie na oboje").

Čo robiť? Jednou z možností je úplne vypnúť bránu firewall (prostredníctvom možnosti Ochrana osobných údajov označenej Ignorovať úrovne ochrany osobných údajov a potenciálne zlepšiť výkon). Čo ak však chcete ponechať bránu firewall zapnutú?

Ak chcete chybu vyriešiť bez vypnutia brány firewall, môžete skombinovať funkciu Spoločnosť a vyhľadávanie do jedného dotazu, napríklad takto:

let
    Source = OData.Feed(
        "https://services.odata.org/V4/Northwind/Northwind.svc/", 
        null, 
        [Implementation="2.0"]
    ),
    Customers_table = Source{[Name="Customers",Signature="table"]}[Data],
    CHOPS = Customers_table{[CustomerID="CHOPS"]}[CompanyName],
    Search = Text.FromBinary(Web.Contents("https://www.bing.com/search?q=" & CHOPS))
in
    Search

Všetko sa teraz deje vo vnútri jedného oddielu. Za predpokladu, že úrovne ochrany osobných údajov pre tieto dva zdroje údajov sú kompatibilné, brána firewall by teraz mala byť spokojná a už sa vám nezobrazuje chyba.

To je zábal

Aj keď by sa o tejto téme dalo povedať oveľa viac, tento úvodný článok je už dosť dlhý. Dúfame, že vám to umožní lepšie pochopiť bránu firewall a pomôže vám pochopiť a opraviť chyby brány firewall, keď sa s nimi v budúcnosti stretnete.