Example RBAC Setup
Context
The following describes an example of a typical RBAC setup for a Data Mesh landscape, complete with roles, example groups and scopes for the permissions. It should be seen as an example, and you will need to adapt it based on your organization's structure, processes and data landscape.
It assumes that there are three environments in which Data Products can be deployed:
- Production: identified as
prd
- Quality Assurance: identified as
qa
- Development: identified as
dev
as well as two domains:
- Sales: identified as
urn:dmb:dmn:sales
- Marketing: identified as
urn:dmb:dmn:marketing
Roles and permissions
We are going to use typical roles for a Data Mesh-based data platform, namely these five:
- Administrator: has every permission including modifying platform settings; not intended for everyday users but only highly privileged personnel
- Data Product Owner: owns Data Products and can manage all their lifecycle, including creating new major versions and deploying to production
- Data Product Developer: develops Data Products and can manage all their lifecycle, excluding creating new major versions and deploying to production
- Governance: manages platform governance settings like policies and documents
- Read Only: can only view objects, cannot make any changes to anything
The following table summarizes the permissions for the roles:
Permission | Administrator | Read Only | DP Owner | DP Developer | Governance |
---|---|---|---|---|---|
practice-shaper.edit | X | ||||
practice-shaper.import | X | ||||
catalog.entity.read | X | X | X | X | X |
catalog.entity.create | X | X | X | ||
catalog.entity.delete | X | X | X | ||
catalog.entity.refresh | X | X | X | ||
catalog.location.read | X | X | X | X | X |
catalog.location.create | X | X | X | ||
catalog.location.delete | X | X | X | ||
catalog.platform.create | X | ||||
catalog.platform.delete | X | ||||
catalog.platform.refresh | X | ||||
builder.software-catalog.view | X | X | X | X | |
builder.dp.snapshot.create | X | X | X | ||
builder.dp.release | X | X | X | ||
builder.dp.deploy.prd | X | X | |||
builder.dp.deploy.qa | X | X | X | ||
builder.dp.deploy.dev | X | X | X | ||
builder.dp.newversion | X | X | |||
builder.dp.commit | X | X | X | ||
builder.dp.policies.test | X | X | X | X | |
cgp.entity.view | X | X | X | X | X |
cgp.entity.edit | X | X | |||
documents.document.insert | X | X | |||
platform.settings.edit | X | ||||
platform.custom-view.edit | X |
Groups
Users are assigned to different groups, which are granted specific roles.
The groups and the assigned roles are:
WITBOOST_ADMINS
: highly privileged users, like the Platform Team; assigned the "Administrator" role.WITBOOST_USERS
: generic users; assigned the "Read Only" role.WITBOOST_DP_OWNERS
: users that own or will own Data Products; assigned the corresponding role.WITBOOST_DP_DEVELOPERS_<DOMAIN>
: users that develop or will develop Data Products for a specific domain; assigned the corresponding role and scoped to the proper domain.WITBOOST_GOVERNANCE
: Governance Team users.
This example setup defines the baseline for the default
preset for automatic RBAC configuration.
Configuring RBAC
The following SQL queries can be used to configure Witboost's RBAC following the example described above.
INSERT INTO rbac."roles"(id, display_name, description, visibility)
VALUES ('ADMINISTRATOR', 'Administrator', 'Manages all aspects of the platform', 'internal');
INSERT INTO rbac."roles_permissions"(role_id, permission_id)
VALUES ('ADMINISTRATOR', 'practice-shaper.edit'),
('ADMINISTRATOR', 'practice-shaper.import'),
('ADMINISTRATOR', 'catalog.entity.read'),
('ADMINISTRATOR', 'catalog.entity.create'),
('ADMINISTRATOR', 'catalog.entity.delete'),
('ADMINISTRATOR', 'catalog.entity.refresh'),
('ADMINISTRATOR', 'catalog.location.read'),
('ADMINISTRATOR', 'catalog.location.create'),
('ADMINISTRATOR', 'catalog.location.delete'),
('ADMINISTRATOR', 'catalog.platform.create'),
('ADMINISTRATOR', 'catalog.platform.delete'),
('ADMINISTRATOR', 'catalog.platform.refresh'),
('ADMINISTRATOR', 'builder.software-catalog.view'),
('ADMINISTRATOR', 'builder.dp.snapshot.create'),
('ADMINISTRATOR', 'rbac.role.create'),
('ADMINISTRATOR', 'rbac.role.edit'),
('ADMINISTRATOR', 'builder.dp.release'),
('ADMINISTRATOR', 'builder.dp.deploy.prd'),
('ADMINISTRATOR', 'builder.dp.deploy.qa'),
('ADMINISTRATOR', 'builder.dp.deploy.dev'),
('ADMINISTRATOR', 'builder.dp.newversion'),
('ADMINISTRATOR', 'builder.dp.commit'),
('ADMINISTRATOR', 'builder.dp.policies.test'),
('ADMINISTRATOR', 'cgp.entity.view'),
('ADMINISTRATOR', 'cgp.entity.edit'),
('ADMINISTRATOR', 'platform.settings.edit'),
('ADMINISTRATOR', 'documents.document.insert'),
('ADMINISTRATOR', 'platform.custom-view.edit')
ON CONFLICT (role_id, permission_id) DO NOTHING;
INSERT INTO rbac."roles"(id, display_name, description, visibility)
VALUES ('READ_ONLY', 'Read Only User', 'Basic user, can only view information and use the Marketplace', 'user');
INSERT INTO rbac."roles_permissions"(role_id, permission_id)
VALUES ('READ_ONLY', 'catalog.entity.read'),
('READ_ONLY', 'catalog.location.read'),
('READ_ONLY', 'cgp.entity.view')
ON CONFLICT (role_id, permission_id) DO NOTHING;
INSERT INTO rbac."roles"(id, display_name, description, visibility)
VALUES ('DP_OWNER', 'Data Product Owner', 'Owns Data Products and manages their whole lifecycle', 'user');
INSERT INTO rbac."roles_permissions"(role_id, permission_id)
VALUES ('DP_OWNER', 'catalog.entity.read'),
('DP_OWNER', 'catalog.entity.create'),
('DP_OWNER', 'catalog.entity.delete'),
('DP_OWNER', 'catalog.entity.refresh'),
('DP_OWNER', 'catalog.location.read'),
('DP_OWNER', 'catalog.location.create'),
('DP_OWNER', 'catalog.location.delete'),
('DP_OWNER', 'builder.software-catalog.view'),
('DP_OWNER', 'builder.dp.snapshot.create'),
('DP_OWNER', 'builder.dp.release'),
('DP_OWNER', 'builder.dp.deploy.prd'),
('DP_OWNER', 'builder.dp.deploy.qa'),
('DP_OWNER', 'builder.dp.deploy.dev'),
('DP_OWNER', 'builder.dp.newversion'),
('DP_OWNER', 'builder.dp.commit'),
('DP_OWNER', 'builder.dp.policies.test'),
('DP_OWNER', 'cgp.entity.view')
ON CONFLICT (role_id, permission_id) DO NOTHING;
INSERT INTO rbac."roles"(id, display_name, description, visibility)
VALUES ('DP_DEVELOPER', 'Data Product Developer', 'Develops Data Products', 'user');
INSERT INTO rbac."roles_permissions"(role_id, permission_id)
VALUES ('DP_DEVELOPER', 'catalog.entity.read'),
('DP_DEVELOPER', 'catalog.entity.create'),
('DP_DEVELOPER', 'catalog.entity.delete'),
('DP_DEVELOPER', 'catalog.entity.refresh'),
('DP_DEVELOPER', 'catalog.location.read'),
('DP_DEVELOPER', 'catalog.location.create'),
('DP_DEVELOPER', 'catalog.location.delete'),
('DP_DEVELOPER', 'builder.software-catalog.view'),
('DP_DEVELOPER', 'builder.dp.snapshot.create'),
('DP_DEVELOPER', 'builder.dp.release'),
('DP_DEVELOPER', 'builder.dp.deploy.qa'),
('DP_DEVELOPER', 'builder.dp.deploy.dev'),
('DP_DEVELOPER', 'builder.dp.commit'),
('DP_DEVELOPER', 'builder.dp.policies.test'),
('DP_DEVELOPER', 'cgp.entity.view')
ON CONFLICT (role_id, permission_id) DO NOTHING;
INSERT INTO rbac."roles"(id, display_name, description, visibility)
VALUES ('GOVERNANCE', 'Governance User', 'Manages platform governance', 'internal');
INSERT INTO rbac."roles_permissions"(role_id, permission_id)
VALUES ('GOVERNANCE', 'catalog.entity.read'),
('GOVERNANCE', 'catalog.location.read'),
('GOVERNANCE', 'builder.software-catalog.view'),
('GOVERNANCE', 'builder.dp.policies.test'),
('GOVERNANCE', 'cgp.entity.edit'),
('GOVERNANCE', 'cgp.entity.view'),
('GOVERNANCE', 'documents.document.insert')
ON CONFLICT (role_id, permission_id) DO NOTHING;
Assigning the roles
To assign roles to the groups, we can simply do the following:
INSERT INTO rbac."roles_subjects"(subject, role_id, entity_ref, enabled)
VALUES ('group:default/witboost_admins', 'ADMINISTRATOR', 'urn:dmb:dmn:sales', true);
INSERT INTO rbac."roles_subjects"(subject, role_id, entity_ref, enabled)
VALUES ('group:default/witboost_admins', 'ADMINISTRATOR', 'urn:dmb:dmn:marketing', true);
INSERT INTO rbac."roles_subjects"(subject, role_id, entity_ref, enabled)
VALUES ('group:default/witboost_users', 'READ_ONLY', 'urn:dmb:dmn:sales', true);
INSERT INTO rbac."roles_subjects"(subject, role_id, entity_ref, enabled)
VALUES ('group:default/witboost_users', 'READ_ONLY', 'urn:dmb:dmn:marketing', true);
INSERT INTO rbac."roles_subjects"(subject, role_id, entity_ref, enabled)
VALUES ('group:default/witboost_dp_owners', 'DP_OWNER', 'urn:dmb:dmn:sales', true);
INSERT INTO rbac."roles_subjects"(subject, role_id, entity_ref, enabled)
VALUES ('group:default/witboost_dp_owners', 'DP_OWNER', 'urn:dmb:dmn:marketing', true);
INSERT INTO rbac."roles_subjects"(subject, role_id, entity_ref, enabled)
VALUES ('group:default/witboost_dp_developers_sales', 'DP_DEVELOPER', 'urn:dmb:dmn:sales', true);
INSERT INTO rbac."roles_subjects"(subject, role_id, entity_ref, enabled)
VALUES ('group:default/witboost_dp_developers_marketing', 'DP_DEVELOPER', 'urn:dmb:dmn:marketing', true);
INSERT INTO rbac."roles_subjects"(subject, role_id, entity_ref, enabled)
VALUES ('group:default/witboost_governance', 'GOVERNANCE', 'urn:dmb:dmn:sales', true);
INSERT INTO rbac."roles_subjects"(subject, role_id, entity_ref, enabled)
VALUES ('group:default/witboost_governance', 'GOVERNANCE', 'urn:dmb:dmn:marketing', true);
With this setup, developers are scoped to their specific domain, while other kinds of users have the same permissions on all the domains.