Authentification en tant que compte de service

Cet article explique comment authentifier une application en tant que compte de service. Pour obtenir des informations générales sur l'authentification auprès des API Google Cloud, y compris les scénarios et les stratégies d'authentification courants, consultez la page Présentation de l'authentification. Pour en savoir plus sur les comptes de service, consultez la section Comptes de service dans la documentation sur la gestion de l'authentification et des accès.

Rechercher automatiquement des identifiants

Si votre application s'exécute dans un environnement Google Cloud doté d'un compte de service par défaut, elle peut récupérer les identifiants du compte de service pour appeler les API Google Cloud. Ces environnements incluent Compute Engine, Google Kubernetes Engine, App Engine, Cloud Run et Cloud Functions. Nous vous recommandons d'utiliser cette stratégie, car elle est plus pratique et plus sécurisée que la transmission manuelle des identifiants.

En outre, nous vous recommandons d'utiliser les bibliothèques clientes Google Cloud pour votre application. Les bibliothèques clientes Google Cloud utilisent une bibliothèque appelée "Application Default Credentials" (ADC) pour rechercher automatiquement vos identifiants de compte de service. L'ADC recherche les identifiants du compte de service dans l'ordre suivant :

  1. Si la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS est définie, ADC utilise le fichier de compte de service vers lequel renvoie la variable.

  2. Si la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS n'est pas définie, ADC utilise le compte de service par défaut fourni par Compute Engine, Google Kubernetes Engine, App Engine, Cloud Run et Cloud Functions.

  3. Si l'ADC ne peut utiliser aucune des informations d'identification ci-dessus, une erreur se produit.

L'exemple de code suivant montre comment utiliser la bibliothèque ADC dans le code de votre application :

C#

public object AuthImplicit(string projectId)
{
    // If you don't specify credentials when constructing the client, the
    // client library will look for credentials in the environment.
    var credential = GoogleCredential.GetApplicationDefault();
    var storage = StorageClient.Create(credential);
    // Make an authenticated API request.
    var buckets = storage.ListBuckets(projectId);
    foreach (var bucket in buckets)
    {
        Console.WriteLine(bucket.Name);
    }
    return null;
}

Go


// implicit uses Application Default Credentials to authenticate.
func implicit() {
	ctx := context.Background()

	// For API packages whose import path is starting with "cloud.google.com/go",
	// such as cloud.google.com/go/storage in this case, if there are no credentials
	// provided, the client library will look for credentials in the environment.
	storageClient, err := storage.NewClient(ctx)
	if err != nil {
		log.Fatal(err)
	}

	it := storageClient.Buckets(ctx, "project-id")
	for {
		bucketAttrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(bucketAttrs.Name)
	}

	// For packages whose import path is starting with "google.golang.org/api",
	// such as google.golang.org/api/cloudkms/v1, use NewService to create the client.
	kmsService, err := cloudkms.NewService(ctx)
	if err != nil {
		log.Fatal(err)
	}

	_ = kmsService
}

Java

static void authImplicit() {
  // If you don't specify credentials when constructing the client, the client library will
  // look for credentials via the environment variable GOOGLE_APPLICATION_CREDENTIALS.
  Storage storage = StorageOptions.getDefaultInstance().getService();

  System.out.println("Buckets:");
  Page<Bucket> buckets = storage.list();
  for (Bucket bucket : buckets.iterateAll()) {
    System.out.println(bucket.toString());
  }
}

Node.js

// Imports the Google Cloud client library.
const {Storage} = require('@google-cloud/storage');

// Instantiates a client. If you don't specify credentials when constructing
// the client, the client library will look for credentials in the
// environment.
const storage = new Storage();
// Makes an authenticated API request.
async function listBuckets() {
  try {
    const results = await storage.getBuckets();

    const [buckets] = results;

    console.log('Buckets:');
    buckets.forEach(bucket => {
      console.log(bucket.name);
    });
  } catch (err) {
    console.error('ERROR:', err);
  }
}
listBuckets();

PHP

// Imports the Cloud Storage client library.
use Google\Cloud\Storage\StorageClient;

