Authenticating Applications

This page explains how to use user-managed service accounts and their private keys to authenticate an application to the Cloud IoT Core API.

You can use applications to administer registries and devices. See Registry Management Samples and Device Management Samples for examples of how to do so.

Authenticating using service accounts

A user-managed service account is a type of Google account that represents an application. User-managed service accounts are primarily used for server-to-API authentication.

Cloud IoT Core uses two types of authentication. When authenticating devices to Cloud IoT Core, you use private/public key pairs and JSON Web Tokens. When authenticating an application to the Cloud IoT Core API, however, you must use GCP authentication in the form of user-managed service accounts.

User-managed service accounts have their own private keys, which come in various formats. By providing a user-managed service account's private key to an application, you can create credentials and authenticate the application.

The recommended way to authenticate applications is to use user-managed service accounts and private JSON keys, as they are the most widely supported and flexible methods. You can create a user-managed service account and download a private JSON key by completing the steps in Getting Started with Authentication.

The following samples show how to use a user-managed service account's private JSON key to authenticate an application to the Cloud IoT Core API:

C#

Note that the C# sample doesn't explicitly specify a JSON key file; rather, it uses the location specified in the GOOGLE_APPLICATION_CREDENTIALS environment variable. The client library can then determine the credentials implicitly.
public static CloudIotService CreateAuthorizedClient()
{
    GoogleCredential credential =
        GoogleCredential.GetApplicationDefaultAsync().Result;
    // Inject the Cloud IoT Core Service scope
    if (credential.IsCreateScopedRequired)
    {
        credential = credential.CreateScoped(new[]
        {
            CloudIotService.Scope.CloudPlatform // Used for IoT + PubSub + IAM
            //CloudIotService.Scope.Cloudiot // Can be used if not accessing Pub/Sub
        });
    }
    return new CloudIotService(new BaseClientService.Initializer
    {
        HttpClientInitializer = credential,
        GZipEnabled = false
    });
}

Go

Note that the Go sample doesn't explicitly specify a JSON key file; rather, it uses the location specified in the GOOGLE_APPLICATION_CREDENTIALS environment variable. The client library can then determine the credentials implicitly. The sample is also used in the context of creating a registry, but the actual authentication is highlighted below.
// 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
}

registry := cloudiot.DeviceRegistry{
	Id: registryID,
	EventNotificationConfigs: []*cloudiot.EventNotificationConfig{
		{
			PubsubTopicName: topicName,
		},
	},
}

parent := fmt.Sprintf("projects/%s/locations/%s", projectID, region)
response, err := client.Projects.Locations.Registries.Create(parent, &registry).Do()
if err != nil {
	return nil, err
}

fmt.Println("Created registry:")
fmt.Println("\tID: ", response.Id)
fmt.Println("\tHTTP: ", response.HttpConfig.HttpEnabledState)
fmt.Println("\tMQTT: ", response.MqttConfig.MqttEnabledState)
fmt.Println("\tName: ", response.Name)

Java

Note that the Java sample doesn't explicitly specify a JSON key file; rather, it uses the location specified in the GOOGLE_APPLICATION_CREDENTIALS environment variable. The client library can then determine the credentials implicitly. The sample is also used in the context of creating a registry, but the actual authentication is highlighted below.
/** Create a registry for Cloud IoT. */
public static void createRegistry(String cloudRegion, String projectId, String registryName,
                                  String pubsubTopicPath)
    throws GeneralSecurityException, IOException {
  GoogleCredential credential =
      GoogleCredential.getApplicationDefault().createScoped(CloudIotScopes.all());
  JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
  HttpRequestInitializer init = new RetryHttpInitializerWrapper(credential);
  final CloudIot service = new CloudIot.Builder(
      GoogleNetHttpTransport.newTrustedTransport(),jsonFactory, init)
      .setApplicationName(APP_NAME).build();

  final String projectPath = "projects/" + projectId + "/locations/" + cloudRegion;
  final String fullPubsubPath = "projects/" + projectId + "/topics/" + pubsubTopicPath;

  DeviceRegistry registry = new DeviceRegistry();
  EventNotificationConfig notificationConfig = new EventNotificationConfig();
  notificationConfig.setPubsubTopicName(fullPubsubPath);
  List<EventNotificationConfig> notificationConfigs = new ArrayList<EventNotificationConfig>();
  notificationConfigs.add(notificationConfig);
  registry.setEventNotificationConfigs(notificationConfigs);
  registry.setId(registryName);

  DeviceRegistry reg = service.projects().locations().registries().create(projectPath,
      registry).execute();
  System.out.println("Created registry: " + reg.getName());
}

