使用授权来授予服务之间的访问权
使用 IBM Cloud® Identity and Access Management (IAM) 可创建或除去授权,授权用于授予一个服务对另一个服务的访问权。 使用授权委派可自动创建访问策略来授予对相依服务的访问权。
IAM的许多功能都集中在管理和执行用户和应用程序对 IBM Cloud 资源的访问。 然而,您可能还会遇到其他情况,需要提供一种服务,以便访问其他服务中的用户资源。 此类型访问权称为授权。
在授权中,源服务是被授予对目标服务的访问权的服务。 您所选择的角色决定了源服务的访问权限。 目标服务是您根据分配的角色授予源服务访问许可权的服务。 源服务可以位于创建授权的同一帐户中,也可以位于另一个帐户中。 目标服务始终位于创建授权的帐户中。 通过在 IBM Cloud® 控制台中的“授权”页面上查看特定授权的“源帐户”列,可以查看源服务是位于当前帐户还是其他帐户中。
授权从属服务
在某些情况下,除了源服务外,还可以对相依服务授权。 被允许访问目标服务的源服务依赖于另一个服务。 相依服务必须分配有访问权才可完成工作流程。 下图说明了在源服务,目标服务和从属服务之间委派访问权的过程:
具有从属服务的
有关角色的更多信息,请参阅 服务访问角色。
以下示例说明了源服务、目标服务和从属服务之间的关系。 假设您具有依赖于 IBM Cloud Object Storage 实例来存储数据的 IBM Watson® 服务。 在 IBM Watson 服务与 IBM® Key Protect 服务之间启用授权时,可能需要 Object Storage 实例来访问用户的 Key Protect 实例中的密钥。 因此,虽然是 IBM Watson 服务与 Key Protect 服务之间的授权,也会同时将 Object Storage 服务作为 IBM Watson 服务的相依服务授予访问权。 通过选择启用对相依服务的授权的选项,您无需执行任何其他操作,因为系统会自动为相依服务创建策略。
源服务的相依服务可能位于源服务的帐户中,这意味着这些服务不会显示在您的帐户中。 但是,源服务为其相依服务创建的任何访问策略都会始终显示。 您可以通过查看“授权”页面上针对特定授权的“类型”列,判断授权是用户创建的还是源服务创建的。
在控制台中创建授权
您必须有权访问目标服务,才能在服务之间创建授权。 作为目标服务的用户,您只能授予自己拥有的访问级别。 例如,如果您对目标服务具有查看者访问权,那么只能为授权分配查看者角色。
-
在 IBM Cloud 控制台中,单击 管理 > 访问权 (IAM),然后选择 授权。
-
单击创建。
-
选择源帐户。
- 如果需要访问目标的源位于此帐户中,请选择 此帐户。
- 如果需要访问目标的源位于其他帐户中,请选择 其他帐户。 然后,输入源帐户的帐户标识。
-
选择需要访问权的一个或多个服务。
- 您可以选择单个服务,并指定是希望源包含所有资源,仅包含在特定资源组中的实例,还是仅包含帐户中的特定实例。
- 新建 您还可以选择 所有启用身份和访问权的服务,然后选择或输入资源组标识。
新建 将资源组作为源输入,使资源组中的服务实例能够访问帐户中的目标资源。 如果您不希望授予对资源的直接访问权,那么可能要设置此访问级别。
-
选择目标。
-
指定是希望目标包含所有资源还是特定资源。 如果选择特定资源作为目标,那么可以添加属性以进一步限定访问权的作用域。 属性类型取决于您选择的目标服务。
-
(可选)选择 “启用授权,允许源服务和依赖服务委派权限”,允许源服务委派其访问权限给任何依赖服务。 仅当源服务具有相依服务时,才会显示此选项。 通过选择此选项,源服务会自动为相依服务创建策略。
-
选择角色以向源服务分配访问目标服务的访问权。
-
单击授权。
如果在另一个帐户中的服务与当前帐户中的目标服务之间创建授权,那么您只需要访问目标资源。 对于源帐户,您只需要帐号。
使用CLI创建授权
要授权源服务访问目标服务,请运行 ibmcloud iam authorization-policy-create
命令。
以下样本使用模拟数据来创建策略,其中授权 IBM Cloud Object Storage 的特定源服务实例访问 IBM Key Protect的特定目标服务实例:
ibmcloud iam authorization-policy-create cloud-object-storage kms Reader --source-service-instance-id 123123 --target-service-instance-id 456456
有关可用于此命令的所有参数的更多信息,请参阅 ibmcloud iam authorization-policy-create。
使用 Terraform 创建授权
您必须有权访问目标服务,才能在服务之间创建授权。 作为目标服务的用户,您只能授予自己拥有的访问级别。 例如,如果您对目标服务具有查看者访问权,那么只能为授权分配查看者角色。
在可以使用 Terraform 创建授权之前,请确保已完成以下操作:
- 安装 Terraform CLI 并为 Terraform 配置 IBM Cloud 提供程序插件。 有关更多信息,请参阅 Terraform on IBM Cloud®入门 教程。 该插件对用于完成此任务的 IBM Cloud API 进行抽象。
- 创建一个名为
main.tf
的Terraform配置文件。 在此文件中,您使用 HashiCorp 配置语言来定义资源。 有关更多信息,请参阅 Terraform 文档。
使用以下步骤通过 Terraform 创建授权:
-
使用
main.tf
文件中的ibm_iam_authorization_policy
资源参数在服务之间创建授权策略。以下示例在服务之间创建授权:
resource "ibm_iam_authorization_policy" "policy" { source_service_name = "cloud-object-storage" target_service_name = "kms" roles = ["Reader"] description = "Authorization Policy" transaction_id = "terraformAuthorizationPolicy" }
ibm_iam_authorization_policy
资源需要源服务,目标服务和角色。 源服务被授予对目标服务的访问权,角色是该访问权所允许的许可权级别。 (可选) 您可以添加授权描述和事务标识。有关更多示例,请参阅 Terraform 文档以获取授权资源。
-
完成构建配置文件后,初始化 Terraform CLI。 有关更多信息,请参阅 初始化工作目录。
terraform init
-
从
main.tf
文件供应资源。 有关更多信息,请参阅 使用 Terraform 供应基础架构。-
运行
terraform plan
以生成 Terraform 执行计划来预览建议的操作。terraform plan
-
运行
terraform apply
以创建计划中定义的资源。terraform apply
-
使用API创建授权
要授权源服务访问目标服务,请使用 IAM 策略管理 API。 请参阅以下 API 示例,以了解在指定了 type=authorization
的情况下创建策略方法。
用于创建授权策略的受支持属性取决于每个服务支持的内容。 有关每个服务的受支持属性的更多信息,请参阅您正在使用的服务的文档。
curl --request POST \
--url https://iam.cloud.ibm.com/v1/policies \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"type": "authorization",
"subjects": [
{
"attributes": [
{
"name": "accountId",
"value": "<account-id>"
},
{
"name": "serviceName",
"value": "<service-name>"
},
{
"name": "serviceInstance",
"value": "<instance-id>"
}
]
}
],
"roles": [
{
"role_id": "crn:v1:bluemix:public:iam::::serviceRole:Reader"
}
],
"resources": [
{
"attributes": [
{
"name": "accountId",
"value": "<account-id>"
},
{
"name": "serviceName",
"value": "<service-name>"
},
{
"name": "serviceInstance",
"value": "<instance-id>"
},
{
"name": "resourceType",
"value": "<resource-type>"
},
{
"name": "resource",
"value": "<id>"
}
]
}
]
}'
SubjectAttribute accountSubjectAttribute = new SubjectAttribute.Builder()
.name("accountId")
.value(exampleAccountId)
.build();
SubjectAttribute serviceNameSubjectAttribute = new SubjectAttribute.Builder()
.name("serviceName")
.value(exampleSourceServiceName)
.build();
SubjectAttribute serviceInstanceSubjectAttribute = new SubjectAttribute.Builder()
.name("serviceInstance")
.value(exampleSourceServiceInstanceId)
.build();
PolicySubject policySubjects = new PolicySubject.Builder()
.addAttributes(accountSubjectAttribute)
.addAttributes(serviceNameSubjectAttribute)
.addAttributes(serviceInstanceSubjectAttribute)
.build();
PolicyRole policyRoles = new PolicyRole.Builder()
.roleId("crn:v1:bluemix:public:iam::::serviceRole:Reader")
.build();
ResourceAttribute accountIdResourceAttribute = new ResourceAttribute.Builder()
.name("accountId")
.value(exampleAccountId)
.operator("stringEquals")
.build();
ResourceAttribute serviceNameResourceAttribute = new ResourceAttribute.Builder()
.name("serviceName")
.value(exampleTargetServiceName)
.operator("stringEquals")
.build();
ResourceAttribute serviceInstanceResourceAttribute = new ResourceAttribute.Builder()
.name("serviceInstance")
.value(exampleTargetInstanceId)
.operator("stringEquals")
.build();
ResourceAttribute resourceTypeResourceAttribute = new ResourceAttribute.Builder()
.name("resourceType")
.value(exampleResourceType)
.operator("stringEquals")
.build();
ResourceAttribute resourceResourceAttribute = new ResourceAttribute.Builder()
.name("resource")
.value(exampleResourceId)
.operator("stringEquals")
.build();
PolicyResource policyResources = new PolicyResource.Builder()
.addAttributes(accountIdResourceAttribute)
.addAttributes(serviceNameResourceAttribute)
.addAttributes(serviceInstanceResourceAttribute)
.addAttributes(resourceTypeResourceAttribute)
.addAttributes(resourceResourceAttribute)
.build();
CreatePolicyOptions options = new CreatePolicyOptions.Builder()
.type("authorization")
.subjects(Arrays.asList(policySubjects))
.roles(Arrays.asList(policyRoles))
.resources(Arrays.asList(policyResources))
.build();
Response<Policy> response = service.createPolicy(options).execute();
Policy policy = response.getResult();
System.out.println(policy);
const policySubjects = [
{
attributes: [
{
name: 'accountId',
value: exampleAccounId,
},
{
name: 'serviceName',
value: exampleSourceServiceName,
},
{
name: 'serviceInstance',
value: exampleSourceServiceInstaceId,
},
],
},
];
const policyRoles = [
{
role_id: 'crn:v1:bluemix:public:iam::::serviceRole:Reader',
},
];
const accountIdResourceAttribute = {
name: 'accountId',
value: exampleAccountId,
operator: 'stringEquals',
};
const serviceNameResourceAttribute = {
name: 'serviceName',
value: exampleTargetServiceName,
operator: 'stringEquals',
};
const serviceInstanceResourceAttribute = {
name: 'serviceInstance',
value: exampleTargetServiceInstanceId,
operator: 'stringEquals',
};
const resourceTypeResourceAttribute = {
name: 'resourceType',
value: exampleResourceType,
operator: 'stringEquals',
};
const resourceResourceAttribute = {
name: 'resource',
value: exampleResourceId,
operator: 'stringEquals',
};
const policyResources = [
{
attributes: [
accountIdResourceAttribute,
serviceNameResourceAttribute,
serviceInstanceResourceAttribute,
resourceTypeResourceAttribute,
resourceResourceAttribute,
],
},
];
const params = {
type: 'authorization',
subjects: policySubjects,
roles: policyRoles,
resources: policyResources,
};
iamPolicyManagementService.createPolicy(params)
.then(res => {
examplePolicyId = res.result.id;
console.log(JSON.stringify(res.result, null, 2));
})
.catch(err => {
console.warn(err)
});
policy_subjects = PolicySubject(
attributes=[SubjectAttribute(name='accountId', value=example_account_id),
SubjectAttribute(name='serviceName', value=example_source_service_name),
SubjectAttribute(name='serviceInstance', value=example_source_service_instance_id)])
policy_roles = PolicyRole(
role_id='crn:v1:bluemix:public:iam::::serviceRole:Reader')
account_id_resource_attribute = ResourceAttribute(
name='accountId', value=example_account_id)
service_name_resource_attribute = ResourceAttribute(
name='serviceName', value=example_target_service_name)
service_instance_resource_attribute = ResourceAttribute(
name='serviceInstance', value=example_target_service_instance_id)
resource_type_resource_attribute = ResourceAttribute(
name='resourceType', value=example_resource_type)
resource_resource_attribute = ResourceAttribute(
name='resource', value=example_resource_id)
policy_resources = PolicyResource(
attributes=[account_id_resource_attribute,
service_name_resource_attribute,
service_instance_resource_attribute,
resource_type_resource_attribute,
resource_resource_attribute])
policy = iam_policy_management_service.create_policy(
type='authorization',
subjects=[policy_subjects],
roles=[policy_roles],
resources=[policy_resources]
).get_result()
print(json.dumps(policy, indent=2))
accountSubjectAttribute := &iampolicymanagementv1.SubjectAttribute{
Name: core.StringPtr("accountId"),
Value: &exampleAccountID,
}
serviceNameSubjectAttribute := &iampolicymanagementv1.SubjectAttribute{
Name: core.StringPtr("serviceName"),
Value: &exampleSourceServiceName,
}
serviceInstanceSubjectAttribute := &iampolicymanagementv1.SubjectAttribute{
Name: core.StringPtr("serviceInstance"),
Value: &exampleSourceServiceInstanceId,
}
policySubjects := &iampolicymanagementv1.PolicySubject{
Attributes: []iampolicymanagementv1.SubjectAttribute{*accountSubjectAttribute,
*serviceNameSubjectAttribute, *serviceInstanceSubjectAttribute},
}
policyRoles := &iampolicymanagementv1.PolicyRole{
RoleID: core.StringPtr("crn:v1:bluemix:public:iam::::serviceRole:Reader"),
}
accountIDResourceAttribute := &iampolicymanagementv1.ResourceAttribute{
Name: core.StringPtr("accountId"),
Value: core.StringPtr(exampleAccountID),
Operator: core.StringPtr("stringEquals"),
}
serviceNameResourceAttribute := &iampolicymanagementv1.ResourceAttribute{
Name: core.StringPtr("serviceName"),
Value: core.StringPtr(exampleTargetServiceName),
Operator: core.StringPtr("stringEquals"),
}
serviceInstanceResourceAttribute := &iampolicymanagementv1.ResourceAttribute{
Name: core.StringPtr("serviceInstance"),
Value: core.StringPtr(exampleTargetServiceInstanceId),
Operator: core.StringPtr("stringEquals"),
}
resourceTypeResourceAttribute := &iampolicymanagementv1.ResourceAttribute{
Name: core.StringPtr("resourceType"),
Value: core.StringPtr(exampleResourceType),
Operator: core.StringPtr("stringEquals"),
}
resourceResourceAttribute := &iampolicymanagementv1.ResourceAttribute{
Name: core.StringPtr("resource"),
Value: core.StringPtr(exampleResourceId),
Operator: core.StringPtr("stringEquals"),
}
policyResources := &iampolicymanagementv1.PolicyResource{
Attributes: []iampolicymanagementv1.ResourceAttribute{
*accountIDResourceAttribute, *serviceNameResourceAttribute,
*serviceInstanceResourceAttribute, *resourceTypeResourceAttribute,
*resourceResourceAttribute},
}
options := iamPolicyManagementService.NewCreatePolicyOptions(
"authorization",
[]iampolicymanagementv1.PolicySubject{*policySubjects},
[]iampolicymanagementv1.PolicyRole{*policyRoles},
[]iampolicymanagementv1.PolicyResource{*policyResources},
)
policy, response, err := iamPolicyManagementService.CreatePolicy(options)
if err != nil {
panic(err)
}
b, _ := json.MarshalIndent(policy, "", " ")
fmt.Println(string(b))
并非所有服务都支持 resourceType
和个人 resource
级别的策略。 支持这些属性的服务示例包括 IBM Cloud Object Storage 和 IBM Key Protect,其中存储区和密钥是资源类型,并且列出了用于指定特定资源的标识。
创建使用 resource-group
作为 resourceType
的授权
要创建将 resource-group
用作源或目标的授权,请使用 IAM 策略管理 API。
resource-group
作为源
请参阅以下 API 示例,以创建指定为源的 resource-group
的策略方法。
{
"type": "authorization",
"subjects": [
{
"attributes": [
{
"name": "resourceGroupId",
"value": "<rgId>"
},
{
"name": "accountId",
"value": "<sourceAccountId>"
}
]
}
],
"roles": [
{
"role_id": "crn:v1:bluemix:public:iam::::role:Viewer"
}
],
"resources": [
{
"attributes": [
{
"name": "accountId",
"value": "<targetAccountId>"
},
{
"name": "serviceName",
"value": "<targetService>"
},
{
"name": "serviceInstance",
"value": "<targetServiceInstance>"
}
]
}
]
}
resource-group
作为目标
请参阅以下 API 示例,以创建将 resource-group
指定为目标的策略方法。
{
"type": "authorization",
"subjects": [
{
"attributes": [
{
"name": "accountId",
"value": "<sourceAccountId>"
},
{
"name": "serviceName",
"value": "<sourceService>"
},
{
"name": "serviceInstance",
"value": "<sourceServiceInstance>"
}
]
}
],
"roles": [
{
"role_id": "crn:v1:bluemix:public:iam::::role:Viewer"
}
],
"resources": [
{
"attributes": [
{
"name": "accountId",
"value": "<targetAccountId>"
},
{
"name": "resourceType",
"value": "resource-group"
}
]
}
]
}
在控制台中除去授权
如果您分配有对目标服务的管理员角色,那么可以除去帐户中服务之间的任何授权。 如果除去了源服务为其相依服务创建的任何访问策略,那么源服务将无法完成工作流程或访问目标服务。
- 在 IBM Cloud 控制台中,单击 管理 > 访问权 (IAM),然后选择 授权。
- 确定要从帐户中除去的授权所在的行。
- 单击 操作 图标
> 除去。
- 选择除去。
如果从帐户中除去了源服务,那么该服务为其相依服务创建的任何策略都会被自动删除。 同样,如果从帐户中删除了相依服务,那么委派给该服务的所有访问策略也将被删除。
使用 CLI 除去授权
如果您分配有对目标服务的管理员角色,那么可以除去帐户中服务之间的任何授权。 如果除去了源服务为其相依服务创建的任何访问策略,那么源服务将无法完成工作流程或访问目标服务。
要授权源服务访问目标服务,请运行 ibmcloud iam authorization-policy-create
命令。
以下样本将删除授权策略:
ibmcloud iam authorization-policy-delete 12345678-abcd-1a2b-a1b2-1234567890ab
有关可用于此命令的所有参数的更多信息,请参阅 ibmcloud iam authorization-policy-delete。
如果从帐户中除去了源服务,那么该服务为其相依服务创建的任何策略都会被自动删除。 同样,如果从帐户中删除了相依服务,那么委派给该服务的所有访问策略也将被删除。
使用 API 除去授权
如果您分配有对目标服务的管理员角色,那么可以除去帐户中服务之间的任何授权。 如果除去了源服务为其相依服务创建的任何访问策略,那么源服务将无法完成工作流程或访问目标服务。
要删除授权策略,请使用 IAM 策略管理 API,如以下样本请求中所示:
curl -X DELETE 'https://iam.cloud.ibm.com/v1/policies/$POLICY_ID' \
-H 'Authorization: Bearer $TOKEN' \
-H 'Content-Type: application/json'
DeletePolicyOptions options = new DeletePolicyOptions.Builder()
.policyId(examplePolicyId)
.build();
service.deletePolicy(options).execute();
const params = {
policyId: examplePolicyId,
};
iamPolicyManagementService.deletePolicy(params)
.then(res => {
console.log(JSON.stringify(res, null, 2));
})
.catch(err => {
console.warn(err)
});
response = iam_policy_management_service.delete_policy(
policy_id=example_policy_id
).get_result()
print(json.dumps(response, indent=2))
options := iamPolicyManagementService.NewDeletePolicyOptions(
examplePolicyID,
)
response, err := iamPolicyManagementService.DeletePolicy(options)
if err != nil {
panic(err)
}
如果从帐户中除去了源服务,那么该服务为其相依服务创建的任何策略都会被自动删除。 同样,如果从帐户中删除了相依服务,那么委派给该服务的所有访问策略也将被删除。
使用 Terraform 除去授权
如果要使用 Terraform 除去授权,那么需要从 main.tf
文件中删除该参数。 删除参数后,使用以下步骤来供应文件:
-
运行
terraform plan
以生成 Terraform 执行计划来预览建议的操作。terraform plan
-
运行
terraform apply
以创建计划中定义的资源。terraform apply