Business Professionals
Power BI | Power Pivot | Power Query | DAX
Cloud Flows | RPA | AI Builder | Copilot
60+ Formulas | Data Stories | Advanced Reporting & Modeling
VB Programming | Report Automation |
MS-Office Automation
Techno-Business Professionals
Power BI | Power Query | Advanced DAX | SQL - Query &
Programming
Microsoft Fabric | Power BI | Power Query | Advanced DAX |
SQL - Query & Programming
Power BI | Power Apps | Power Automate | Copilot Studio | Power Pages | Dataverse
Microsoft Power Apps | Microsoft Power Automate
Power BI | Adv. DAX | SQL (Query & Programming) |
VBA | Python | Web Scrapping | API Integration
Power BI | Power Apps | Power Automate |
SQL (Query & Programming)
Power BI | Adv. DAX | Power Apps | Power Automate |
SQL (Query & Programming) | VBA | Python | Web Scrapping | API Integration
Power Apps | Power Automate | SQL | VBA | Python |
Web Scraping | RPA | API Integration
Technology Professionals
Power BI | DAX | SQL | ETL with SSIS | SSAS | VBA | Python
Power BI | SQL | Azure Data Lake | Synapse Analytics |
Data Factory | Databricks | Power Apps | Power Automate |
Azure Analysis Services
Microsoft Fabric | Power BI | SQL | Lakehouse |
Data Factory (Pipelines) | Dataflows Gen2 | KQL | Delta Tables | Power Apps | Power Automate
Power BI | Power Apps | Power Automate | SQL | VBA | Python | API Integration
Power BI | Advanced DAX | Databricks | SQL | Lakehouse Architecture
Business Professionals
Power BI | Power Pivot | Power Query | DAX
Cloud Flows | RPA | AI Builder | Copilot
60+ Formulas | Data Stories | Advanced Reporting & Modeling
VB Programming | Report Automation |
MS-Office Automation
Techno-Business Professionals
Power BI | Power Query | Advanced DAX | SQL - Query &
Programming
Microsoft Fabric | Power BI | Power Query | Advanced DAX |
SQL - Query & Programming
Power BI | Power Apps | Power Automate | Copilot Studio | Power Pages | Dataverse
Microsoft Power Apps | Microsoft Power Automate
Power BI | Adv. DAX | SQL (Query & Programming) |
VBA | Web Scrapping | API Integration
Power BI | Power Apps | Power Automate |
SQL (Query & Programming)
Power BI | Adv. DAX | Power Apps | Power Automate |
SQL (Query & Programming) | VBA | Web Scrapping | API Integration
Power Apps | Power Automate | SQL | VBA |
Web Scraping | RPA | API Integration
Technology Professionals
Power BI | DAX | SQL | ETL with SSIS | SSAS | VBA
Power BI | SQL | Azure Data Lake | Synapse Analytics |
Data Factory | Azure Analysis Services
Microsoft Fabric | Power BI | SQL | Lakehouse |
Data Factory (Pipelines) | Dataflows Gen2 | KQL | Delta Tables
Power BI | Power Apps | Power Automate | SQL | VBA | API Integration
Power BI | Advanced DAX | Databricks | SQL | Lakehouse Architecture
The sales performance dashboard looks great in the Monday stand-up, until someone zooms in and realises you can guess which underperforming bar belongs to which salesperson. Your model only has employee IDs, but combined with filters and drill-through, identities suddenly become obvious. This post shows how to spot those AVG (GDPR) privacy leaks in Power BI and how to redesign your model, visuals, and sharing so your dashboards stay useful without exposing personal data.
You’re building a sales performance report for a commercial team:
SalespersonID, Name, Email, Manager, HireDateThe request from management:
The report works. People love it.
Then the privacy officer joins a demo and asks:
“Can you see individual performance per salesperson? Is this shared with everyone in the organisation?”
You answer “Yes, but it’s just internal.”
Now you’re in AVG territory:
Let’s walk through how to turn this into a compliant, privacy-aware setup without killing the usefulness of the report.
Before you fix anything, you need to know what counts as personal data under AVG.
Fields that directly identify a person:
FirstName, LastName, FullName)Email, Phone, Mobile)EmployeeID, UserPrincipalName, login names)Even if you removed names, a person can be identifiable when:
SalespersonID that HR uses)In our sales dashboard scenario, the risky fields are:
Salesperson[Name]Salesperson[Email]Salesperson[EmployeeNumber]Create a quick checklist for each table:
If the answer to the last question is “no”, that column should not be in the model at all.
AVG doesn’t forbid all personal data in reporting. It forces you to justify it.
For each measure and visual, ask two questions:
In our scenario, we can split the requirements:
Team-level report for all sales staff:
Manager report for line managers and HR:
This naturally leads to:
Trying to satisfy both use cases in one report is where most leaks start.
Where you don’t need individual identities, strip them out or mask them.
For the team-level report, simply don’t load names and emails.
In Power Query, keep only what you need:
let
Source = Sql.Database("SQLSERVER01", "SalesDW"),
SalespersonRaw = Source{[Schema="dbo",Item="DimSalesperson"]}[Data],
Salesperson = Table.SelectColumns(
SalespersonRaw,
{"SalespersonKey", "Region", "Team"} // no Name, Email, EmployeeNumber
)
in
Salesperson
Now your visuals can’t show what isn’t there.
If you still need some notion of “person” but not who exactly, you can:
Senior, Junior)Rep 1, Rep 2)Example in Power Query to create pseudonyms:
let
Source = Sql.Database("SQLSERVER01", "SalesDW"),
SalespersonRaw = Source{[Schema="dbo",Item="DimSalesperson"]}[Data],
IndexAdded = Table.AddIndexColumn(SalespersonRaw, "PseudoID", 1, 1, Int64.Type),
Pseudonymized = Table.TransformColumns(
IndexAdded,
{{"PseudoID", each "Rep " & Text.From(_), type text}}
),
Result = Table.SelectColumns(Pseudonymized, {"SalespersonKey", "PseudoID", "Region", "Team"})
in
Result
Your visuals can now show PseudoID instead of real names.
Instead of loading row-level transactions, load pre-aggregated data:
SELECT
s.Region,
s.Team,
CAST(s.SaleDate AS date) AS SaleDate,
SUM(s.SalesAmount) AS TotalSales,
COUNT(DISTINCT s.SalespersonKey) AS SalespeopleCount
FROM FactSales s
GROUP BY
s.Region,
s.Team,
CAST(s.SaleDate AS date);
This way, your Power BI model never even sees individual-level performance.
For the manager report, you may have a legitimate reason to show individual performance. Here the leak risk moves from data content to data access.
Row-Level Security (RLS) is your main tool.
In our scenario:
You can model this with a DimUser table linked to Salesperson.
Example structure:
DimUser:
UserPrincipalNameRole (Sales, Manager, HR)SalespersonKey (for individual mapping)Team (for manager mapping)DimSalesperson:
SalespersonKeyTeamName-- On DimSalesperson
UserPrincipalName = USERPRINCIPALNAME()
If you have a bridge table:
-- RLS on DimUser
DimUser[UserPrincipalName] = USERPRINCIPALNAME()
-- RLS on DimUser
DimUser[UserPrincipalName] = USERPRINCIPALNAME()
&& DimUser[Role] = "Manager"
Then rely on relationships so that only matching teams in DimSalesperson are visible.
You can create a separate role with no filter on DimSalesperson, but assign it only to a small, controlled group.
Always test with “View as” in Power BI Service and with real user accounts where possible.
Even if your data model is anonymised, visuals can still leak identity indirectly.
If there is only one salesperson in Region = North and you show Sales per Region, then everyone who knows the org structure knows whose performance that is.
Mitigation options:
Example DAX measure to suppress small groups:
Sales (Suppressed) =
VAR DistinctSalespeople = DISTINCTCOUNT(Sales[SalespersonKey])
RETURN
IF(
DistinctSalespeople < 3,
BLANK(),
[Total Sales]
)
Use this measure in visuals instead of raw [Total Sales].
The main report might be aggregated, but:
In our scenario, the team-level report should:
Keep the detailed drill-through pages in the manager report only.
A lot of AVG risk in Power BI is not the model, but what people do with it.
For the aggregated team report:
For the manager report:
Exports can break all your careful RLS and aggregation if misconfigured.
Check per report:
If your organisation allows it, consider:
Have a simple document (even a PowerPoint slide) that shows:
This isn’t just for audits; it helps you avoid accidental reuse of sensitive datasets in new reports.
To avoid fighting fires later, make privacy checks a standard part of your workflow.
For every new report:
With your team, define:
HR_, PII_)In our sales dashboard scenario, this would mean:
Sales_Team_Aggregated.pbix and Sales_Manager_Detail.pbixBefore you publish your next Power BI report, do a quick pass over your model and visuals and ask: “Could someone reasonably identify a specific person from this?” If the answer is anything other than a clear “no”, either aggregate or anonymise the data, and lock down access with RLS and sharing controls before your privacy officer asks the question for you.
This article reflects how Power BI teams can move from ad-hoc, person-level reporting to structured, privacy-aware designs that separate aggregated and sensitive views, especially in organisations where AVG/GDPR compliance and internal transparency need to coexist.
Professionals who want to apply these patterns to their own data can explore Excelgoodies' Power BI Reporting programme - taught live by instructors, with certification awarded once a real project is running at work.
Insights compiled through ongoing industry research and discussions within the Excelgoodies Analytics Community.
Power BI
New
Next Batches Now Live
Power BI
SQL
Power Apps
Power Automate
Microsoft Fabrics
Azure Data Engineering