[{"data":1,"prerenderedAt":667},["ShallowReactive",2],{"navigation_docs_en":3,"-en-using-dashboards-rls":241,"-en-using-dashboards-rls-surround":664},[4,17,42,206,232],{"title":5,"redirect":6,"path":7,"stem":8,"children":9,"page":16},"Introduction","\u002Fen\u002Fintroduction\u002Fintroduction","\u002Fen\u002Fintroduction","en\u002F1.introduction",[10,12],{"title":5,"path":6,"stem":11},"en\u002F1.introduction\u002F1.introduction",{"title":13,"path":14,"stem":15},"Prerequisites","\u002Fen\u002Fintroduction\u002Fprerequisites","en\u002F1.introduction\u002F2.prerequisites",false,{"title":18,"redirect":19,"path":20,"stem":21,"children":22,"page":16},"Installation","\u002Fen\u002Finstallation\u002Fsetup","\u002Fen\u002Finstallation","en\u002F2.installation",[23,26,30,34,38],{"title":24,"path":19,"stem":25},"Machine set-up","en\u002F2.installation\u002F1.setup",{"title":27,"path":28,"stem":29},"A Tale of Two Repos","\u002Fen\u002Finstallation\u002Ftale-repos","en\u002F2.installation\u002F2.tale-repos",{"title":31,"path":32,"stem":33},"Database connection","\u002Fen\u002Finstallation\u002Fdbt-profile","en\u002F2.installation\u002F3.dbt-profile",{"title":35,"path":36,"stem":37},"Smoke-testing","\u002Fen\u002Finstallation\u002Fsmoke-testing","en\u002F2.installation\u002F4.smoke-testing",{"title":39,"path":40,"stem":41},"What now ?","\u002Fen\u002Finstallation\u002Fwhat-now","en\u002F2.installation\u002F5.what-now",{"title":43,"path":44,"stem":45,"children":46,"page":16},"Users Guide","\u002Fen\u002Fusing","en\u002F3.using",[47,50,54,88,188,202],{"title":5,"path":48,"stem":49},"\u002Fen\u002Fusing\u002Fintroduction","en\u002F3.using\u002F1.introduction",{"title":51,"path":52,"stem":53},"Running the ETL","\u002Fen\u002Fusing\u002Frunning","en\u002F3.using\u002F2.running",{"title":55,"path":56,"stem":57,"children":58,"page":16},"Configuration","\u002Fen\u002Fusing\u002Fconfiguration","en\u002F3.using\u002F3.configuration",[59,72,76,80,84],{"title":60,"path":61,"stem":62,"children":63,"page":16},"Architecture","\u002Fen\u002Fusing\u002Fconfiguration\u002Farchitecture","en\u002F3.using\u002F3.configuration\u002F1.architecture",[64,68],{"title":65,"path":66,"stem":67},"Overview","\u002Fen\u002Fusing\u002Fconfiguration\u002Farchitecture\u002Foverview","en\u002F3.using\u002F3.configuration\u002F1.architecture\u002F1.overview",{"title":69,"path":70,"stem":71},"Marts and reporting layer","\u002Fen\u002Fusing\u002Fconfiguration\u002Farchitecture\u002Fmarts-reporting","en\u002F3.using\u002F3.configuration\u002F1.architecture\u002F2.marts-reporting",{"title":73,"path":74,"stem":75},"Linking the databases","\u002Fen\u002Fusing\u002Fconfiguration\u002Fdatabases","en\u002F3.using\u002F3.configuration\u002F2.databases",{"title":77,"path":78,"stem":79},"Adapters and seeds","\u002Fen\u002Fusing\u002Fconfiguration\u002Fadapts-seeds","en\u002F3.using\u002F3.configuration\u002F3.adapts-seeds",{"title":81,"path":82,"stem":83},"Enabling a resource","\u002Fen\u002Fusing\u002Fconfiguration\u002Fenabling","en\u002F3.using\u002F3.configuration\u002F4.enabling",{"title":85,"path":86,"stem":87},"Overriding","\u002Fen\u002Fusing\u002Fconfiguration\u002Foverriding","en\u002F3.using\u002F3.configuration\u002F5.overriding",{"title":89,"redirect":90,"path":91,"stem":92,"children":93,"page":16},"Dashboards","\u002Fen\u002Fusing\u002F","\u002Fen\u002Fusing\u002Fdashboards","en\u002F3.using\u002F4.dashboards",[94,97,126,167,176,184],{"title":5,"path":95,"stem":96},"\u002Fen\u002Fusing\u002Fdashboards\u002Fintroduction","en\u002F3.using\u002F4.dashboards\u002F1.introduction",{"title":98,"redirect":99,"path":99,"stem":100,"children":101,"page":16},"Human resources","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr","en\u002F3.using\u002F4.dashboards\u002F2. hr",[102,106,110,114,118,122],{"title":103,"path":104,"stem":105},"Employees leaves","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr\u002Femp_conge","en\u002F3.using\u002F4.dashboards\u002F2. hr\u002F1.emp_conge",{"title":107,"path":108,"stem":109},"Active employees","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr\u002Fempl_actif","en\u002F3.using\u002F4.dashboards\u002F2. hr\u002F2.empl_actif",{"title":111,"path":112,"stem":113},"Retirement","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr\u002Fretirement","en\u002F3.using\u002F4.dashboards\u002F2. hr\u002F3.retirement",{"title":115,"path":116,"stem":117},"Efficacité","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr\u002Fefficacite","en\u002F3.using\u002F4.dashboards\u002F2. hr\u002F4.efficacite",{"title":119,"path":120,"stem":121},"Absences des employé(e)s","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr\u002Femp_abs","en\u002F3.using\u002F4.dashboards\u002F2. hr\u002F5.emp_abs",{"title":123,"path":124,"stem":125},"Resignation","\u002Fen\u002Fusing\u002Fdashboards\u002Fhr\u002Fresignation","en\u002F3.using\u002F4.dashboards\u002F2. hr\u002F6.resignation",{"title":127,"redirect":128,"path":128,"stem":129,"children":130,"page":16},"Educational service","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv",[131,135,139,143,147,151,155,159,163],{"title":132,"path":133,"stem":134},"Res epreuves","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fres_epreuves","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F1.res_epreuves",{"title":136,"path":137,"stem":138},"Students results monitoring","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fsuivi_resultats","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F2.suivi_resultats",{"title":140,"path":141,"stem":142},"Students headcount","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Feffectif_css","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F3.effectif_css",{"title":144,"path":145,"stem":146},"Students absenteeism","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fchronic_absenteeism","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F4.chronic_absenteeism",{"title":148,"path":149,"stem":150},"Academic results","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fres_scolaires","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F5.res_scolaires",{"title":152,"path":153,"stem":154},"Predictive modelling - aggregated","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fpredictive-aggregated","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F6.predictive-aggregated",{"title":156,"path":157,"stem":158},"PEVR","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fpevr","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F7.pevr",{"title":160,"path":161,"stem":162},"Absenteeism","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fabsenteeism","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F8.absenteeism",{"title":164,"path":165,"stem":166},"Diplôme","\u002Fen\u002Fusing\u002Fdashboards\u002Feduc-serv\u002Fdiplome","en\u002F3.using\u002F4.dashboards\u002F3.educ-serv\u002F9.diplome",{"title":168,"redirect":169,"path":169,"stem":170,"children":171,"page":16},"School organisation","\u002Fen\u002Fusing\u002Fdashboards\u002Fschool-org","en\u002F3.using\u002F4.dashboards\u002F4.school-org",[172],{"title":173,"path":174,"stem":175},"Anomalies","\u002Fen\u002Fusing\u002Fdashboards\u002Fschool-org\u002Fanomalies","en\u002F3.using\u002F4.dashboards\u002F4.school-org\u002F1.anomalies",{"title":177,"path":178,"stem":179,"children":180,"page":16},"DirectionGenerale","\u002Fen\u002Fusing\u002Fdashboards\u002Fdirection_generale","en\u002F3.using\u002F4.dashboards\u002F5.direction_generale",[181],{"title":156,"path":182,"stem":183},"\u002Fen\u002Fusing\u002Fdashboards\u002Fdirection_generale\u002Fpevr","en\u002F3.using\u002F4.dashboards\u002F5.direction_generale\u002F1.pevr",{"title":185,"path":186,"stem":187},"Row Level Security","\u002Fen\u002Fusing\u002Fdashboards\u002Frls","en\u002F3.using\u002F4.dashboards\u002F5.rls",{"title":189,"redirect":90,"path":190,"stem":191,"children":192,"page":16},"Data marts","\u002Fen\u002Fusing\u002Fmarts","en\u002F3.using\u002F6.marts",[193,196,199],{"title":5,"path":194,"stem":195},"\u002Fen\u002Fusing\u002Fmarts\u002Fmarts","en\u002F3.using\u002F6.marts\u002F1.marts",{"title":127,"path":197,"stem":198},"\u002Fen\u002Fusing\u002Fmarts\u002Feducational-service","en\u002F3.using\u002F6.marts\u002F2.educational-service",{"title":98,"path":200,"stem":201},"\u002Fen\u002Fusing\u002Fmarts\u002Fhuman-resources","en\u002F3.using\u002F6.marts\u002F3.human-resources",{"title":203,"path":204,"stem":205},"Production checklist","\u002Fen\u002Fusing\u002Fproduction","en\u002F3.using\u002F7.production",{"title":207,"redirect":208,"path":209,"stem":210,"children":211,"page":16},"Developers Guide","\u002Fen\u002Fcontributing\u002Fgetting-started","\u002Fen\u002Fcontributing","en\u002F4.contributing",[212,215,223],{"title":213,"path":208,"stem":214},"Getting Started","en\u002F4.contributing\u002F1.getting-started",{"title":216,"redirect":217,"path":218,"stem":219,"children":220,"page":16},"Conventions","\u002Fen\u002Fcontributing\u002Fconventions\u002Fgetting-started","\u002Fen\u002Fcontributing\u002Fconventions","en\u002F4.contributing\u002F2.conventions",[221],{"title":213,"path":217,"stem":222},"en\u002F4.contributing\u002F2.conventions\u002F1.getting-started",{"title":224,"path":225,"stem":226,"children":227,"page":16},"Docs Ref","\u002Fen\u002Fcontributing\u002Fdocs","en\u002F4.contributing\u002F99.docs",[228],{"title":229,"path":230,"stem":231},"Components","\u002Fen\u002Fcontributing\u002Fdocs\u002Fcomponents","en\u002F4.contributing\u002F99.docs\u002F1.components",{"title":233,"redirect":6,"path":234,"stem":235,"children":236,"page":16},"Migrations","\u002Fen\u002Fmigrations","en\u002F5.migrations",[237],{"title":238,"path":239,"stem":240},"V0.17 -> V0.18","\u002Fen\u002Fmigrations\u002Fv0.17_to_v0.18","en\u002F5.migrations\u002F1.v0.17_to_v0.18",{"id":242,"title":185,"body":243,"description":414,"extension":658,"links":659,"meta":660,"navigation":661,"path":186,"seo":662,"stem":187,"__hash__":663},"docs_en\u002Fen\u002F3.using\u002F4.dashboards\u002F5.rls.md",{"type":244,"value":245,"toc":643},"minimark",[246,251,255,260,264,268,271,274,278,282,291,296,304,324,328,341,451,455,458,466,471,484,488,566,570,573,597,603,615,619,622,639],[247,248,250],"alert",{"type":249},"danger","This page is a draft. It's something you will have to decipher until I find the time to complete it :(",[252,253,5],"h1",{"id":254},"introduction",[256,257,259],"h2",{"id":258},"what-is-rls","What is RLS ?",[261,262,263],"p",{},"RLS, or Row-Level Security, is a method of restricting data access in a database or business intelligence environment based on the characteristics of the user. Essentially, it allows administrators to control who can see what data within the same table or report. This is particularly valuable in environments where you have sensitive or private data that should only be accessible by certain users.",[256,265,267],{"id":266},"how-is-it-different-from-rbac","How is it different from RBAC ?",[261,269,270],{},"RLS in Power BI allows you to control access to rows of data based on the user viewing the report. This means you can create filters within roles defined in Power BI Desktop, and when users log into Power BI, they will only see data relevant to these filters.",[261,272,273],{},"RBAC, on the other hand, is broader and controls access at higher levels of the Power BI environment, not just at the data level. RBAC helps manage who has access to workspaces, reports, dashboards, and what kind of operations they can perform (like read, write, share, or delete).",[252,275,277],{"id":276},"how-to-enable-rls","How to enable RLS.",[256,279,281],{"id":280},"what-you-will-need","What you will need ?",[247,283,285,286,290],{"type":284},"info","The 'users table' must be implemented following your own business logic. In this example, we assume that user identification is done through the ",[287,288,289],"strong",{},"email address"," people use to connect to Power BI. If you are using an alternative way to authenticate people, you will have to adapt this example.",[292,293,295],"h3",{"id":294},"the-user-table","The 'user table'",[261,297,298,299,303],{},"The ",[300,301,302],"code",{},"users"," table is a table that maps all the users that will have access to the data, to the data they can see. It should be structured in the following way :",[305,306,307,314],"ul",{},[308,309,310,313],"li",{},[300,311,312],{},"user_id"," : the unique identifier of the user, which can be mapped back to an item of the Power BI authentication payload.",[308,315,316,319,320,323],{},[300,317,318],{},"scope"," : the scope of the data available to the user. This is a string that will be used to filter the ",[287,321,322],{},"reporting"," data.",[256,325,327],{"id":326},"how-to-configure-the-rls","How to configure the RLS ?",[261,329,330,331,334,335,337,338,340],{},"The RLS is implemented by adding the ",[300,332,333],{},"user_table"," to your Power BI dashboard and by (inner) joining it onto the reporting table. The ",[300,336,333],{}," can then be used to filter down data from the reporting table the user has been granted access to.\nTo do so, you will need to create a new role in your Power BI dashboard, and add a filter to the reporting table that will filter down the data based on the ",[300,339,318],{}," of the user.",[342,343,344,357,370],"ol",{},[308,345,346,347,349,350,352,353,356],{},"Ensure that your data model has the necessary columns to define RLS filters. Basically, you need a set of dimensions you want to apply RLS to, to be available in both the reporting table and the ",[300,348,333],{},". The ",[300,351,333],{}," should also include a column acting as a primary mean of identification for the user (in the example, we will be using the ",[300,354,355],{},"email"," column).",[308,358,359,360,362,363,365,366,369],{},"Import the ",[300,361,333],{}," into your Power BI dashboard, and create a relationship between the ",[300,364,333],{}," and the reporting tables. ",[287,367,368],{},"The join must be done on the scope column",".",[308,371,372,373,408,424],{},"Create and manage a role:\n",[342,374,375,385,392,402],{},[308,376,377,378,381,382,369],{},"In Power BI Desktop, click on the ",[300,379,380],{},"Model"," tab, then click on ",[300,383,384],{},"Manage Roles",[308,386,387,388,391],{},"Click on ",[300,389,390],{},"Create"," to create a new role.",[308,393,394,395,398,399,369],{},"In the ",[300,396,397],{},"Manage roles"," dialog box, enter a name for the role, and then click on ",[300,400,401],{},"Add Table Filter",[308,403,394,404,407],{},[300,405,406],{},"Table Filter DAX Expression"," dialog box, enter a DAX expression that filters the data based on the user's email address. This is done to filter the users table to the current dashboard viewer. For example, if you want to filter the data based on the user's email address, you can use the following DAX expression:",[409,410,415],"pre",{"className":411,"code":412,"language":413,"meta":414,"style":414},"language-dax shiki shiki-themes material-theme-lighter material-theme material-theme-palenight"," 'user_table'[email] = USERPRINCIPALNAME()\n","dax","",[300,416,417],{"__ignoreMap":414},[418,419,422],"span",{"class":420,"line":421},"line",1,[418,423,412],{},[342,425,427,433,439,448],{"start":426},5,[308,428,387,429,432],{},[300,430,431],{},"OK"," to save the DAX expression.",[308,434,387,435,438],{},[300,436,437],{},"Save"," to save the role.",[308,440,387,441,444,445,447],{},[300,442,443],{},"Close"," to close the ",[300,446,397],{}," dialog box.",[308,449,450],{},"Publish the report to the Power BI service.",[292,452,454],{"id":453},"example-implementing-rls-at-the-school-level","Example : implementing RLS at the school level",[261,456,457],{},"In this example, we will implement RLS to restrict access to the data based on the user's email address, so that each user can only see the data for the school they are associated with.",[459,460,462,463,465],"h4",{"id":461},"step-1-create-the-users-table","Step 1 : Create the ",[300,464,302],{}," table",[261,467,298,468,470],{},[300,469,302],{}," table should have the following columns:",[305,472,473,478],{},[308,474,475,477],{},[300,476,355],{}," : the email address of the user",[308,479,480,483],{},[300,481,482],{},"school"," : the school the user is associated with",[459,485,487],{"id":486},"step-2-implementing-rls-in-power-bi","Step 2 : Implementing RLS in Power BI",[342,489,490,514],{},[308,491,359,492,494,495,497,498,504,505,369],{},[300,493,302],{}," table into your Power BI dashboard, and create a relationship between the ",[300,496,302],{}," table and the reporting tables. ",[287,499,500,501,503],{},"The join must be done on the ",[300,502,482],{}," column",". This is the big deal: ",[287,506,507,508,510,511,513],{},"if your reporting table DOES NOT contain a ",[300,509,482],{}," column, you won't be able to join the ",[300,512,333],{}," table, and you won't be able to apply RLS to this table",[308,515,516,517,539,548],{},"Create a role :\n",[342,518,519,525,529,535],{},[308,520,377,521,381,523,369],{},[300,522,380],{},[300,524,384],{},[308,526,387,527,391],{},[300,528,390],{},[308,530,394,531,398,533,369],{},[300,532,397],{},[300,534,401],{},[308,536,394,537,407],{},[300,538,406],{},[409,540,542],{"className":411,"code":541,"language":413,"meta":414,"style":414}," user_table['email'] = USERPRINCIPALNAME()\n",[300,543,544],{"__ignoreMap":414},[418,545,546],{"class":420,"line":421},[418,547,541],{},[342,549,550,554,558,564],{"start":426},[308,551,387,552,432],{},[300,553,431],{},[308,555,387,556,438],{},[300,557,437],{},[308,559,387,560,444,562,447],{},[300,561,443],{},[300,563,397],{},[308,565,450],{},[459,567,569],{"id":568},"why-is-it-working","Why is it working ?",[261,571,572],{},"Here is what happens when a user is viewing the report, deep inside the Power BI engine:",[342,574,575,578,585,591],{},[308,576,577],{},"The user logs with his email into Power BI and the report is displayed.",[308,579,580,581,584],{},"Power BI sets ",[300,582,583],{},"USERPRINCIPALNAME()"," to the user's email.",[308,586,587,588,590],{},"The DAX expression in the role is evaluated, and the ",[300,589,333],{}," is filtered to the user's email.",[308,592,593,594,596],{},"The tables joined on the ",[300,595,333],{}," are now filtered to the user's email, and the user can only see the data for the school they are associated with.",[292,598,600,601],{"id":599},"a-note-about-userprincipalname","A note about ",[300,602,583],{},[261,604,605,607,608,611,612,614],{},[300,606,583],{}," is a DAX function that returns the ",[287,609,610],{},"currently authenticated user's email address",". This function is only available in Power BI service, and not in Power BI Desktop. When you publish the report to the Power BI service, the ",[300,613,583],{}," function will return the email address of the user viewing the report. This is useful for filtering the data based on the user's email address.",[292,616,618],{"id":617},"my-customer-wants-rls-to-work-at-school-level-but-also-at-class-level-how-can-i-do-that","My customer wants RLS to work at school level, but also at class level. How can I do that?",[247,620,621],{"type":284},"Implementing RLS on multiple columns is actually easy to do : the trick is to rewrite the multiple-columns join into a one column join (yup). \"If we don't have any issue at first, we don't have to look up for a solution\" - Confucius (maybe, I have honestly no idea, but I'm sure he would agree, cause' you know, seems to me like a pretty good idea).",[261,623,624,625,631,632,638],{},"Since Power BI doesn't handle multiple-column joins (it's only been half a century since we walked on the moon after all), you will have to concatenate the columns you want to join on into a single column. This is done by creating a new column in ",[287,626,627,628,630],{},"all your reporting and ",[300,629,333],{}," tables",". Creating one column for multiple columns can be done by simply concatenating the columns you want to join on. Of course, the concatenation order ",[287,633,634,635,637],{},"must be exactly the same in both your ",[300,636,333],{}," and your reporting table"," (otherwise the join won't work). If you want to show off how smart you are, you can do it in SQL BEFORE importing your data and use the hash of the concatenation as the join column instead of the concatenation itself (to save some tiny bits of precious memory).",[640,641,642],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":414,"searchDepth":644,"depth":644,"links":645},2,[646,647,648,652],{"id":258,"depth":644,"text":259},{"id":266,"depth":644,"text":267},{"id":280,"depth":644,"text":281,"children":649},[650],{"id":294,"depth":651,"text":295},3,{"id":326,"depth":644,"text":327,"children":653},[654,655,657],{"id":453,"depth":651,"text":454},{"id":599,"depth":651,"text":656},"A note about USERPRINCIPALNAME()",{"id":617,"depth":651,"text":618},"md",null,{},true,{"title":185,"description":414},"cxcOWyZnwQA7vEN7b-GG4JV6QCwKPDxY3p75V85-Qtk",[665,666],{"title":156,"path":182,"stem":183,"description":414,"children":-1},{"title":5,"path":194,"stem":195,"description":414,"children":-1},1781106582682]