function auth_cloud_implicit($projectId)
{
    $config = [
        'projectId' => $projectId,
    ];

    # If you don't specify credentials when constructing the client, the
    # client library will look for credentials in the environment.
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def implicit():
    from google.cloud import storage

    # If you don't specify credentials when constructing the client, the
    # client library will look for credentials in the environment.
    storage_client = storage.Client()

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

# project_id = "Your Google Cloud project ID"

require "google/cloud/storage"

# If you don't specify credentials when constructing the client, the client
# library will look for credentials in the environment.
storage = Google::Cloud::Storage.new project: project_id

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

Transmettre manuellement des identifiants

Si votre application s'exécute en dehors des environnements Google Cloud qui fournissent un compte de service par défaut, vous devez en créer un manuellement. Vous pouvez ensuite créer une ou plusieurs clés de compte de service, qui sont des identifiants associés au compte de service. Les clés de compte de service peuvent ensuite être transmises manuellement à votre application.

Créer un compte de service

Les étapes suivantes décrivent comment créer un compte de service si vous n'en avez pas :

Cloud Console

  1. Dans Cloud Console, accédez à la page Créer une clé de compte de service.

    Accéder à la page "Créer une clé de compte de service"
  2. Dans la liste Compte de service, sélectionnez Nouveau compte de service.
  3. Dans le champ Nom du compte de service, saisissez un nom.
  4. Dans la liste Rôle, sélectionnez Projet > Propriétaire

  5. Cliquez sur Créer. Un fichier JSON contenant votre clé est téléchargé sur votre ordinateur.

Ligne de commande

Vous pouvez exécuter les commandes suivantes à l'aide du SDK Cloud sur votre ordinateur local, ou dans Cloud Shell.

  1. Créez le compte de service. Remplacez NAME par le nom que vous souhaitez donner au compte de service.

    gcloud iam service-accounts create NAME
  2. Accordez des autorisations au compte de service. Remplacez PROJECT_ID par votre ID de projet.

    gcloud projects add-iam-policy-binding PROJECT_ID --member="serviceAccount:NAME@PROJECT_ID.iam.gserviceaccount.com" --role="roles/owner"
  3. Générez le fichier de clé. Remplacez FILE_NAME par le nom du fichier de clé.

    gcloud iam service-accounts keys create FILE_NAME.json --iam-account=NAME@PROJECT_ID.iam.gserviceaccount.com

Transmettre des identifiants via une variable d'environnement

Fournissez des identifiants d'authentification au code de votre application en définissant la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS. Remplacez [PATH] par le chemin du fichier JSON contenant la clé de votre compte de service. Cette variable ne s'applique qu'à la session d'interface système actuelle. Par conséquent, si vous ouvrez une nouvelle session, vous devez la définir à nouveau.

Linux ou macOS

export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"

Exemple :

export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/my-key.json"

Windows

Avec PowerShell :

$env:GOOGLE_APPLICATION_CREDENTIALS="[PATH]"

Exemple :

$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\my-key.json"

Avec l'invite de commande :

set GOOGLE_APPLICATION_CREDENTIALS=[PATH]

Une fois que vous avez terminé les étapes ci-dessus, l'ADC peut trouver automatiquement vos identifiants, comme décrit dans la section ci-dessus. Nous vous recommandons d'utiliser la stratégie ADC, car elle nécessite moins de code et rend votre code portable dans environnements différents.

Transmettre des identifiants grâce à du code

Vous pouvez également choisir de renvoyer explicitement vers votre fichier de compte de service, directement dans le code comme indiqué dans l'exemple suivant. Vous devez installer la bibliothèque cliente Cloud Storage pour exécuter l'exemple suivant.

C#

        // Some APIs, like Storage, accept a credential in their Create()
        // method.
        public object AuthExplicit(string projectId, string jsonPath)
        {
            // Explicitly use service account credentials by specifying
            // the private key file.
            var credential = GoogleCredential.FromFile(jsonPath);
            var storage = StorageClient.Create(credential);
            // Make an authenticated API request.
            var buckets = storage.ListBuckets(projectId);
            foreach (var bucket in buckets)
            {
                Console.WriteLine(bucket.Name);
            }
            return null;
        }
        // Other APIs, like Language, accept a channel in their Create()
        // method.
        public object AuthExplicit(string projectId, string jsonPath)
        {
            LanguageServiceClientBuilder builder = new LanguageServiceClientBuilder
            {
                CredentialsPath = jsonPath
            };

            LanguageServiceClient client = builder.Build();
            AnalyzeSentiment(client);
            return 0;
        }

Go


// explicit reads credentials from the specified path.
func explicit(jsonPath, projectID string) {
	ctx := context.Background()
	client, err := storage.NewClient(ctx, option.WithCredentialsFile(jsonPath))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Buckets:")
	it := client.Buckets(ctx, projectID)
	for {
		battrs, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(battrs.Name)
	}
}

Java

static void authExplicit(String jsonPath) throws IOException {
  // You can specify a credential file by providing a path to GoogleCredentials.
  // Otherwise credentials are read from the GOOGLE_APPLICATION_CREDENTIALS environment variable.
  GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(jsonPath))
        .createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
  Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

  System.out.println("Buckets:");
  Page<Bucket> buckets = storage.list();
  for (Bucket bucket : buckets.iterateAll()) {
    System.out.println(bucket.toString());
  }
}

