Veri Gizliliği Güvenlik Duvarı'nın arka planı
Not
Power Platform veri akışlarında gizlilik düzeyleri şu anda kullanılamıyor, ancak ürün ekibi bu işlevselliği etkinleştirmek için çalışıyor.
Power Query'yi herhangi bir süre kullandıysanız, büyük olasılıkla bunu deneyimlediniz. Çevrimiçi arama, sorgu ayarlama veya klavye bash'inin düzeltebileceği bir hatayla aniden karşı karşıya olduğunuzda sorguyu dışarıda bırakabilirsiniz. Şuna benzer bir hata:
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.
Veya belki:
Formula.Firewall: Query 'Query1' (step 'Source') is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination.
Bu Formula.Firewall
hatalar, Power Query'nin Veri Gizliliği Güvenlik Duvarı'nın (Güvenlik Duvarı olarak da bilinir) sonucu ortaya çıkabilir ve bu güvenlik duvarı bazen yalnızca veri analistlerini hayal kırıklığına uğratıyor gibi görünebilir. İster inanın ister inanmayın, ancak Güvenlik Duvarı önemli bir amaca hizmet eder. Bu makalede, nasıl çalıştığını daha iyi anlamak için arka planda araştırma yapacağız. Daha fazla anlayışla, gelecekte Güvenlik duvarı hatalarını daha iyi tanılayıp düzeltebilmenizi umuyoruz.
Nedir?
Veri Gizliliği Güvenlik Duvarı'nın amacı basittir: Power Query'nin yanlışlıkla kaynaklar arasında veri sızdırmasını önlemek için mevcuttur.
Bu neden gereklidir? OData akışına SQL değeri geçirebilecek bir M yazabilirsiniz. Ancak bu kasıtlı veri sızıntısı olabilir. Karma yazarı bunu yaptığını bilir (veya en azından bunu yapmalıdır). O zaman neden istemeden veri sızıntısına karşı koruma ihtiyacı duyulsun?
Cevap mı? Katlanır.
Katlanır?
Katlama , M'deki ifadeleri (filtreler, yeniden adlandırmalar, birleştirmeler vb.) ham veri kaynağına (SQL, OData vb.) karşı işlemlere dönüştürmeyi ifade eden bir terimdir. Power Query'nin gücünün büyük bir kısmı, PQ'nun kullanıcının kullanıcı arabirimi aracılığıyla gerçekleştirdiği işlemleri, kullanıcının söz konusu dilleri bilmesine gerek kalmadan karmaşık SQL veya diğer arka uç veri kaynağı dillerine dönüştürebildiği gerçeğinden kaynaklanabilir. Kullanıcılar yerel veri kaynağı işlemlerinin performans avantajını elde eder ve tüm veri kaynaklarının ortak bir komut kümesi kullanılarak dönüştürülebileceği bir kullanıcı arabiriminin kullanım kolaylığı sağlar.
Katlamanın bir parçası olarak, PQ bazen belirli bir karmayı yürütmenin en verimli yolunun verileri bir kaynaktan alıp diğerine geçirmek olduğunu belirleyebilir. Örneğin, küçük bir CSV dosyasını büyük bir SQL tablosuna katıyorsanız, büyük olasılıkla PQ'nun CSV dosyasını okumasını, SQL tablosunun tamamını okumasını ve ardından bunları yerel bilgisayarınızda birleştirmesini istemezsiniz. Büyük olasılıkla PQ'nin CSV verilerini bir SQL deyimine satır içine alıp SQL veritabanından birleştirmeyi gerçekleştirmesini istemesini istersiniz.
İstenmeyen veri sızıntısı bu şekilde gerçekleşebilir.
Dış bir OData akışının sonuçlarıyla çalışan Sosyal Güvenlik Numaralarını içeren SQL verilerine katıldığınızı ve aniden SQL'den Sosyal Güvenlik Numaralarının OData hizmetine gönderildiğini fark ettiğinizi düşünün. Kötü haber, değil mi?
Bu, Güvenlik Duvarı'nın önlemeyi amaçladığı senaryo türüdür.
Nasıl çalışır?
Güvenlik Duvarı, bir kaynaktan gelen verilerin istemeden başka bir kaynağa gönderilmesini önlemek için vardır. Yeterince basit.
Peki bu görevi nasıl başarıyor?
Bunu yapmak için M sorgularınızı bölümler adlı bir şeye böler ve sonra aşağıdaki kuralı zorunlu kılabilir:
- Bir bölüm uyumlu veri kaynaklarına erişebilir veya diğer bölümlere başvurabilir, ancak her ikisini birden başvuramayabilir.
Basit... ancak kafa karıştırıcı. Bölüm nedir? İki veri kaynağını "uyumlu" yapan nedir? Bir bölüm bir veri kaynağına erişmek ve bir bölüme başvurmak istiyorsa Güvenlik Duvarı neden ilgilenmelidir?
Şimdi bunu ayıralım ve yukarıdaki kurala birer birer göz atalım.
Bölüm nedir?
En temel düzeyde, bölüm yalnızca bir veya daha fazla sorgu adımı koleksiyonudur. Mümkün olan en ayrıntılı bölüm (en azından geçerli uygulamada) tek bir adımdır. En büyük bölümler bazen birden çok sorguyu kapsayabilir. (Daha sonra bu konu hakkında daha fazla bilgi edinin.)
Adımları bilmiyorsanız, bir sorgu seçtikten sonra Power Query Düzenleyicisi penceresinin sağında, Uygulanan Adımlar bölmesinde görüntüleyebilirsiniz. Adımlar, verilerinizi son şekline dönüştürmek için yaptığınız her şeyi takip eder.
Diğer bölümlere başvuran bölümler
Bir sorgu Güvenlik Duvarı açık olarak değerlendirildiğinde, Güvenlik Duvarı sorguyu ve tüm bağımlılıklarını bölümlere (yani adım gruplarına) böler. Bir bölüm başka bir bölümdeki bir öğeye başvursa, Güvenlik Duvarı başvuruyu adlı Value.Firewall
özel bir işleve yapılan çağrıyla değiştirir. Başka bir deyişle, Güvenlik Duvarı bölümlerin birbirine doğrudan erişmesine izin vermez. Tüm başvurular Güvenlik Duvarı'nı geçecek şekilde değiştirilir. Güvenlik Duvarı'nı ağ geçidi denetleyicisi olarak düşünün. Başka bir bölüme başvuran bir bölüm, Güvenlik Duvarı'nın bunu yapma iznini almalıdır ve Güvenlik Duvarı, başvuruda bulunılan verilere bölüme izin verilip verilmeyeceğini denetler.
Bunların hepsi oldukça soyut görünebilir, bu nedenle bir örneğe bakalım.
Sql veritabanından bazı verileri çeken Employees adlı bir sorgunuz olduğunu varsayalım. Ayrıca, Yalnızca Çalışanlar'a başvuran başka bir sorgunuz (EmployeesReference) olduğunu varsayalım.
shared Employees = let
Source = Sql.Database(…),
EmployeesTable = …
in
EmployeesTable;
shared EmployeesReference = let
Source = Employees
in
Source;
Bu sorgular iki bölüme ayrılır: biri Çalışanlar sorgusu için, diğeri de EmployeesReference sorgusu için (Çalışanlar bölümüne başvurur). Güvenlik Duvarı açık olarak değerlendirildiğinde, bu sorgular şu şekilde yeniden yazılır:
shared Employees = let
Source = Sql.Database(…),
EmployeesTable = …
in
EmployeesTable;
shared EmployeesReference = let
Source = Value.Firewall("Section1/Employees")
in
Source;
Çalışanlar sorgusuna yapılan basit başvurunun, Çalışanlar sorgusunun tam adı sağlanan çağrısıyla Value.Firewall
değiştirildiğine dikkat edin.
EmployeesReference değerlendirildiğinde, çağrısı Value.Firewall("Section1/Employees")
Güvenlik Duvarı tarafından kesilir ve artık istenen verilerin EmployeesReference bölümüne akıp akmadığını (ve nasıl) denetleyemeyeceğini denetleme şansı olur. İstediğiniz sayıda işlem yapabilir: isteği reddedebilir, istenen verileri arabelleğe alabilir (özgün veri kaynağına daha fazla katlanmayı önler) vb.
Güvenlik Duvarı, bölümler arasında akan veriler üzerinde bu şekilde denetim sahibidir.
Veri kaynaklarına doğrudan erişen bölümler
Sorgu1 sorgusunu tek adımla tanımladığınız (bu tek adımlı sorgu bir Güvenlik Duvarı bölümüne karşılık gelir) ve bu tek adımın iki veri kaynağına eriştiğine dikkat edin: SQL veritabanı tablosu ve CSV dosyası. Bölüm başvurusu olmadığından ve kesmesi için çağrı Value.Firewall
yapılmadığından Güvenlik Duvarı bununla nasıl başa çıkmaktadır? Şimdi daha önce belirtilen kuralı gözden geçirelim:
- Bir bölüm uyumlu veri kaynaklarına erişebilir veya diğer bölümlere başvurabilir, ancak her ikisini birden başvuramayabilir.
Tek bölümlü ancak iki veri kaynağı sorgunuzun çalışmasına izin verilebilmesi için iki veri kaynağının "uyumlu" olması gerekir. Başka bir deyişle, verilerin bunlar arasında çift yönlü olarak paylaşılabilmesinin uygun olması gerekir. Bu, her iki kaynağın da gizlilik düzeylerinin Genel veya her ikisinin de Kurumsal olması gerektiği anlamına gelir, çünkü bunlar her iki yönde de paylaşıma izin veren tek iki birleşimdir. Her iki kaynak da Özel olarak işaretlenirse veya biri Genel, biri Kuruluş olarak işaretlenirse ya da başka bir gizlilik düzeyi bileşimi kullanılarak işaretlenirse çift yönlü paylaşıma izin verilmez ve bu nedenle her ikisinin de aynı bölümde değerlendirilmesi güvenli değildir. Bunun yapılması güvenli olmayan veri sızıntısı gerçekleşebileceği anlamına gelir (katlama nedeniyle) ve Güvenlik Duvarı bunu önlemenin hiçbir yolu yoktur.
Aynı bölümdeki uyumsuz veri kaynaklarına erişmeye çalışırsanız ne olur?
Formula.Firewall: Query 'Query1' (step 'Source') is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination.
Umarım bu makalenin başında listelenen hata iletilerinden birini daha iyi anlarsınız.
Bu uyumluluk gereksiniminin yalnızca belirli bir bölüm içinde geçerli olduğunu unutmayın. Bir bölüm diğer bölümlere başvuruyorsa, başvuruda bulunılan bölümlerdeki veri kaynaklarının birbiriyle uyumlu olması gerekmez. Bunun nedeni, Güvenlik Duvarı'nın verileri arabelleğe alabilir ve bu da özgün veri kaynağında daha fazla katlanmasını önler. Veriler belleğe yüklenir ve hiçbir yerden gelmiş gibi değerlendirilir.
Neden ikisini de yapmayasın?
Diğer iki sorguya (yani iki bölüme) erişen bir adımla (bir bölüme karşılık gelecek) bir sorgu tanımladığınız varsayalım. Aynı adımda bir SQL veritabanına doğrudan erişmek isterseniz ne olur? Bölüm neden diğer bölümlere başvuramıyor ve uyumlu veri kaynaklarına doğrudan erişemiyor?
Daha önce gördüğünüz gibi, bir bölüm başka bir bölüme başvurduğunda, Güvenlik Duvarı bölüme akan tüm veriler için ağ geçidi denetleyicisi işlevi görür. Bunu yapmak için, hangi verilere izin verileceği denetlenmelidir. Bölüm içinde erişilen veri kaynakları varsa ve diğer bölümlerden veri akışı yapılıyorsa, içeri akan veriler şirket içinde erişilen veri kaynaklarından birine bilgi sahibi olmadan sızdırılabileceğinden ağ geçidi denetleyicisi olma özelliğini kaybeder. Bu nedenle Güvenlik Duvarı, diğer bölümlere erişen bir bölümün herhangi bir veri kaynağına doğrudan erişmesine izin verilmemesini önler.
Peki bir bölüm diğer bölümlere başvurmaya ve veri kaynaklarına doğrudan erişmeye çalışırsa ne olur?
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.
Artık bu makalenin başında listelenen diğer hata iletisini daha iyi anlayacağınızı umuyoruz.
Ayrıntılı bölümler
Yukarıdaki bilgilerden tahmin edebilirsiniz, sorguların nasıl bölümlendiği inanılmaz derecede önemli olur. Diğer sorgulara başvuran bazı adımlarınız ve veri kaynaklarına erişen diğer adımlarınız varsa, artık bölüm sınırlarını belirli yerlerde çizmenin Güvenlik Duvarı hatalarına neden olacağını ve bunları başka yerlerde çizmenin sorgunuzun düzgün çalışmasına olanak tanıdığını umuyoruz.
Peki sorgular tam olarak nasıl bölümlenebilir?
Bu bölüm, güvenlik duvarı hatalarını neden gördüğünüzu anlamak ve bunların nasıl çözüleceğini (mümkün olduğunda) anlamak için büyük olasılıkla en önemli bölümdür.
Bölümleme mantığının üst düzey bir özeti aşağıda verilmiştır.
- İlk Bölümleme
- Her sorgudaki her adım için bir bölüm oluşturur
- Statik Aşama
- Bu aşama değerlendirme sonuçlarına bağlı değildir. Bunun yerine sorguların nasıl yapılandırıldığına bağlıdır.
- Parametre Kırpma
- Parametre-esque bölümlerini, yani şu bölümleri kırpıyor:
- Diğer bölümlere başvurmaz
- İşlev çağrıları içermez
- Döngüsel değildir (başka bir ifadeyle kendisine başvurmaz)
- Bir bölümün "kaldırılmasının", diğer bölümlerin başvurduğunu etkin bir şekilde içerdiğini unutmayın.
- Parametre bölümlerini kırpmak, "bölüm veri kaynaklarına ve diğer adımlara başvuramıyor" hataları atmak yerine veri kaynağı işlev çağrıları (örneğin,
Web.Contents(myUrl)
) içinde kullanılan parametre başvurularının çalışmasını sağlar.
- Parametre-esque bölümlerini, yani şu bölümleri kırpıyor:
- Gruplandırma (Statik)
- Bölümler, aşağıdan yukarıya bağımlılık sırasına göre birleştirilir. Sonuçta elde edilen birleştirilmiş bölümlerde aşağıdakiler ayrı olacaktır:
- Farklı sorgulardaki bölümler
- Diğer bölümlere başvurmayen bölümler (ve bu nedenle bir veri kaynağına erişmesine izin verilir)
- Diğer bölümlere başvuran bölümler (ve bu nedenle veri kaynağına erişmesi yasaktır)
- Bölümler, aşağıdan yukarıya bağımlılık sırasına göre birleştirilir. Sonuçta elde edilen birleştirilmiş bölümlerde aşağıdakiler ayrı olacaktır:
- Parametre Kırpma
- Bu aşama değerlendirme sonuçlarına bağlı değildir. Bunun yerine sorguların nasıl yapılandırıldığına bağlıdır.
- Dinamik Aşama
- Bu aşama, çeşitli bölümler tarafından erişilen veri kaynakları hakkındaki bilgiler de dahil olmak üzere değerlendirme sonuçlarına bağlıdır.
- Kesme
- Aşağıdaki tüm gereksinimleri karşılayan bölümleri kırpılır:
- Hiçbir veri kaynağına erişmez
- Veri kaynaklarına erişen bölümlere başvurmaz
- Döngüsel değil
- Aşağıdaki tüm gereksinimleri karşılayan bölümleri kırpılır:
- Gruplandırma (Dinamik)
- Artık gereksiz bölümler kırpıldığına göre, mümkün olduğunca büyük Kaynak bölümleri oluşturmayı deneyin. Bu işlem, yukarıdaki statik gruplandırma aşamasında açıklanan kuralların aynısını kullanarak bölümleri birleştirerek yapılır.
Tüm bunlar ne anlama geliyor?
Yukarıda ortaya konan karmaşık mantığın nasıl çalıştığını göstermek için bir örneği inceleyelim.
Örnek bir senaryo aşağıda verilmiştır. Bir metin dosyasının (Kişiler) SQL veritabanı (Çalışanlar) ile oldukça basit bir şekilde birleştirilmesidir ve BURADA SQL sunucusu bir parametredir (DbServer).
Üç sorgu
Bu örnekte kullanılan üç sorgunun M kodu aşağıda verilmiştır.
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";
Bağımlılıkları gösteren daha üst düzey bir görünüm aşağıdadır.
Bölümleyelim
Biraz yakınlaştıralım ve resme adımları ekleyelim ve bölümleme mantığında gezinmeye başlayalım. İlk güvenlik duvarı bölümlerini yeşil olarak gösteren üç sorgunun diyagramı aşağıdadır. Her adımın kendi bölümünde başladığına dikkat edin.
Ardından parametre bölümlerini kırpacağız. Bu nedenle, DbServer örtük olarak Kaynak bölümüne eklenir.
Şimdi statik gruplandırma gerçekleştiriyoruz. Bu, ayrı sorgulardaki bölümler (örneğin, Çalışanların son iki adımının Kişiler adımlarıyla gruplandırılmaz) ve diğer bölümlere başvuran bölümler (Çalışanların son iki adımı gibi) ile olmayan bölümler (Çalışanların ilk üç adımı gibi) arasındaki ayrımı korur.
Şimdi dinamik aşamaya giriyoruz. Bu aşamada, yukarıdaki statik bölümler değerlendirilir. Hiçbir veri kaynağına erişmeyen bölümler kırpılır. Ardından bölümler, mümkün olduğunca büyük kaynak bölümler oluşturmak için gruplandırılır. Ancak, bu örnek senaryoda, kalan tüm bölümler veri kaynaklarına erişiyor ve gerçekleştirilebilecek başka gruplandırma yok. Bu nedenle örneğimizdeki bölümler bu aşamada değişmez.
Hadi rol yapalım.
Ancak çizim açısından, bir metin dosyasından gelmek yerine Kişiler sorgusunun M'de sabit kodlanmış olması durumunda (belki de Verileri Girin iletişim kutusu aracılığıyla) neler olabileceğine bakalım.
Bu durumda, Kişiler sorgusu hiçbir veri kaynağına erişemez. Böylece, dinamik fazın ilk bölümünde kırpılır.
Kişiler bölümü kaldırıldıktan sonra, Çalışanlar'ın son iki adımı, Çalışanlar'ın ilk üç adımını içeren bölüm dışında hiçbir bölüme başvurmaz. Bu nedenle, iki bölüm gruplandırılır.
Sonuçta elde edilen bölüm şöyle görünür.
Örnek: Bir veri kaynağından diğerine veri geçirme
Tamam, bu kadar soyut açıklama yeter. Güvenlik duvarı hatasıyla karşılaşma olasılığınız olan yaygın bir senaryoya ve bunu çözme adımlarına göz atalım.
Northwind OData hizmetinden bir şirket adı aramak ve ardından Bing araması yapmak için şirket adını kullanmak istediğinizi düşünün.
İlk olarak, şirket adını almak için bir Şirket sorgusu oluşturursunuz.
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
Ardından, Şirket'e başvuran ve Bing'e geçiren bir Arama sorgusu oluşturacaksınız.
let
Source = Text.FromBinary(Web.Contents("https://www.bing.com/search?q=" & Company))
in
Source
Bu noktada başın belaya girer. Arama'nın değerlendirilmesi bir Güvenlik Duvarı hatası oluşturur.
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.
Bunun nedeni, Aramanın Kaynak adımının bir veri kaynağına (bing.com) ve ayrıca başka bir sorguya/bölüme (Şirket) başvurmasıdır. Yukarıda belirtilen kuralı ihlal ediyor ("bir bölüm uyumlu veri kaynaklarına erişebilir veya diğer bölümlere başvurabilir, ancak her ikisini birden erişmeyebilir").
Ne yapmalı? Bir seçenek, Güvenlik Duvarı'nı tamamen devre dışı bırakmaktır (Gizlilik Düzeylerini Yoksay ve potansiyel olarak performansı geliştirin etiketli Gizlilik seçeneği aracılığıyla). Peki ya Güvenlik Duvarı'nı etkin bırakmak istiyorsanız?
Güvenlik Duvarı'nı devre dışı bırakmadan hatayı çözmek için Şirket ve Arama'yı tek bir sorguda birleştirebilirsiniz, örneğin:
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
Artık her şey tek bir bölümde gerçekleşiyor. İki veri kaynağının gizlilik düzeylerinin uyumlu olduğunu varsayarsak, Güvenlik Duvarı artık mutlu olmalıdır ve artık bir hata alamayacaksınız.
Bu bir sarma.
Bu konuda söylenebilecek çok daha fazla şey olsa da, bu giriş makalesi zaten yeterince uzun. Umarım güvenlik duvarını daha iyi anlamanıza yardımcı olur ve gelecekte karşılaştığınızda Güvenlik duvarı hatalarını anlamanıza ve düzeltmenize yardımcı olur.