Background
Currently CloudStack provides very limited IAM services and there are several drawbacks within those services:
...
Goal for this feature would be to address these limitations and offer true IAM services in a phased manner
Architecture and Design description
IAM Taxonomy
Gliffy Diagram |
---|
size | L |
---|
name | iamTaxonomy |
---|
align | left |
---|
version | 9 |
---|
|
Group
Group contains a number of CloudStack accounts. Customers should be able to Create, Edit, List and Delete Groups. Editing includes adding or removing accounts to or from a group. For backwards compatibility, out of box, CloudStack will provide 3 default groups:
...
- createVPC
- listVPCs
- updateVPC
IAM Schema
![](/confluence/download/attachments/34838986/iam_schema.png?version=4&modificationDate=1394748493000&api=v2)
IAM API
New API's
- createAclGroup
- String name - name of the ACL group. Required
- String description - short decsription
- String domainId - UUID of the domain of the account owning the acl group
...
- removeAclPermissionFromAclPolicy
- String id - UUID of the ACL policy. Required
- List<String> permission Ids - comma separated list of permission ids that are going to be removed from the acl policy
IAM Interface
IAM Interface to check Entity Access
...
For given user, resource and given api name, default permission is 'deny', then run through this:
- Find all groups the user belongs too.
- Find all 'effective' policies the groups are associated to. Effective includes all policy associations in the DB and the dynamic 'Resource Owner' policy if the resource is owned by the user
- If any policy 'Allows' the API, grant permission to make this call
- Else, if no Allow entry is found for any policy for this API, deny the permission
IAM Interface to check API Access
...
By invoking these QueryChecker APIs, CloudStack API engine can pre-construct proper SQL where clause to achieve proper row filter for accessibility control.
Response View
Currently CloudStack provides different response views for Root admin and non-root user, some response fields are only visible to root admin. Basically we have provided two static response views (Full view and Restricted view), domain admin will also a User view. With new IAM service introduced, we should also allow customers to be able to specify what view should be applied to the new Acl group when they are creating a new customized Acl group, for example, customer care group. To achieve that, we will implement as follows:
- We will have a column in AclGroup db table to record what view to be used for this group. From Acl group creation UI, user can pick which view to be associated with this group. Note that in this release, we are not going to support full-fledged column filter (that is, allowing users to pick arbitrary columns to be see for each API). We are only supporting static view association at the Acl group level.
- We will separate all current both admin and user allowed API commands to two classes: API for admin and API for user. For example, previous ListVMsCmd will be splitted into two classes: ListVMsCmdByAdmin and ListVMsCmd.
Code Block |
---|
@APICommand(name = "listVirtualMachines", description = "List the virtual machines owned by the account.", responseObject = UserVmResponse.class, responseView = ResponseView.Restricted)
public class ListVMsCmd extends BaseListTaggedResourcesCmd {
......
}
@APICommand(name = "listVirtualMachines", description = "List the virtual machines owned by the account.", responseObject = UserVmResponse.class, responseView = ResponseView.Full)
public class ListVMsCmdByAdmin extends ListVMsCmd {
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.HOST_ID, type=CommandType.UUID, entityType=HostResponse.class,
description="the host ID")
private Long hostId;
@Parameter(name=ApiConstants.POD_ID, type=CommandType.UUID, entityType=PodResponse.class,
description="the pod ID")
private Long podId;
@Parameter(name=ApiConstants.STORAGE_ID, type=CommandType.UUID, entityType=StoragePoolResponse.class,
description="the storage ID where vm's volumes belong to")
private Long storageId;
}
|
Note that ListVMsCmdByAdmin and ListVMsCmd are sharing the same API name "listVirtualMachines". From client perspective, this is transparent to them, CloudStack API client will still just invoke previous listVirtualMachine API, and CloudStack API server will internally consult with IAM plugin to determine the group associated with the invoking user and then determine which internal Cmd class to be invoked. There is a new attribute "responseView" introduced for @APICommand annoation, which can be used to instruct CloudStack to generate different response view. By separating the command class into admin cmd class and user cmd class, we can also restrict valid input parameters for different account. For example, in this case, when Admin invokes listVirtualMachine api, he/she can pass hostId, podId and storageId, which parameters are not applicable for end user.
Default Policy
Default Policy Generation Flow
...
- As illustrated in the above access flow, the access checks get invoked when the resource Ids in the API Cmd are annotated.
- Thus we will have to edit all existing API Cmds and add the relevant @ACL annotation on the primary resource Ids the command operates on.
- For any other resources that the command works with, the current access checks placed in the service layer will invoke the SecurityChecker.
- These current access checks pass the AccessType whereever needed or mostly pass null. Our SecurityChecker will interpret null as a 'Read' access. In the 'acl_permission' schema, all List* APIs will be marked as 'Read' AccessType entries to facilitate this access check.
Creating Custom Group and Policy
Consider following example:
...