Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

IAM Schema

IAM API

New API's

  • createIAMGroupcreateAclGroup
    1. String name - name of the ACL IAM group. Required
    2. String description - short decsription
    3. String domainId - UUID of the domain of the account owning the acl IAM group
  • deleteIAMGroupdeleteAclGroup
    1. String id - UUID of the ACL IAM group. Required
  • listIAMGroupslistAclGroups
    1. String name - name of the ACL IAM group.
    2. String id - UUID of the ACL IAM group.
  • addAccountToIAMGroupaddAccountToAclGroup
    1. String id - UUID of the ACL IAM group. Required
    2. List<String> accounts - comma separated list of account id that are going to be assigned to the acl IAM group
  • removeAccountFromIAMGroupremoveAccountFromAclGroup
    1. String id - UUID of the ACL IAM group. Required
    2. List<String> accounts - comma separated list of account id that are going to be removed from the acl IAM group
  • createIAMPolicycreateAclPolicy
    1. String name - name of the ACL IAM Policy. Required
    2. String description - short decsription
    3. String domainId - UUID of the domain of the account owning the acl IAM policy
    4. String sourcePolicyId - UUID of the policy which should be used as a template to generate the new policy
  • deleteIAMPolicydeleteAclPolicy
    1. String id - UUID of the ACL IAM Policy. Required
  • listIAMPolicieslistAclPolicies
    1. String name - name of the ACL IAM policy.
    2. String id - UUID of the ACL IAM policy.
  • attachIAMPolicyToIAMGroupattachAclPolicyToAclGroup
    1. String id - UUID of the ACL IAM group. Required
    2. List<String> policies - comma separated list of policy ids that are going to be assigned to the acl IAM group
  • removeIAMPolicyFromIAMGroupremoveAclPolicyFromAclGroup
    1. String id - UUID of the ACL IAM group. Required
    2. List<String> policies- comma separated list of policy ids that are going to be revoked from the acl IAM group
  • createIAMPermissioncreateAclPermission
    1. String action - name of the API allowed/denied. Required
    2. String permission - "Allow"/ "Deny"
    3. String scope- ("Account" / "Domain" / "Resource")
    4. String scope id - UUID of the Scope
    5. String resourceType
  • addIAMPermissionToIAMPolicyaddAclPermissionToAclPolicy
    1. String id - UUID of the ACL IAM policy. Required
    2. List<String> permissionIds - comma separated list of permission ids that are going to be added to the acl IAM policy
  • removeIAMPermissionFromIAMPolicyremoveAclPermissionFromAclPolicy
    1. String id - UUID of the ACL IAM policy. Required
    2. List<String> permission Ids - comma separated list of permission ids that are going to be removed from the acl IAM policy

IAM Interface

IAM Interface to check Entity Access

CloudStack currently has a domain-tree based implementation of access checks, namely com.cloud.acl.DomainChecker. This implementation is based on an adapter interface of Cloudstack - org.apache.cloudstack.acl.SecurityChecker that defines the basic ACL IAM interface to check ownership and access control to objects within the account/ domain.

...

Code Block
/**
* QuerySelector returns granted domain, or account or resources for caller.
*/
public interface QuerySelector extends Adapter {

...

/**
* List granted domains for the caller, given a specific entity type.
*
* @param caller account to check against.
* @param entityType entity type
* @return list of domain Ids granted to the caller account.
*/
List<Long> getAuthorizedDomains(Account caller, String entityType);

/**
* List granted accounts for the caller, given a specific entity type.
*
* @param caller account to check against.
* @param entityType entity type
* @return list of domain Ids granted to the caller account.
*/
List<Long> getAuthorizedAccounts(Account caller, String entityType);


/**
* List granted resources for the caller, given a specific entity type.
*
* @param caller account to check against.
* @param entityType entity type
* @return list of domain Ids granted to the caller account.
*/
List<Long> getAuthorizedResources(Account caller, String entityType);

/**
 * Check if this account is associated with a policy with scope of ALL
 * @param caller account to check
 * @param action action.
 * @return true if this account is attached with a policy for the given action of ALL scope.
 */
boolean isGrantedAll(Account caller, String action);

/**
 * List of ACLIAM group the given account belongs to
 * @param accountId account id.
 * @return ACLIAM group names
 */
List<String> listAclGroupsByAccountlistIAMGroupsByAccount(long accountId); 

By invoking these QuerySelector APIs, CloudStack API engine can pre-construct proper SQL where clause to achieve proper row filter for accessibility control.

...

  •  plugin
    • This will be a CloudStack plugin and will integrate with CloudStack API/Server projects for all ACL IAM related functionality through adapter implementations that get injected in the core CS components.
    • Contains implementations of all the ACL IAM related adapter interfaces of CloudStack namely, SecurityChecker, APIChecker and the new QuerySelector
    • Contains the new ACL IAM APIs related to group/policy/permission CRUD operations and APIS related to account-group associations.
  •  server
    • This will be an implementation of the pure IAM/RBAC model and is independent of any CloudStack terminology
    • Contains IAM interfaces dealing with group-policy-permission
    • Contains a GenericDao based implementation of these interfaces
    • Thus in order to work with a different IAM implementation say LDAP/AD based, one will have to implement the IAM server interfaces. The plugin portion and its integration with CS will not be affected.

...

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 IAM group when they are creating a new customized Acl IAM group, for example, customer care group. To achieve that, we will implement as follows:

  1. We will have a column in AclGroup IAMGroup db table to record what view to be used for this group. From Acl IAM 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 IAM group level.
  2. 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.

...

When user creates a customized policy, he can specify a source policy from list of default policies. Then we will create new mapping between these default policy permission entries and the new policy in acliam_policy_permission_map table.

...

id

account_name

uuid

domain_id

2

admin

1c5afd64-482b-11e3-86f3-8118f47f9f9f

1

3

domainAdmin

929d172c-b95e-4b86-9474-9789072c9bdb

2

4

domainUserA

f96ddb47-d3c0-4360-a9cd-613d631c8333

2

acliam_group

id

name

description

uuid

path

removed

created

1

REGULAR_USER

Domain user group

d283d4f0-31f0-11e3-ad37-80f85ce25918

/

NULL

2013-10-10 14:13:34

2

ADMIN

Root admin group

d283de28-31f0-11e3-ad37-80f85ce25918

/

NULL

2013-10-10 14:13:34

3

DOMAIN_ADMIN

Domain admin group

d283e6e8-31f0-11e3-ad37-80f85ce25918

/

NULL

2013-10-10 14:13:34

acliam_group_account_map

id

group_id

account_id

removed

created

2

2

2

NULL

2013-10-10 14:13:34

3

3

3

NULL

2013-10-11 00:14:54

4

1

4

NULL

2013-10-11 00:19:55

acliam_policy

id

name

description

uuid

path

removed

created

policy_type

1

REGULAR_USER

Domain user role

d2838dce-31f0-11e3-ad37-80f85ce25918

/

NULL

2013-10-10 14:13:34

Static

2

ADMIN

Root admin role

d2839c56-31f0-11e3-ad37-80f85ce25918

/

NULL

2013-10-10 14:13:34

Static

3

DOMAIN_ADMIN

Domain admin role

d283a7f0-31f0-11e3-ad37-80f85ce25918

/

NULL

2013-10-10 14:13:34

Static

6

RESOURCE_OWNER

Resource owner role

d283c794-31f0-11e3-ad37-80f85ce25918

/

NULL

2013-10-10 14:13:34

Dynamic

acliam_group_policy_map

id

group_id

policy_id

removed

created

1

1

1

NULL

2013-10-10 14:13:34

2

2

2

NULL

2013-10-10 14:13:34

3

3

3

NULL

2013-10-10 14:13:34

Sample DB entries for the policy permissions for 'StartVM' operation:

acliam_permission

id

action

resource_type

scope_id

scope

access_type

permission

removed

created

1

startVirtualMachine

VirtualMachine

NULL

ALL

NULL

Allow

NULL

2013-10-10 14:13:34

2

startVirtualMachine

VirtualMachine

$domainId

Domain

NULL

Allow

NULL

2013-10-10 14:13:34

3

startVirtualMachine

VirtualMachine

$accountId

Account

NULL

Allow

NULL

2013-10-10 14:13:34

acliam_policy_permission_map

id

policy_id

permission_id

removed

created

1

6

3

NULL

2013-10-10 14:13:34

2

2

1

NULL

2013-10-10 14:13:34

3

3

2

NULL

2013-10-10 14:13:34

...

  • 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 'UseEntry' access. In the 'acliam_permission' schema, all List* APIs will be marked as 'UseEntry' AccessType entries to facilitate this access check.

...

A Domain admin wants to create a 'Service Desk' group for his domain and allow 'ready only' access to the group for all VMs and Volumes within the Domain.

Steps:

  • createAclGroupcreateIAMGroup('Service Desk', 'Service Desk group', $domainId of the admin)
  • createAclPolicycreateIAMPolicy('Read Only Access', 'read only access to domain resources', $domainId of the admin)
  • createAclPermissioncreateIAMPermission('ListVirtualMachine', 'Allow', 'Domain', $domainId, 'VirtualMachine')
  • createAclPermissioncreateIAMPermission('ListVolumes', 'Allow', 'Domain', $domainId, 'Volume')
  • addAclPermissionToAclPolicyaddIAMPermissionToIAMPolicy( UUID of the 'Read Only Access' policy, List<String> permissionIds of above permissions)
  • attachAclPolicyToAclGroup attachIAMPolicyToIAMGroup (groupId, policyId)
  • addAccountToAclGroupaddAccountToIAMGroup(groupId, List<String> accountIds)

...