Skip to content

User role to view company details #279

@Erikvv

Description

@Erikvv

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:

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?

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions