Google Cloud IoT Core は 2023 年 8 月 16 日に廃止されます。詳細については、担当の Google Cloud アカウント チームにお問い合わせください。

IAM によるアクセス制御

このページでは、Identity and Access Management(IAM)を使用してデバイスへのアクセスを制御する方法について説明します。アクセス権はプロジェクト レベルまたはレジストリレベルで付与できます。個々のデバイスレベルでアクセス制御を行うことはできません。通常、アクセス権は個人やユーザー グループ、あるいはサーバー側サービス アカウントに付与されます。(デバイスは公開鍵/秘密鍵の認証を使用します。詳細については、デバイスのセキュリティをご覧ください)。

たとえば、デバイス レジストリ IAM ポリシーに対する cloudiot.provisionerロールをユーザーに割り当てると、そのユーザーはデバイスを追加または削除できますが、レジストリ自体の変更または削除はできません。ロールはクラウド プロジェクトにも設定できます。このロールは、そのクラウド プロジェクトに属するすべてのレジストリに適用されます。

このセクションでは、Cloud IoT Core に関連する IAM 権限と、これらの権限を付与する IAM ロールについて説明します。IAM とその機能の詳細については、IAM のドキュメントをご覧ください。特に、IAM ポリシーの管理のセクションをご覧ください。

役割

ロールは、権限をまとめたものです。たとえば、roles/cloudiot.viewer には cloudiot.registries.getcloudiot.registries.listcloudiot.devices.get および cloudiot.devices.listの権限が含まれています。ロールを割り当てられたユーザーまたはグループは、プロジェクト内のレジストリに対する操作を実行できるようになります。

次の表に、各ロールに関連付けられた権限を含む Cloud IoT Core の IAM のロールを示します。

ロール 説明 権限
roles/cloudiot.viewer すべての Cloud IoT リソースに対する読み取り専用権限
  • cloudiot.registries.get
  • cloudiot.registries.list
  • cloudiot.devices.get
  • cloudiot.devices.list
roles/cloudiot.deviceController デバイスの構成を更新するため権限(デバイスの作成や削除はできない) 上記のすべてと
  • cloudiot.devices.updateConfig
  • cloudiot.devices.sendCommand
roles/cloudiot.provisioner レジストリに対してデバイスを作成および削除する権限(レジストリの変更はできない) 上記のすべてと
  • cloudiot.devices.create
  • cloudiot.devices.delete
  • cloudiot.devices.update
roles/cloudiot.editor すべての Cloud IoT リソースに対する読み取り / 書き込み権限 上記のすべてと
  • cloudiot.registries.create
  • cloudiot.registries.delete
  • cloudiot.registries.update
roles/cloudiot.admin すべての Cloud IoT リソースと権限を完全に制御する権限。 上記のすべてと
  • cloudiot.registries.getIamPolicy
  • cloudiot.registries.setIamPolicy

追加のロール roles/cloudiot.serviceAgent は、関連する Cloud Pub/Sub トピックに対するパブリッシャー権限を付与します。このロールは、プロジェクトで Google Cloud IoT Core API を有効にするときに作成されるサービス アカウントに自動的に割り当てられます。ほとんどの場合、このロールの設定や管理は必要ありません。Cloud Pub/Sub トピックに関連する権限エラーが発生した場合は、トラブルシューティングをご覧ください。

ロールの詳細については、ロールについてをご覧ください。

権限

権限を使用することで、Cloud IoT Core 内のレジストリまたはデバイスに対して、特定のアクションを実行できます。たとえば、cloudiot.registries.list 権限を持つユーザーは、プロジェクト内のレジストリを一覧表示できます。ユーザーには権限を直接付与するのではなく、役割を割り当てます。役割には、1 つ以上の権限が譲渡します。カスタムのロールを作成することもできます。

次の表は、Cloud IoT Core に関連付けられている IAM の権限を示しています。