Node.js

// Imports the Google Cloud client library.
const {Storage} = require('@google-cloud/storage');

// Instantiates a client. Explicitly use service account credentials by
// specifying the private key file. All clients in google-cloud-node have this
// helper, see https://github.com/GoogleCloudPlatform/google-cloud-node/blob/master/docs/authentication.md
// const projectId = 'project-id'
// const keyFilename = '/path/to/keyfile.json'
const storage = new Storage({projectId, keyFilename});

// Makes an authenticated API request.
async function listBuckets() {
  try {
    const [buckets] = await storage.getBuckets();

    console.log('Buckets:');
    buckets.forEach(bucket => {
      console.log(bucket.name);
    });
  } catch (err) {
    console.error('ERROR:', err);
  }
}
listBuckets();

PHP

namespace Google\Cloud\Samples\Auth;

// Imports the Cloud Storage client library.
use Google\Cloud\Storage\StorageClient;

function auth_cloud_explicit($projectId, $serviceAccountPath)
{
    # Explicitly use service account credentials by specifying the private key
    # file.
    $config = [
        'keyFilePath' => $serviceAccountPath,
        'projectId' => $projectId,
    ];
    $storage = new StorageClient($config);

    # Make an authenticated API request (listing storage buckets)
    foreach ($storage->buckets() as $bucket) {
        printf('Bucket: %s' . PHP_EOL, $bucket->name());
    }
}

Python

def explicit():
    from google.cloud import storage

    # Explicitly use service account credentials by specifying the private key
    # file.
    storage_client = storage.Client.from_service_account_json(
        'service_account.json')

    # Make an authenticated API request
    buckets = list(storage_client.list_buckets())
    print(buckets)

Ruby

# project_id = "Your Google Cloud project ID"
# key_file   = "path/to/service-account.json"
require "google/cloud/storage"

# Explicitly use service account credentials by specifying the private key
# file.
storage = Google::Cloud::Storage.new project: project_id, keyfile: key_file

# Make an authenticated API request
storage.buckets.each do |bucket|
  puts bucket.name
end

Bonnes pratiques de gestion des identifiants

Les identifiants permettent d'accéder aux données sensibles. Les pratiques suivantes vous aident à protéger l'accès à vos identifiants.

  • N'intégrez pas les informations secrètes liées à l'authentification dans le code source, telles que les clés API, les jetons OAuth et les clés de compte de service. Vous pouvez utiliser une variable d'environnement renvoyant vers des identifiants en dehors du code source de l'application, comme Cloud Key Management Service.

  • Créez et utilisez différents identifiants pour différents contextes, comme par exemple pour les environnements de test et de production.

  • Ne transférez vos identifiants que via un canal sécurisé tel que HTTPS pour empêcher un tiers de les intercepter. Ne les transférez jamais en texte clair ou dans l'URL.

  • N'intégrez jamais des identifiants de longue durée dans votre application côté client. Par exemple, n'intégrez pas les clés de compte de service dans une application mobile. Les applications côté client peuvent être analysées et les identifiants pourraient facilement être découverts et utilisés par un tiers.

  • Révoquez un jeton si vous n'en avez plus besoin.

Dépanner les erreurs d'API

Pour en savoir plus sur le dépannage des requêtes d'API ayant échoué, consultez la section Erreurs.

Étapes suivantes

Faites l'essai

Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.

Profiter d'un essai gratuit