RESOURCE GROUPS ---> ROLES <--- USERS ^ | permissions
Ignore this page, It's just a scratch page to help me convince myself there isn't a better approach...
This alternate approach is not all new, a major aspect was considered and avoided, but I think it may be the way to go. So, this page fleshes out the alternative. For more, see other proposal.
New Fine-Grained Bundle Permissions
User Deploying Another User's Bundle To Specific Resource Group (no change)
Team Leader Creates Bundles, Team Members Deploy Those Bundles
Deployment Manager Gives Teams Bundles Which They Can Deploy
Allow A User To See All Bundles In the System And Deploy Them Anywhere Accessible To User
Allow a User To Manage All Bundle Groups In The System (unchanged)
Allow a User To Only Delete Certain Bundles The User Can See
See All Bundles But Only Create Bundles in Certain Bundle Groups previously unsupported
We need a more fine-grained security model surrounding bundle deployments. This design page explains how we can do it.
To apply fine grained security permissions to the bundle subsystem will require adding a new concept to the security subsystem - bundle groups. Similar to resource groups, bundle groups will allow RHQ to apply user permissions to a set of bundles.
Today's RHQ security model surrounding resources looks like this:
RESOURCE GROUPS ---> ROLES <--- USERS ^ | permissions
An RHQ admin can define a role (which has certain permissions enabled, like MANAGE_INVENTORY, CONTROL, CONFIGURE_WRITE, et. al.). If a permission is a global permission, it does not involve resource groups; rather, it takes affect globally (e.g. MANAGE_INVENTORY). If a permission is a resource permission (e.g. CONTROL), it is restricted in that it applies only for resources found in resource groups assigned to the role that provides the permission.
What this means for the newly proposed DEPLOY_BUNDLES permission (which will be described below) is that it restricts the user to only deploy bundles to resource groups that that user has access to.
If we want to allow for a user to deploy a bundle to an allowed resource group, not only does the resource group need to be assigned to a role that is assigned to the user, but the bundle to be deployed must be in a bundle group that is attached to a role that is assigned to a user (note: the role doesn't have to be the same as the one the resource group is attached to). Today, we do not have this concept of a bundle group. We would have to add a new relationship between role and bundle - this is where bundle groups come in:
BUNDLE GROUPS | v RESOURCE GROUPS ---> ROLES <--- USERS ^ | permissions
WARNING! Any change to the security model involves large amounts of risk. Not only because it involves security, but also because it is used in so many places. We have role queries in every subsystem. Even if we only add to the model (and leave alone what already exists), we would need to carefully study the changes and perform some quality testing to ensure we don't break existing queries and security checks.
If we have that new bundle group relationship to roles, then this would allow things like having an admin user create a new role with permission DEPLOY_BUNDLES, assign resource groups to that role, assign bundle groups to that role, then give that role to any user. That user would then be able to deploy those bundles that are members of the bundle group but only to those resource groups assigned roles that the user is assigned. More examples will be explained below in the Use Cases section of this document.
A global permission must be held to view bundles not assigned to any bundle group.
Implies all other bundle-related permissions.
This is for backward compatibility - it can do EVERYTHING bundle-wise.
We may want to rename this during a db upgrade to something else - to indicate it may be deprecated.
This permission is required to CRUD bundle groups (bundle groups are a new entity introduced in order to implement these new features).
Currently, this means it can add and remove members of the group.
This implies Global.VIEW_ALL_BUNDLES - user can see all bundles.
This seems analogous to INVENTORY_MANAGER permission for resources/resource groups.
Create bundle [version]s
This allows bundle [version] creation but not assignment.
Implies VIEW_ALL_BUNDLES
assign any bundle to any bundle group
unassign any bundle from any bundle group
Implies VIEW_ALL_BUNDLES
Delete any bundle [version]
Implies VIEW_ALL_BUNDLES
A user can deploy any bundle version to any visible resource group
the resource group does not need ResourceGroup.DEPLOY_BUNDLES
Implies VIEW_ALL_BUNDLES
View any bundle [version]s, no matter what group, if any, a bundle is in.
Can deploy bundles to resource groups for which the user has ResourceGroup.DEPLOY_BUNDLE.
A user can create bundle [version]s for the bundle group.
New bundle versions will be reflected in other bundle groups to which the bundle has been assigned.
Implies VIEW_BUNDLES
A user can assign viewable bundles to the group.
A user can unassign bundles from the group.
Implies VIEW_BUNDLES
A user can delete the group's bundle [version]s.
Bundle [version] deletion will be reflected in other bundle groups to which the bundle has been assigned.
Implies VIEW_BUNDLES
A user can deploy bundle versions from the group to a visible resource group
the resource group does not need ResourceGroup.DEPLOY_BUNDLES
Implies VIEW_BUNDLES
can view bundles [version]s in the group
can deploy bundles in the group to resource groups for which the user has ResourceGroup.DEPLOY_BUNDLE.
The user can deploy bundles he can see to the resource group. This includes bundles in the user's bundle groups. If the user has VIEW_ALL_BUNDLES, the user can deploy any bundle.
Note that a bundle group and a resource group need NOT be associated with the same role. If bundle group A is associated with role A and resource group B is associated with role B, as long as DEPLOY_BUNDLES is enabled for role B, you can deploy any bundle in bundle group A to resource group B.
A bundle is made up of its bundle versions. The addition or removal of a bundle version is reflected in all bundle groups in which the bundle is associated. Put differently, it is not possible to have different bundle versions of a bundle in different bundle groups.
Associating a bundle to a group creates a reference. There is really only one bundle which is associated with zero or more bundle groups. Therefore changes in the bundle are reflected in all groups associated with the bundle.
There is no distinction between creating an initial bundle (that is, creating bundle version "1.0" where the bundle itself is also created) and when uploading a new bundle version for an existing bundle (e.g. uploading bundle version "2.0")
Users with CREATE_ALL_BUNDLES can elect to associate a new bundle with 0 or more bundle groups at creation time. Users with CREATE_BUNDLES will automatically have it associated with the bundle group for which the permission is held.
Bundles can be copied from one bundle group to another. The bundle reference remains in the original group.
Users with CREATE_ALL_BUNDLES can copy any bundle to any group.
Users with CREATE_BUNDLES on multiple groups can copy bundles between those groups.
Bundles can be removed from bundle groups. This does not delete anything, it simply removes the association between the bundle and the bundle group.
Users with DELETE_ALL_BUNDLES can remove any bundle from any group.
Users with DELETE_BUNDLES can remove bundles from the bundle group for which the permission is held.
Deleting a bundle or its last bundle version physically removed the bundle. Deleting one of multiple bundle versions physically removes the bundle version.
Users with DELETE_ALL_BUNDLES can delete any bundle or bundle version from any group.
Users with DELETE_BUNDLES can delete any bundle or bundle version from the bundle group for which the permission is held.
Today, there is a coarse-grained, "uber-permission" MANAGE_BUNDLE. If you have this global permission, you can create, delete, deploy and pretty much do anything in the bundle subsystem. We would leave this in the code for backward compatibility. If a user has MANAGE_BUNDLE, it would imply the user has all of the new proposed permissions (VIEW_ALL_BUNDLES, DEPLOY_BUNDLES, etc.) and can do anything and everything in the bundle subsystem.
We may want to rename MANAGE_BUNDLE permission to indicate this is a very powerful permission. We may even consider deprecated this permission, unless we have some users that still want this capability. For now, we will leave it.
Here are some use cases that help illustrate how the new bundle permissions and bundle groups can be utilized.
But first, all use cases must start with an admin user with MANAGE_SECURITY permission creating users and roles and assigning bundle permissions to those roles. In addition, that admin user must create bundle groups (or have a user with MANAGE_BUNDLE_GROUPS permission create bundle groups) and then associate the bundle group(s) with the appropriate role(s). The permissions assigned to the roles and the bundles assigned to the bundle groups will be different depending on the use case. But realize that an admin user must initially set up the security arrangements.
You can do this several ways. Here are some possibilities. With one role:
Bundle Group A | v Resource Group X ---> Role R <--- User U ^ | BundleGroup.CREATE_BUNDLES, ResourceGroup.DEPLOY_BUNDLES
or two roles:
Bundle Group A | v Role R1 <--- User U Resource Group X ---> Role R2 <--- User U ^ ^ | | BundleGroup.CREATE_BUNDLES, ResourceGroup.DEPLOY_BUNDLES
or another way with two roles:
Resource Group X ---> Role R2 <--- User U Role R3 <--- User U ^ ^ | | ResourceGroup.DEPLOY_BUNDLES Global.CREATE_ALL_BUNDLES Global.VIEW_ALL_BUNDLES
Actions By User: User U creates a bundle. He can see the bundle because he has VIEW_ALL_BUNDLES. User goes through the deploy-bundle-wizard and is able to deploy to Resource Group X. No bundle groups are involved.
You can do this with one role:
Bundle Group A | v Resource Group X ---> Role R <--- User U ^ | BundleGroup.VIEW_BUNDLES, ResourceGroup.DEPLOY_BUNDLES
or two roles:
Bundle Group A | v Role R1 <--- User U Resource Group X ---> Role R2 <--- User U ^ ^ | | BundleGroup.VIEW_BUNDLES ResourceGroup.DEPLOY_BUNDLES
Actions By User: User cannot create any bundles. User selects a bundle from all bundle groups he has access to (in this case, Bundle Group A) and can deploy them to any resource group to which he has DEPLOY_BUNDLES permission (in this case, Resource Group X).
Bundle Group A Bundle Group A | | v v Role R1 <--- User TeamLeader Resource Group X ---> Role R2 <--- Users: TeamMember1, TeamMember2 ^ ^ | | BundleGroup.CREATE_BUNDLES BundleGroup.VIEW_BUNDLES, ResourceGroup.DEPLOY_BUNDLES
Actions By User TeamLeader: Team Leader creates a bundle in BundleGroup A. Note that TeamLeader cannot deploy the bundles - he can only create them.
Actions By User TeamMember1: This user cannot create bundles, nor add/remove bundles from the bundle group, however, this user can deploy any bundle found in Bundle Group A to Resource Group X. Note that team members can only see bundles associated with Bundle Group A - no others are visible.
Role R1 <--- User TeamLeader | v Global.CREATE_ALL_BUNDLES Bundle Group A Bundle Group A | | v v Role R2 <--- User DeployManager Resource Group X ---> Role R3 <--- Users: TeamMember1, TeamMember2 ^ ^ | | Global.VIEW_ALL_BUNDLES, BundleGroup.VIEW_BUNDLES, BundleGroup.ASSIGN_BUNDLES, ResourceGroup.DEPLOY_BUNDLES
Actions By User TeamLeader: User TeamLeader can create bundles. But he cannot deploy them or assign them to any groups.
Actions By DeployManager: User DeployManager cannot create bundles, but he can see all bundles created by TeamLeader (and any other user associated with Role R1). DeployManager can add any of those bundles he can see to Bundle Group A. This allows him to give the ability to let anyone associated with Role R3 to be able to deploy those bundles. DeployManager can also remove bundles from Bundle Group A, thus disallowing team members from deploying it. So, in short, DeployManager is the one who dictates which bundles can be deployed by whom, simply by assigning bundles to the appropriate bundle group.
Actions By User TeamMember1: TeamMember1 (and TeamMember2 for that matter) cannot create any bundles and cannot add any bundles to groups. But TeamMember1 can deploy bundles from Bundle Group A to Resource Group X.
_Note that TemLeader will likley also need Global.DELETE_ALL_BUNDLES in order to delete unwanted bundles.
Role R1 <--- User U | v Global.VIEW_ALL_BUNDLES, Global.DEPLOY_ALL_BUNDLES
Notice that the user's role R1 need not have any resource groups or bundle groups associated with it. The two global permissions allow the user to see all bundles and to deploy them to any resource group the user has access to. So, while this role need not have any resource groups, the user still must have other roles that give him access to resource groups - the idea here is that any resource groups this user U has access to can have any bundle deployed to it by user U.
You can do this with one role:
Resource Group X ---> Role R <--- User U ^ | Global.VIEW_ALL_BUNDLES, ResourceGroup.DEPLOY_BUNDLES
or two roles:
Resource Group X ---> Role R1 <--- User U Role R2 <--- User U ^ ^ | | ResourceGroup.DEPLOY_BUNDLES Global.VIEW_ALL_BUNDLES
Actions by User U: The user cannot create or delete bundles nor can the user add or remove bundles from bundle groups. However, the user can see all bundles in the system and can deploy those bundles to Resource Group X (but only to Resource Group X).
Role R1 <--- User U | v Global.MANAGE_BUNDLE_GROUPS, Global.VIEW_ALL_BUNDLES
This will allow user U to create and delete bundle groups as well as adding and removing any bundle from any bundle group. However, note that this user has no ability to create or delete bundles nor can the user deploy bundles. This user can only operate on bundles that already exist.
Role R1 <--- User U | v Global.CREATE_ALL_BUNDLES, Global.DELETE_ALL_BUNDLES
This will allow user U to create bundles, and delete any bundle (whether or not those bundles are in bundle groups). The VIEW_ALL_BUNDLES allows the user to see all bundles, and DELETE_BUNDLES allows the user to delete all those bundles the user can see. However, note that this user has no ability to assign bundles to groups and the user cannot deploy bundles.
You can do this with one role:
Bundle Group A | v Role R1 <--- User U ^ | BUNDLE_GROUP.DELETE_BUNDLES
The user is restricted to being able to delete those bundles in Bundle Group A.
Bundle Group A | v Role R1 <--- User U1, U2, ..., Un ^ | BundleGroup.CREATE_BUNDLES, BundleGroup.DELETE_BUNDLES
This allows all users Ux to create and delete bundles (including uploading bundle versions for existing bundles) but ONLY for those bundles that the users can see. And this means only those bundles associated with Bundle Group A. If a user wants to create a new bundle, they can only associate them with Bundle Group A.
Note also these users Ux cannot deploy any bundle anywhere - they are restricted to only creating and deleting them.
Bundle Group A ---> Role R1 <--- User U Role R2 <--- User U ^ ^ | | BundleGroup.CREATE_BUNDLES Global.VIEW_ALL_BUNDLES
Bundle Group A ---> Role R1 <--- User U Bundle Group A ---> Role R1 <--- User U ^ ^ | | BundleGroup.CREATE_BUNDLES BundleGroup.VIEW_BUNDLES
Bundle Group A ---> Role R1 <--- User U Bundle Group A ---> Role R1 <--- User U ^ ^ | | BundleGroup.DELETE_BUNDLES BundleGroup.VIEW_BUNDLES
None currently