サービス間のアクセスの認可

IBM Cloud® Identity and Access Management (IAM) を使用して、あるサービスに別のサービスへのアクセス権限を付与する許可を作成または削除します。 許可の委任を使用して、依存サービスへのアクセス権限を付与するアクセス・ポリシーを自動的に作成します。

IAMの機能の多くは、 IBM Cloud リソースへのユーザーとアプリケーションのアクセスを管理し、強制することに重点を置いている。 しかし、あるサービスに別のサービス内のユーザーのリソースへのアクセス権限を提供する必要があるような他のシナリオが発生する場合もあります。 このタイプのアクセスは、許可と呼ばれます。

許可におけるソース・サービスとは、ターゲット・サービスへのアクセス権限を付与されたサービスです。 選択した役割によって、ソース・サービスのアクセス・レベルが定義されます。 ターゲット・サービスとは、割り当てる役割に基づいて、ソース・サービスがアクセスする許可を付与するサービスです。 ソース・サービスは、許可が作成されたのと同じアカウントに含めることも、別のアカウントに含めることもできます。 ターゲット・サービスは常に、許可が作成されたアカウント内にあります。 IBM Cloud® コンソールの「許可」ページで特定の許可の「ソース・アカウント」列を表示することにより、ソース・サービスが現在のアカウントに配置されているか、別のアカウントに配置されているかを確認できます。

被扶養者サービスの承認

場合によっては、ソース・サービスに加えて依存サービスを許可できます。 ターゲット・サービスへのアクセスが有効になっているソース・サービスは、別のサービスに依存しています。 ワークフローを完了するには、依存サービスにアクセス権限を割り当てる必要があります。 以下の図に、ソース、ターゲット、および依存サービス間のアクセス委譲のプロセスを示す:

S2S 被扶養者サービスを伴う認可。
S2S オーソライゼーションと被扶養者サービスの関係

ロールの詳細については、 サービス・アクセス・ロールを 参照してください。

次の例では、ソース、ターゲット、依存サービスの関係がどのように機能するかを説明します。 例えば、 IBM Cloud Object Storage のインスタンスに依存してデータを保存する IBM Watson® サービスがあるとしよう。 IBM Watson サービスと IBM® Key Protect サービスの間で許可を有効にするときに、Object Storage インスタンスがユーザーの Key Protect インスタンスのキーにアクセスする必要が生じる場合があります。 したがって、許可は IBM Watson サービスと Key Protect サービスの間であると同時に、Object Storage サービスには IBM Watson サービスの依存サービスとしてのアクセス権限も与えられます。 依存サービスの許可を有効にするオプションを選択すると、依存サービスに対してポリシーが自動的に作成されるため、追加のアクションを実行する必要はありません。

ソース・サービスの依存サービスがソース・サービスのアカウントにある可能性があります。これは、アカウントで可視ではないことを意味します。 ただし、依存サービスのソース・サービスによって作成されたアクセス・ポリシーは、常に可視です。 ユーザーが作成した許可や、作成されたソース・サービスは、「許可」ページの特定の許可の「タイプ」列で確認できます。

コンソールでの許可の作成

サービス間の許可を作成するには、ターゲット・サービスにアクセスできる必要があります。 ターゲット・サービスのユーザーとして保持しているアクセス・レベルのみを付与できます。 例えば、ターゲット・サービスでビューアー権限がある場合、許可に割り当てることができるのはビューアーの役割のみです。

  1. IBM Cloud コンソールで、「管理」 > **「アクセス (IAM)」をクリックし、「許可」**を選択します。

  2. 「作成」 をクリックします。

  3. ソース・アカウントを選択します。

    • ターゲットへのアクセスが必要なソースがこのアカウントある場合は、 このアカウント を選択します。
    • ターゲットにアクセスする必要があるソースが別のアカウントである場合は、 別のアカウント を選択します。 次に、ソース・アカウントのアカウント ID を入力します。
  4. アクセスが必要なサービスを選択してください。

    • 個々のサービスを選択し、ソースにすべてのリソースを含めるか、特定のリソース・グループ内のインスタンスのみを含めるか、またはアカウント内の特定のインスタンスのみを含めるかを指定できます。
    • New また、「 All Identity and Access enabled services 」を選択し、リソースグループ ID を選択または入力することもできる。

    新規 ソースとしてリソースグループを入力すると、リソースグループ内のサービスインスタンスが、 アカウント内のターゲットリソースにアクセスできるようになります。 リソースへの直接アクセスを与えたくない場合は、このレベルのアクセス権を設定するとよいでしょう。

  5. ターゲットを選択する。

  6. ターゲットにすべてのリソースを含めるか、特定のリソースを含めるかを指定します。 対象として特定のリソースを選択した場合、属性を追加してさらにアクセス範囲を広げることができます。 属性の種類は、選択した対象サービスによって異なります。

  7. (オプション) [ ソース・サービスと依存サービスによる権限委譲を有効にする ]を選択して、ソース・サービスが依存サービスにアクセスを委譲できるようにします。 このオプションは、ソース・サービスに依存サービスがある場合にのみ表示されます。 このオプションを選択すると、依存サービスのソース・サービスによってポリシーが自動的に作成されます。

  8. ターゲット・サービスにアクセスするソース・サービスに対して、アクセス権限を割り当てるための役割を選択します。

  9. 「許可」 をクリックします。

