Proposal summary
- Create roles in keycloak which give permission to view the details of companies
- Assign these roles to Zenmo and Energieke Region personnel but not to civil servants
- Implement permission checks in the model when showing sensitive company data
Background
In the Drechtsteden project, civil servants of municipalities should not have access to data of individual companies. The consequence is that they currently can't use the interactive LUX Energy Hub models.
This pertains to the following 7 models:
- Alblasserdam
- Hardinxveld-Giessendam
- Sliedrecht
- Dordrecht
- Papendrecht
- Zwijndrecht
- Hendrik-Ido-Ambacht
In the long term, I wish we eventually have a more comprehensive access control strategy based on resources and scopes (lux-website#306). However this is a big project and I don't oversee all the implications yet to create a minimal version.
Constraints
To keep this a quick win we preferably stay close to the currently implemented structure:
- Communicating user privileges to the simulation model is done through the user ID token
- The user ID token can only contain roles
Implementation
Keycloak
Create a new client "lux_access_roles". Add the following roles:
- alblasserdam_view_company_details
- hardinxveld_giessendam_view_company_details
- sliedrecht_view_company_details
- dordrecht_view_company_details
- papendrecht_view_company_details
- zwijndrecht_view_company_details
- hendrik_ido_ambacht_view_company_details
Assign these roles to Zenmo and Energieke Regio personnel but not to the civil servants.
Library
Modify the existing but unused library zero-access to check the roles in client "lux_access_roles".
Package a JAR file to import in the Drechtsteden model.
Example library usage:
import static energy.lux.access.LuxAccessKt.hasRole;
if (hasRole("zwijndrecht_view_company_details", idToken)) {
// show GUI element
}
Relevant code:
Generic model code
To zerointerfaceloader add a new interface:
interface AccessPolicy {
boolean mayViewCompanyDetails();
AccessPolicy AllowAll = () -> true;
AccessPolicy DenyAll = () -> false;
}
To zerointerfaceloader.Zero_Interface add a new parameter p_accessPolicy with a default value AccessPolicy.AllowAll
In places where sensitive data is shown the UI code calls p_accessPolicy.mayViewCompanyDetails() beforehand. If this returns false, display a placeholder or alert dialog box informing the user that he may not view this part of the model.
Relevant code:
|
uI_Company.va_companyUI.navigateTo(); |
|
uI_Company = add_pop_UI_Company(); |
- Probably many more places....
Drechsteden model code
- In
Project_selection.xlsx add a new column view_company_details_role filled with the roles above.
- Add a new class:
import static energy.lux.access.LuxAccessKt.hasRole;
@lombok.Builder
class RoleBasedAccessPolicy implements AccessPolicy {
private String viewCompanyDetailsRole;
private String userIdToken;
@Override
public boolean mayViewCompanyDetails() {
return hasRole(viewCompanyDetailsRole, userIdToken);
}
}
- Bring the class and parameters together in startup/loader code:
project_interface.p_accessPolicy = RoleBasedAccessPolicy
.builder()
.viewCompanyDetailsRole(...)
.userIdToken(...)
.build();
Model Development Experience (DX)
We need some easy way to obtain an ID token, for example Zenmo/lux-website#230 -> asked Kofi to work on this.
We don't want to leak it so it doesn't seem like a good idea to put it in a parameter when developing locally. Correct?
Maybe we can ask for it in a popup and then write it to a file which is in .gitignore and not uploaded to the cloud.
I general to test if the right things are hidden you can set the AccessPolicy to DenyAll.
Throughts or ideas?
Proposal summary
Background
In the Drechtsteden project, civil servants of municipalities should not have access to data of individual companies. The consequence is that they currently can't use the interactive LUX Energy Hub models.
This pertains to the following 7 models:
In the long term, I wish we eventually have a more comprehensive access control strategy based on resources and scopes (lux-website#306). However this is a big project and I don't oversee all the implications yet to create a minimal version.
Constraints
To keep this a quick win we preferably stay close to the currently implemented structure:
Implementation
Keycloak
Create a new client "lux_access_roles". Add the following roles:
Assign these roles to Zenmo and Energieke Regio personnel but not to the civil servants.
Library
Modify the existing but unused library zero-access to check the roles in client "lux_access_roles".
Package a JAR file to import in the Drechtsteden model.
Example library usage:
Relevant code:
Generic model code
To
zerointerfaceloaderadd a new interface:To
zerointerfaceloader.Zero_Interfaceadd a new parameterp_accessPolicywith a default valueAccessPolicy.AllowAllIn places where sensitive data is shown the UI code calls
p_accessPolicy.mayViewCompanyDetails()beforehand. If this returns false, display a placeholder or alert dialog box informing the user that he may not view this part of the model.Relevant code:
zero_Interface-Loader/_alp/Agents/Zero_Interface/Levels/Level.level.xml
Line 1010 in f9fe8db
zero_Interface-Loader/_alp/Agents/Zero_Interface/Code/Functions.java
Line 3033 in f9fe8db
Drechsteden model code
Project_selection.xlsxadd a new columnview_company_details_rolefilled with the roles above.Model Development Experience (DX)
We need some easy way to obtain an ID token, for example Zenmo/lux-website#230 -> asked Kofi to work on this.
We don't want to leak it so it doesn't seem like a good idea to put it in a parameter when developing locally. Correct?
Maybe we can ask for it in a popup and then write it to a file which is in .gitignore and not uploaded to the cloud.
I general to test if the right things are hidden you can set the
AccessPolicytoDenyAll.Throughts or ideas?