デバイス レジストリの権限名 説明
cloudiot.registries.create プロジェクトに新しいレジストリを作成します。
cloudiot.registries.delete レジストリの削除。
cloudiot.registries.get ACL を除くレジストリの詳細を読み取ります。
cloudiot.registries.getIAMPolicy レジストリ ACL を読み取ります。
cloudiot.registries.list プロジェクト内のレジストリを一覧表示します。
cloudiot.registries.setIAMPolicy レジストリ ACL を更新します。
cloudiot.registries.update レジストリの詳細を更新します(ACL を除く)。
cloudiot.devices.sendCommand コマンドを送信する(デバイスごとではなく、レジストリごと)。
デバイスの権限名 説明
cloudiot.devices.create 新しいデバイスをレジストリに追加します。
cloudiot.devices.delete デバイスを削除します。
cloudiot.devices.get デバイスの詳細を読み取ります(ACL を除く)。
cloudiot.devices.list レジストリ内のデバイスを一覧表示します。
cloudiot.devices.update デバイスの詳細を更新します(ACL を除く)。
cloudiot.devices.updateConfig デバイス構成を更新します。
cloudiot.devices.bindGateway デバイスをゲートウェイにバインドします。
cloudiot.devices.unbindGateway ゲートウェイからのデバイスのバインドを解除します。

ユーザーがレジストリとデバイスに対してメソッドを実行できるようにする IAM 権限の詳細については、各メソッドの特定の REST リファレンスをご覧ください。

Cloud IoT Core の IAM 管理

IAM ポリシーの取得と設定は、Google Cloud コンソール、IAM API、gcloud ツールのいずれかを使って実行できます。プロジェクト レベルでこれを行う方法については、アクセス権の付与、変更、取り消しをご覧ください。このセクションの残りの部分では、デバイス レジストリ レベルでの IAM 管理について説明します。

ポリシーの取得

Console

デバイス レジストリのアクセス制御を取得するには:

  1. Google Cloud コンソールで、[レジストリ] ページに移動します。

    [レジストリ] ページに移動する

  2. 権限を設定するデバイス レジストリの横にあるチェックボックスをオンにします。情報パネルが開かない場合は、[情報パネルを表示] をクリックします。

  3. [権限] をクリックします。[権限] ペインが開き、ユーザーとその権限のリストが表示されます。

gcloud

デバイス レジストリのポリシーを取得するには、gcloud iot registries get-iam-policy コマンドを実行します。

gcloud iot registries get-iam-policy REGISTRY_ID \
  --region=REGION \
  [--filter=EXPRESSION]
  [--limit=LIMIT]
  [--page-size=PAGE_SIZE]
  [--sort-by=[FIELD,...]]

API

API を介IAM 権限を取得するには、DeviceRegistry getIamPolicy メソッドを使用します。

C#

public static object GetIamPolicy(string projectId, string cloudRegion, string registryId)
{
    var cloudIot = CreateAuthorizedClient();
    // The resource name of the location associated with the key rings.
    var parent = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}";
    try
    {
        var req = new GetIamPolicyRequest();
        var result = cloudIot.Projects.Locations.Registries.GetIamPolicy(req, parent).Execute();
        Console.WriteLine("Bindings: ");
        if (result.Bindings != null)
        {
            result.Bindings.ToList().ForEach(binding =>
            {
                Console.WriteLine($"Role: {binding.Role}");
                binding.Members.ToList().ForEach(member =>
                {
                    Console.WriteLine($"\tMember: {member}");
                });
            });
        }
        else
        {
            Console.WriteLine($"\tNo IAM bindings for {registryId}.");
        }
    }
    catch (Google.GoogleApiException e)
    {
        Console.WriteLine(e.Message);
        return e.Error.Code;
    }
    return 0;
}

Go


// getRegistryIAM gets the IAM policy for a device registry.
func getRegistryIAM(w io.Writer, projectID string, region string, registryID string) (*cloudiot.Policy, error) {
	// Authorize the client using Application Default Credentials.
	// See https://g.co/dv/identity/protocols/application-default-credentials
	ctx := context.Background()
	httpClient, err := google.DefaultClient(ctx, cloudiot.CloudPlatformScope)
	if err != nil {
		return nil, err
	}
	client, err := cloudiot.New(httpClient)
	if err != nil {
		return nil, err
	}

	var req cloudiot.GetIamPolicyRequest

	path := fmt.Sprintf("projects/%s/locations/%s/registries/%s", projectID, region, registryID)
	response, err := client.Projects.Locations.Registries.GetIamPolicy(path, &req).Do()
	if err != nil {
		return nil, err
	}

	fmt.Fprintln(w, "Policy:")
	for _, binding := range response.Bindings {
		fmt.Fprintf(w, "Role: %s\n", binding.Role)
		for _, member := range binding.Members {
			fmt.Fprintf(w, "\tMember: %s\n", member)
		}
	}

	return response, nil
}