別のアカウントあるサービスと、現在のアカウントあるターゲット・サービスとの間で認可を作成する場合、ターゲット・リソースへのアクセスのみが必要です。 ソース・アカウントの場合は、アカウント番号のみが必要です。

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 Providerプラグインを設定する。 詳しくは、 でTerraformを始める IBM Cloud® のチュートリアルをご覧ください。 このプラグインは、以下のタスクを実行するために使用される IBM Cloud API を抽象化します。
  • main.tfという名前の Terraform 構成ファイルを作成します。 このファイルでは、 HashiCorp Configuration Languageを使用してリソースを定義します。 詳しくは Terraformのドキュメントを参照。

以下の手順で、Terraformを使って認可を作成する:

  1. 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 リソースには、ソースサービス、ターゲットサービス、およびロールが必要です。 ソース・サービスはターゲット・サービスへのアクセスを許可され、ロールはアクセスが許可する権限レベルである。 オプションで、認証の説明とトランザクションIDを追加できます。

    より詳しい例については、 Terraformの認可リソースのドキュメントを参照してください。

  2. 設定ファイルのビルドが終わったら、Terraform CLIを初期化します。 詳しくは、 作業ディレクトリの初期化を参照のこと。

    terraform init
    
  3. main.tf ファイルからリソースをプロビジョニングする。 詳しくは Terraformによるインフラのプロビジョニングを参照してください。

    1. terraform plan を実行してTerraformの実行プランを生成し、提案されたアクションをプレビューする。

      terraform plan
      
    2. terraform apply を実行し、プランで定義されたリソースを作成する。

      terraform apply
      

API を使用した許可の作成

ソース・サービスからターゲット・サービスへのアクセスを許可するには、IAM Policy Management API を使用します。 type=authorization を指定してポリシー・メソッドを作成する方法については、次の API の例を参照してください。

許可ポリシーの作成でサポートされる属性は、それぞれのサービスが何をサポートしているかによって異なります。 各サービスでサポートされる属性について詳しくは、使用しているサービスの資料を参照してください。

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 があり、バケットと鍵はリソース・タイプで、ID は特定のリソースを指定するためにリストされます。

として resource-group を使用する権限を作成する。 resourceType

resource-group をソースまたはターゲットとして使用する認可を作成するには、 IAM Policy Management API を 使用する。

resource-group ソースとして

ソースとして resource-group を指定したポリシーメソッドの作成については、次の API の例を参照してください。

{
 "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 ターゲットとして

resource-group をターゲットに指定したポリシーメソッドの作成については、次の API の例を参照してください。

{
 "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"
                }
            ]
        }
    ]
}

コンソールでの許可の削除

ターゲット・サービスの管理者の役割が割り当てられている場合は、アカウント内のサービス間の許可を削除できます。 依存サービスのソース・サービスによって作成されたアクセス・ポリシーを削除すると、ソース・サービスはワークフローを完了したり、ターゲット・サービスにアクセスしたりできなくなります。

  1. IBM Cloud コンソールで、「管理」 > **「アクセス (IAM)」をクリックし、「許可」**を選択します。
  2. アカウントから削除する許可の行を識別します。
  3. アクション・アイコンアクション・アイコン > 削除をクリックします。
  4. **「削除」**を選択します。

アカウントからソース・サービスが削除されると、そのサービスによってその依存サービスに対して作成されたポリシーはすべて自動的に削除されます。 同様に、依存サービスがアカウントから削除されると、そのサービスに委任されたアクセス・ポリシーも削除されます。

CLI を使用した許可の削除

ターゲット・サービスの管理者の役割が割り当てられている場合は、アカウント内のサービス間の許可を削除できます。 依存サービスのソース・サービスによって作成されたアクセス・ポリシーを削除すると、ソース・サービスはワークフローを完了したり、ターゲット・サービスにアクセスしたりできなくなります。

ソース・サービスにターゲット・サービスへのアクセスを許可するには、ibmcloud iam authorization-policy-create コマンドを実行します。

許可ポリシーを削除する例を以下に示します。

ibmcloud iam authorization-policy-delete 12345678-abcd-1a2b-a1b2-1234567890ab

このコマンドで利用可能なすべてのパラメーターについて詳しくは、ibmcloud iam authorization-policy-delete を参照してください。

アカウントからソース・サービスが削除されると、そのサービスによってその依存サービスに対して作成されたポリシーはすべて自動的に削除されます。 同様に、依存サービスがアカウントから削除されると、そのサービスに委任されたアクセス・ポリシーも削除されます。

API を使用した許可の削除

ターゲット・サービスの管理者の役割が割り当てられている場合は、アカウント内のサービス間の許可を削除できます。 依存サービスのソース・サービスによって作成されたアクセス・ポリシーを削除すると、ソース・サービスはワークフローを完了したり、ターゲット・サービスにアクセスしたりできなくなります。

以下のサンプル要求に示すように、許可ポリシーを削除するには、IAM Policy Management 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 ファイルから引数を削除する必要がある。 引数を削除したら、以下の手順でファイルをプロビジョニングする:

  1. terraform plan を実行してTerraformの実行プランを生成し、提案されたアクションをプレビューする。

    terraform plan
    
  2. terraform apply を実行し、プランで定義されたリソースを作成する。

    terraform apply