Table of Contents |
---|
Overview
One outcome of a recent investigation into misleading permission set configuration (
Jira Legacy | ||||||
---|---|---|---|---|---|---|
|
Naming Conventions
- Name the permission sets appropriately, e.g. avoid inclusion of POST/PUT/DELETE permissions in "
*.view
" permission sets.GoodClear:
Code Block language js { "permissionName": "ui-erm-usage.view-create-edit", "displayName": "eUsage: Can view, create and edit usage data providers and COUNTER reports", "id": "ade748af-66b5-4584-a319-3cac20899241", "description": "Can view, create and edit usage data providers and COUNTER reports", "tags": [], "subPermissions": [ "module.erm-usage.enabled", "usagedataproviders.collection.get", "usagedataproviders.item.get", "usagedataproviders.item.post", "usagedataproviders.item.put", "counterreports.collection.get", "counterreports.item.get", "counterreports.item.post", "counterreports.item.put", "aggregatorsettings.collection.get", "aggregatorsettings.item.get" ], "childOf": [], "grantedTo": [ "fba0106d-e2ad-494e-8958-ce5b447ab2aa" ], "mutable": false, "visible": true, "dummy": false }
BadMisleading:
Code Block language js { "permissionName": "ui-receiving.basic.view", "displayName": "Receiving: Basic view", "id": "5542bb26-9eff-4699-a7c5-6e6a049979d7", "tags": [], "subPermissions": [ "module.receiving.enabled", "orders.item.get", "orders.pieces.item.post", "orders.pieces.item.put", "orders.po-lines.collection.get", "orders.titles.collection.get", "orders.titles.item.get", "ui-receiving.third-party-services" ], "childOf": [ "ui-receiving.view" ], "grantedTo": [], "mutable": false, "visible": false, "dummy": false }
- Permission sets for modulePermissions should use the "modperms" prefix. These also should not be visible as they aren't intended to be assigned to users.
Example:
Code Block "permissionName": "modperms.circulation.loans.anonymize", "permissionName": "modperms.circulation.override-renewal-by-barcode.post", "permissionName": "modperms.circulation.renew-by-barcode.post", "permissionName": "modperms.circulation.requests.item.move.post", "permissionName": "modperms.circulation.renew-by-id.post", "permissionName": "modperms.circulation.requests.item.post", "permissionName": "modperms.circulation.override-check-out-by-barcode.post", "permissionName": "modperms.circulation.requests.item.put", "permissionName": "modperms.circulation.requests.instances.item.post", "permissionName": "modperms.circulation.check-out-by-barcode.post", "permissionName": "modperms.orders.item.post", "permissionName": "modperms.orders.item.put",
Backend Modules
- Avoid inclusion of other modules permissions in your permission sets. For example, mod-foo's permission set foo.all shouldn't include mod-bar's bar.item.get permission. Here it's the module that needs the permission, not the user.
- Do: include the other module's permission(s) in your modulePermissions (or non-visible modulePermission sets - see above)
- Don't: include other modules permissions in your visible permission sets that will be assigned to users.
Visible Permission Sets
- Be careful about making a permission set visible. Permissions should only have visible=true if/when they're intended to be granted to a user. Permission sets for modulePermissions should not be visible.
UI Modules
- Define separate permission sets for settings if other other module permissions are needed (e.g.
configuration.entries.collection.get
).- Example: "
ui-users.settings.customfields.edit
" probably needsconfiguration.entries.collection.get
, but "ui-users.view
" probably doesn't. If needed, additional permission sets should be created with appropriate names. Example: Should we really be granting users, source-storage, circulation, configuration, etc. permissions from a ui-inventory permission set?
Code Block { "permissionName" : "ui-inventory.instance.view", "displayName" : "Inventory: View instances, holdings, and items", "id" : "885b608a-2423-44bb-bcc2-68daaa7383b6", "tags" : [ ], "subPermissions" : [ "module.inventory.enabled", "users.collection.get", "source-storage.records.get", "circulation.loans.collection.get", "circulation.loans.collection.get", "circulation.requests.collection.get", "configuration.entries.collection.get", "inventory.config.instances.blocked-fields.get", "inventory.instances.collection.get", "inventory.instances.item.get", "inventory.items.collection.get", "inventory.items.item.get", "inventory-storage.items.item.get", "inventory-storage.items.collection.get", "inventory-storage.identifier-types.collection.get", "inventory-storage.contributor-types.collection.get", "inventory-storage.contributor-name-types.collection.get", "inventory-storage.call-number-types.collection.get", "inventory-storage.item-note-types.collection.get", "inventory-storage.item-damaged-statuses.collection.get", "inventory-storage.nature-of-content-terms.collection.get", "inventory-storage.classification-types.collection.get", "inventory-storage.alternative-title-types.collection.get", "inventory-storage.locations.collection.get", "inventory-storage.locations.item.get", "inventory-storage.location-units.institutions.collection.get", "inventory-storage.location-units.institutions.item.get", "inventory-storage.location-units.campuses.collection.get", "inventory-storage.location-units.campuses.item.get", "inventory-storage.location-units.libraries.collection.get", "inventory-storage.location-units.libraries.item.get", "inventory-storage.modes-of-issuance.collection.get", "inventory-storage.instance-formats.collection.get", "inventory-storage.instance-statuses.collection.get", "inventory-storage.instance-types.collection.get", "inventory-storage.instance-relationship-types.collection.get", "inventory-storage.instance-note-types.collection.get", "inventory-storage.instances.item.get", "inventory-storage.electronic-access-relationships.collection.get", "inventory-storage.statistical-code-types.collection.get", "inventory-storage.statistical-codes.collection.get", "inventory-storage.ill-policies.collection.get", "inventory-storage.holdings-note-types.collection.get", "inventory-storage.holdings-types.collection.get", "inventory-storage.holdings.collection.get", "inventory-storage.holdings.item.get", "inventory-storage.material-types.collection.get", "inventory-storage.loan-types.collection.get", "inventory-storage.service-points.get", "inventory-storage.service-points.collection.get", "inventory-storage.hrid-settings.item.get", "inventory-storage.instance-bulk.ids.get" ], "childOf" : [ "ui-inventory.instance.create", "ui-inventory.item.create", "ui-inventory.holdings.create", "ui-inventory.instance.view-staff-suppressed-records", "ui-inventory.all-permissions.TEMPORARY" ], "grantedTo" : [ ], "mutable" : false, "visible" : true, "dummy" : false }
- Example: "
Using *.all Permissions
- Only include *.all permissions when absolutely sure it's necessary/appropriate. Instead use just the permissions actually needed.
Example of a permission set that probably abuses *.all permissions
Code Block { "permissionName": "ui-checkin.all", "displayName": "Check in: All permissions", "id": "094310c8-cd71-4b76-a10d-2921ccd10654", "description": "Entire set of permissions needed to use Checkin", "tags": [], "subPermissions": [ "circulation.all", "circulation-storage.all", "configuration.all", "users.collection.get", "usergroups.collection.get", "module.checkin.enabled", "inventory.items.collection.get", "inventory-storage.service-points.collection.get" ], "childOf": [], "grantedTo": [ "fba0106d-e2ad-494e-8958-ce5b447ab2aa" ], "mutable": false, "visible": true, "dummy": false }
Other Considerations
- Sensitive information should NEVER be stored in mod-configuration. SMTP credentials, RMAPI credentials, etc. should be stored behind their own endpoints which are protected with distinct permissions.
- We might want to take a look at ways to make the permissions of this module more granular, perhaps something could be done using desiredPermissions / X-Okapi-Permissions? Though I'm not sure this is really doable or even worth it. I think I'm in favor of just moving away from mod-configuration all together altogether (see below)
- We should consider moving away from using mod-configuration in general. The cross-app nature of this module makes it difficult to deal with other things like sample/reference data... what if you want some reference data loaded into mod-configuration, but not all of it?
- See
Jira Legacy server System JIRA serverId 01505d01-b853-3c2e-90f1-ee9b165564fc key FOLIO-2583 - One use case where it probably makes sense to continue to have centralized configuration is for things that are truly shared across multiple apps, e.g. the tenant settings
- See
- How do we handle "migration" of permission sets as teams clean things up?TBD
- One idea is to do something like add a field to the module descriptor that allows you to specify that this permission set "replaces" one named XYZ. This would result the swapping and cleanup of permissions.
- See
Jira Legacy server System JIRA serverId 01505d01-b853-3c2e-90f1-ee9b165564fc key FOLIO-2607
Appendix
Examples of Permission Sets with Misleading Names
Code Block | ||||
---|---|---|---|---|
| ||||
[{
"permissionName": "ui-receiving.basic.view",
"displayName": "Receiving: Basic view",
"id": "5542bb26-9eff-4699-a7c5-6e6a049979d7",
"tags": [],
"subPermissions": [
"module.receiving.enabled",
"orders.item.get",
"orders.pieces.item.post",
"orders.pieces.item.put",
"orders.po-lines.collection.get",
"orders.titles.collection.get",
"orders.titles.item.get",
"ui-receiving.third-party-services"
],
"childOf": [
"ui-receiving.view"
],
"grantedTo": [],
"mutable": false,
"visible": false,
"dummy": false
},{
"permissionName": "ui-organizations.basic.view",
"displayName": "Organizations: Basic view",
"id": "c0f97cdc-7fb5-46b1-814c-d78b58d62da0",
"tags": [],
"subPermissions": [
"module.organizations.enabled",
"organizations-storage.accounts.collection.get",
"organizations-storage.accounts.item.get",
"organizations-storage.addresses.collection.get",
"organizations-storage.addresses.item.get",
"organizations-storage.agreements.collection.get",
"organizations-storage.agreements.item.get",
"organizations-storage.aliases.collection.get",
"organizations-storage.aliases.item.get",
"organizations-storage.categories.collection.get",
"organizations-storage.categories.item.get",
"organizations-storage.contacts.all",
"organizations-storage.emails.collection.get",
"organizations-storage.emails.item.get",
"organizations-storage.interfaces.all",
"organizations-storage.organizations.collection.get",
"organizations-storage.organizations.item.get",
"organizations-storage.phone-numbers.collection.get",
"organizations-storage.phone-numbers.item.get",
"organizations-storage.urls.collection.get",
"organizations-storage.urls.item.get",
"ui-organizations.third-party-services"
],
"childOf": [
"ui-organizations.view",
"ui-organizations.creds.view"
],
"grantedTo": [],
"mutable": false,
"visible": false,
"dummy": false
},{
"permissionName": "ui-licenses.licenses.view",
"displayName": "Licenses: Search & view licenses",
"id": "9f9bad1c-dfbd-4c36-98f6-7ef9c8c722d6",
"tags": [],
"subPermissions": [
"module.licenses.enabled",
"tags.item.post",
"licenses.licenses.view",
"licenses.files.view",
"licenses.contacts.view",
"licenses.custprops.view",
"licenses.orgs.view"
],
"childOf": [
"ui-licenses.licenses.edit",
"ui-licenses.licenses.delete"
],
"grantedTo": [],
"mutable": false,
"visible": true,
"dummy": false
},{
"permissionName": "ui-notes.item.view",
"displayName": "Notes: Can view a note",
"id": "ccb872ae-eb1b-421d-9b36-4f818e96bde7",
"tags": [],
"subPermissions": [
"note.types.collection.get",
"notes.item.get",
"notes.collection.get",
"notes.collection.get.by.status",
"notes.domain.all",
"module.notes.enabled"
],
"childOf": [
"ui-notes.item.create",
"ui-notes.item.edit",
"ui-notes.item.delete",
"ui-notes.item.assign-unassign"
],
"grantedTo": [],
"mutable": false,
"visible": true,
"dummy": false
},{
"permissionName": "ui-receiving.view",
"displayName": "Receiving: View",
"id": "33096278-520c-4268-8f2f-a5075e8e7171",
"tags": [],
"subPermissions": [
"orders.check-in.collection.post",
"orders.receiving.collection.post",
"settings.receiving.enabled",
"ui-receiving.basic.view"
],
"childOf": [
"ui-receiving.edit"
],
"grantedTo": [],
"mutable": false,
"visible": true,
"dummy": false
}] |