Java

/** Retrieves IAM permissions for the given registry. */
protected static void getIamPermissions(String projectId, String cloudRegion, String registryName)
    throws GeneralSecurityException, IOException {
  GoogleCredentials credential =
      GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
  HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
  final CloudIot service =
      new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
          .setApplicationName(APP_NAME)
          .build();

  final String registryPath =
      String.format(
          "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);

  com.google.api.services.cloudiot.v1.model.Policy policy =
      service
          .projects()
          .locations()
          .registries()
          .getIamPolicy(registryPath, new GetIamPolicyRequest())
          .execute();

  System.out.println("Policy ETAG: " + policy.getEtag());

  if (policy.getBindings() != null) {
    for (com.google.api.services.cloudiot.v1.model.Binding binding : policy.getBindings()) {
      System.out.println(String.format("Role: %s", binding.getRole()));
      System.out.println("Binding members: ");
      for (String member : binding.getMembers()) {
        System.out.println(String.format("\t%s", member));
      }
    }
  } else {
    System.out.println(String.format("No policy bindings for %s", registryName));
  }
}

Node.js

// const cloudRegion = 'us-central1';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';
const iot = require('@google-cloud/iot');

const iotClient = new iot.v1.DeviceManagerClient({
  // optional auth parameters.
});

async function getIamPolicy() {
  // Construct request
  const formattedResource = iotClient.registryPath(
    projectId,
    cloudRegion,
    registryId
  );

  let bindings;
  const [response] = await iotClient.getIamPolicy({
    resource: formattedResource,
  });

  bindings = response.bindings;
  const etag = response.etag;

  console.log('ETAG:', etag);
  bindings = bindings || [];

  bindings.forEach(_binding => {
    console.log(`Role: ${_binding.role}`);
    _binding.members || (_binding.members = []);
    _binding.members.forEach(_member => {
      console.log(`\t${_member}`);
    });
  });
}

getIamPolicy();

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;

/**
 * Retrieves IAM permissions for the given registry.
 *
 * @param string $registryId IOT Device Registry ID
 * @param string $projectId Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function get_iam_policy(
    $registryId,
    $projectId,
    $location = 'us-central1'
) {
    print('Getting IAM Policy' . PHP_EOL);

    // Instantiate a client.
    $deviceManager = new DeviceManagerClient();

    // Format the full registry path
    $registryName = $deviceManager->registryName($projectId, $location, $registryId);

    $policy = $deviceManager->getIamPolicy($registryName);

    print($policy->serializeToJsonString() . PHP_EOL);
}

Python

# project_id = 'YOUR_PROJECT_ID'
# cloud_region = 'us-central1'
# registry_id = 'your-registry-id'
client = iot_v1.DeviceManagerClient()

registry_path = client.registry_path(project_id, cloud_region, registry_id)

policy = client.get_iam_policy(request={"resource": registry_path})

return policy

Ruby

# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry to get an IAM policy for"

require "google/apis/cloudiot_v1"

# Initialize the client and authenticate with the specified scope
Cloudiot   = Google::Apis::CloudiotV1
iot_client = Cloudiot::CloudIotService.new
iot_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the location associated with the project
parent   = "projects/#{project_id}/locations/#{location_id}"
resource = "#{parent}/registries/#{registry_id}"

# List the devices in the provided region
policy = iot_client.get_registry_iam_policy(
  resource
)

if policy.bindings
  policy.bindings.each do |binding|
    puts "Role: #{binding.role} Member: #{binding.members[0]}"
  end
else
  puts "No bindings"
end

ポリシーの設定

Console

デバイス レジストリ レベルでアクセス制御を設定するには:

  1. Google Cloud コンソールで、[レジストリ] ページに移動します。

    [レジストリ] ページに移動する

  2. 権限を設定するデバイス レジストリの横にあるチェックボックスをオンにします。情報パネルが開かない場合は、[情報パネルを表示] をクリックします。

  3. [権限] をクリックします。[権限] ペインが開きます。

  4. 1 人以上のユーザーを入力し、プルダウン メニューからロールを選択して、[追加] をクリックします。

gcloud

デバイス レジストリにポリシーを設定するには、gcloud iot registries set-iam-policy コマンドを実行します。

gcloud iot registries set-iam-policy REGISTRY_ID \
  --region=REGION \
  POLICY_FILE

API

API を介して IAM 権限を設定するには、DeviceRegistry setIamPolicy メソッドを使用します。

C#

public static object SetIamPolicy(string projectId, string cloudRegion, string registryId,
                                 string role, string member)
{
    var cloudIot = CreateAuthorizedClient();
    // The resource name of the location associated with the key rings.
    var parent = $"projects/{projectId}/locations/{cloudRegion}/registries/{registryId}";
    try
    {
        var req = new SetIamPolicyRequest();
        Policy pol = new Policy();
        pol.Bindings = new List<Binding>();
        Binding bind = new Binding()
        {
            Role = role,
            Members = new List<string>()
        };
        bind.Members.Add(member);
        pol.Bindings.Add(bind);

        req.Policy = pol;
        var result = cloudIot.Projects.Locations.Registries.SetIamPolicy(req, parent).Execute();
    }
    catch (Google.GoogleApiException e)
    {
        Console.WriteLine(e.Message);
        return e.Error.Code;
    }
    return 0;
}

Go


// setRegistryIAM sets the IAM policy for a device registry
func setRegistryIAM(w io.Writer, projectID string, region string, registryID string, member string, role string) (*cloudiot.Policy, error) {
	// Authorize the client using Application Default Credentials.
	// See https://g.co/dv/identity/protocols/application-default-credentials
	ctx := context.Background()
	httpClient, err := google.DefaultClient(ctx, cloudiot.CloudPlatformScope)
	if err != nil {
		return nil, err
	}
	client, err := cloudiot.New(httpClient)
	if err != nil {
		return nil, err
	}

	req := cloudiot.SetIamPolicyRequest{
		Policy: &cloudiot.Policy{
			Bindings: []*cloudiot.Binding{
				{
					Members: []string{member},
					Role:    role,
				},
			},
		},
	}
	path := fmt.Sprintf("projects/%s/locations/%s/registries/%s", projectID, region, registryID)
	response, err := client.Projects.Locations.Registries.SetIamPolicy(path, &req).Do()
	if err != nil {
		return nil, err
	}

	fmt.Fprintf(w, "Successfully set IAM policy for registry: %s\n", registryID)

	return response, nil
}

Java

/** Sets IAM permissions for the given registry. */
protected static void setIamPermissions(
    String projectId, String cloudRegion, String registryName, String member, String role)
    throws GeneralSecurityException, IOException {
  GoogleCredentials credential =
      GoogleCredentials.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
  HttpRequestInitializer init = new HttpCredentialsAdapter(credential);
  final CloudIot service =
      new CloudIot.Builder(GoogleNetHttpTransport.newTrustedTransport(), jsonFactory, init)
          .setApplicationName(APP_NAME)
          .build();

  final String registryPath =
      String.format(
          "projects/%s/locations/%s/registries/%s", projectId, cloudRegion, registryName);

  com.google.api.services.cloudiot.v1.model.Policy policy =
      service
          .projects()
          .locations()
          .registries()
          .getIamPolicy(registryPath, new GetIamPolicyRequest())
          .execute();

  List<com.google.api.services.cloudiot.v1.model.Binding> bindings = policy.getBindings();

  boolean addNewRole = true;
  if (bindings != null) {
    for (com.google.api.services.cloudiot.v1.model.Binding binding : bindings) {
      if (binding.getRole().equals(role)) {
        List<String> members = binding.getMembers();
        members.add(member);
        binding.setMembers(members);
        addNewRole = false;
      }
    }
  } else {
    bindings = new ArrayList<>();
  }

  if (addNewRole) {
    com.google.api.services.cloudiot.v1.model.Binding bind =
        new com.google.api.services.cloudiot.v1.model.Binding();
    bind.setRole(role);
    List<String> members = new ArrayList<>();
    members.add(member);
    bind.setMembers(members);

    bindings.add(bind);
  }

  policy.setBindings(bindings);
  SetIamPolicyRequest req = new SetIamPolicyRequest().setPolicy(policy);

  policy = service.projects().locations().registries().setIamPolicy(registryPath, req).execute();

  System.out.println("Policy ETAG: " + policy.getEtag());
  for (com.google.api.services.cloudiot.v1.model.Binding binding : policy.getBindings()) {
    System.out.println(String.format("Role: %s", binding.getRole()));
    System.out.println("Binding members: ");
    for (String mem : binding.getMembers()) {
      System.out.println(String.format("\t%s", mem));
    }
  }
}

Node.js

// const cloudRegion = 'us-central1';
// const projectId = 'adjective-noun-123';
// const registryId = 'my-registry';

const iot = require('@google-cloud/iot');

const iotClient = new iot.v1.DeviceManagerClient({
  // optional auth parameters.
});

async function setIamPolicy() {
  // Construct request
  const resource = iotClient.registryPath(projectId, cloudRegion, registryId);

  const policy = {
    bindings: [
      {
        members: [member],
        role: role,
      },
    ],
  };

  const request = {
    resource: resource,
    policy: policy,
  };

  let bindings;

  const [response] = await iotClient.setIamPolicy(request);

  bindings = response.bindings;
  const etag = response.etag;

  console.log('ETAG:', etag);
  bindings = bindings || [];

  bindings.forEach(_binding => {
    console.log(`Role: ${_binding.role}`);
    _binding.members || (_binding.members = []);
    _binding.members.forEach(_member => {
      console.log(`\t${_member}`);
    });
  });
}

setIamPolicy();

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;
use Google\Cloud\Iam\V1\Policy;
use Google\Cloud\Iam\V1\Binding;

/**
 * Sets IAM permissions for the given registry to a single role/member.
 *
 * @param string $registryId IOT Device Registry ID
 * @param string $role Role used for IAM commands
 * @param string $member Member used for IAM commands
 * @param string $projectId Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function set_iam_policy(
    $registryId,
    $role,
    $member,
    $projectId,
    $location = 'us-central1'
) {
    print('Setting IAM policy' . PHP_EOL);

    // Instantiate a client.
    $deviceManager = new DeviceManagerClient();
    $registryName = $deviceManager->registryName($projectId, $location, $registryId);

    $binding = (new Binding())
        ->setMembers([$member])
        ->setRole($role);

    $policy = (new Policy())
        ->setBindings([$binding]);

    $policy = $deviceManager->setIamPolicy($registryName, $policy);

    print($policy->serializeToJsonString() . PHP_EOL);
}

Python

# project_id = 'YOUR_PROJECT_ID'
# cloud_region = 'us-central1'
# registry_id = 'your-registry-id'
# role = 'viewer'
# member = 'group:dpebot@google.com'
client = iot_v1.DeviceManagerClient()
registry_path = client.registry_path(project_id, cloud_region, registry_id)

body = {"bindings": [{"members": [member], "role": role}]}

return client.set_iam_policy(request={"resource": registry_path, "policy": body})

Ruby

# project_id  = "Your Google Cloud project ID"
# location_id = "The Cloud region the registry is located in"
# registry_id = "The registry to set an IAM policy for"
# member      = "The member to add to the policy bindings"
# role        = "The role for the binding the policy is set to"

require "google/apis/cloudiot_v1"

# Initialize the client and authenticate with the specified scope
Cloudiot   = Google::Apis::CloudiotV1
iot_client = Cloudiot::CloudIotService.new
iot_client.authorization = Google::Auth.get_application_default(
  "https://www.googleapis.com/auth/cloud-platform"
)

# The resource name of the location associated with the project
parent   = "projects/#{project_id}/locations/#{location_id}"
resource = "#{parent}/registries/#{registry_id}"

request = Google::Apis::CloudiotV1::SetIamPolicyRequest.new
policy  = Google::Apis::CloudiotV1::Policy.new
binding = Google::Apis::CloudiotV1::Binding.new
binding.members = [member]
binding.role    = role
policy.bindings = [binding]
request.policy  = policy

# List the devices in the provided region
result = iot_client.set_registry_iam_policy(
  resource, request
)

if result.bindings
  puts "Binding set:"
  result.bindings.each do |binding|
    puts "\tRole: #{binding.role} Member: #{binding.members[0]}"
  end
else
  puts "No bindings"
end