Node.js

function getClient (serviceAccountJson, cb) {
  const serviceAccount = JSON.parse(fs.readFileSync(serviceAccountJson));
  const jwtAccess = new google.auth.JWT();
  jwtAccess.fromJSON(serviceAccount);
  // Note that if you require additional scopes, they should be specified as a
  // string, separated by spaces.
  jwtAccess.scopes = 'https://www.googleapis.com/auth/cloud-platform';
  // Set the default authentication to the above JWT access.
  google.options({ auth: jwtAccess });

  const discoveryUrl = `${DISCOVERY_API}?version=${API_VERSION}`;

  google.discoverAPI(discoveryUrl, {}, (err, client) => {
    if (err) {
      console.log('Error during API discovery', err);
      return undefined;
    }
    cb(client);
  });
}

PHP

use Google\Cloud\Iot\V1\DeviceManagerClient;

/**
 * List all registries in the project.
 *
 * @param string $projectId Google Cloud project ID
 * @param string $location (Optional) Google Cloud region
 */
function list_registries(
    $projectId,
    $location = 'us-central1'
) {
    print('Listing Registries' . PHP_EOL);

    // The Google Cloud Client Library automatically checks the environment
    // variable GOOGLE_APPLICATION_CREDENTIALS for the Service Account
    // credentials, and defaults scopes to [
    //    'https://www.googleapis.com/auth/cloud-platform',
    //    'https://www.googleapis.com/auth/cloudiot'
    // ].
    $deviceManager = new DeviceManagerClient();
    $locationName = $deviceManager->locationName($projectId, $location);

    $response = $deviceManager->listDeviceRegistries($locationName);

    foreach ($response->iterateAllElements() as $registry) {
        printf(' - Id: %s, Name: %s' . PHP_EOL,
            $registry->getId(),
            $registry->getName());
    }
}

Python

This sample uses the Google API Client Library for Python.
def get_client(service_account_json):
    """Returns an authorized API client by discovering the IoT API and creating
    a service object using the service account credentials JSON."""
    api_scopes = ['https://www.googleapis.com/auth/cloud-platform']
    api_version = 'v1'
    discovery_api = 'https://cloudiot.googleapis.com/$discovery/rest'
    service_name = 'cloudiotcore'

    credentials = service_account.Credentials.from_service_account_file(
            service_account_json)
    scoped_credentials = credentials.with_scopes(api_scopes)

    discovery_url = '{}?version={}'.format(
            discovery_api, api_version)

    return discovery.build(
            service_name,
            api_version,
            discoveryServiceUrl=discovery_url,
            credentials=scoped_credentials)

Ruby

Note that the Ruby sample doesn't explicitly specify a JSON key file; rather, it uses the location specified in the GOOGLE_APPLICATION_CREDENTIALS environment variable. The client library can then determine the credentials implicitly. The sample is also used in the context of creating a registry, but the actual authentication is highlighted below.
# project_id   = "Your Google Cloud project ID"
# location_id  = "The Cloud region that you created the registry in"
# registry_id  = "The Google Cloud IoT Core device registry identifier"
# pubsub_topic = "The Google Cloud PubSub topic to use for this registry"

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 project / location where the registry is created.
parent = "projects/#{project_id}/locations/#{location_id}"

registry = Cloudiot::DeviceRegistry.new
registry.id = registry_id
registry.event_notification_configs = [Cloudiot::EventNotificationConfig::new]
registry.event_notification_configs[0].pubsub_topic_name = pubsub_topic

registry = iot_client.create_project_location_registry(
    parent, registry
)

puts "Created registry: #{registry.name}"

Was this page helpful? Let us know how we did:

Send feedback about...

Google Cloud Internet of Things Core