Custom Roles and Entities¶
When creating a module, you can define custom data entities and custom module roles. Both are configured in a JSON file and are used to build the module-specific permission model.
How It Works¶
datadefines the custom entities your module works with.rolesdefines which CRUD actions a role can execute on those entities.- Each custom module role is mapped to a platform role via
baseRoles. - If a user has that platform role, the corresponding module role is included in the module permission token.
Updates for already published modules
If the roles JSON is updated after a module is already published, the platform must iterate through all installed module instances. Depending on the scope of the change and the number of installations, there can be a delay between publish and when the updated permissions are available in the module.
Available Base Roles¶
- Organization level:
OrganizationAdmin,OrganizationMember - Location level:
FarmManager,Agronomist,Advisor,FarmWorker
All of these roles can be used as baseRoles values. Currently, module roles are still mapped only to organizationId, because locationId is not included in the module permission token yet.
JSON Structure¶
The configuration file contains two top-level arrays:
data: List of module entities (name, intention, visibility, referenced API)roles: List of module roles with mappedbaseRolesand CRUD permissions
Module-to-module communication
internalOnly and environmentVariableKey are required for module-to-module communication.
internalOnly: falseallows other modules to query and share this module's data entities.- If this feature is used, a shared
environmentVariableKeymust be configured so the platform can route requests from other modules to the correct backend.
{
"data": [
{
"name": "Season",
"intention": "datatype to exchange information about seasons",
"internalOnly": false,
"environmentVariableKey": "SEASON_API"
},
{
"name": "BlockPlantLayout",
"intention": "datatype to exchange information about block plant layouts",
"internalOnly": false,
"environmentVariableKey": "SEASON_API"
}
],
"roles": [
{
"name": "SeasonAdmin",
"baseRoles": ["OrganizationAdmin", "FarmManager", "Agronomist"],
"permissions": {
"create": ["Season", "BlockPlantLayout"],
"read": ["Season", "BlockPlantLayout"],
"update": ["Season", "BlockPlantLayout"],
"delete": ["Season", "BlockPlantLayout"]
}
},
{
"name": "SeasonReader",
"baseRoles": ["Advisor"],
"permissions": {
"create": [],
"read": ["Season", "BlockPlantLayout"],
"update": [],
"delete": []
}
}
]
}
Reserved entity names
Do not use platform-internal entity names for custom module entities. For example, names like season or blockPlantLayout are reserved and must not be reused.
Module Permission Token Example (FarmManager)¶
Based on the permission.json example above, a user with the platform role FarmManager would receive the mapped custom module role SeasonAdmin.
{
"tokenType": "HvPlattformToken",
"ModuleRolesAndPermissions": {
"FarmOrganizationId": "00000000-0000-0000-0000-000000000000",
"UserId": "00000000-0000-0000-0000-000000000000",
"ModuleId": "00000000-0000-0000-0000-000000000000",
"RoleNames": ["SeasonAdmin"],
"ExecuteEndpointPermissionNames": [
"season-create",
"season-read",
"season-update",
"season-delete",
"blockplantlayout-create",
"blockplantlayout-read",
"blockplantlayout-update",
"blockplantlayout-delete"
],
"DataAreaEndPointPermissionNames": ["FarmOrganization"]
}
}