Autentícate como cuenta de servicio

En este tema, se explica cómo autenticar una aplicación como una cuenta de servicio. Para obtener información general sobre la autenticación en las API de Google Cloud, incluidas las situaciones y las estrategias de autenticación comunes, consulta Descripción general de la autenticación. Para obtener más información sobre las cuentas de servicio, consulta cuentas de servicio en la documentación de la administración de identidades y accesos.

Encuentra credenciales de forma automática

Si tu aplicación se ejecuta dentro de un entorno de Google Cloud que tiene una cuenta de servicio predeterminada, la aplicación puede recuperar las credenciales de la cuenta de servicio para llamar a las API de Google Cloud. Entre estos entornos, se incluyen Compute Engine, Google Kubernetes Engine, App Engine, Cloud Run y Cloud Functions. Recomendamos usar esta estrategia porque es más conveniente y segura que pasar las credenciales de forma manual.

Además, te recomendamos usar las bibliotecas cliente de Google Cloud para tu aplicación. Las bibliotecas cliente de Google Cloud usan una biblioteca llamada credenciales predeterminadas de la aplicación (ADC) para encontrar de forma automática las credenciales de la cuenta de servicio. ADC busca las credenciales de la cuenta de servicio en el siguiente orden:

  1. Si se establece la variable de entorno GOOGLE_APPLICATION_CREDENTIALS, ADC usa el archivo de la cuenta de servicio al que apunta la variable.

  2. Si la variable de entorno GOOGLE_APPLICATION_CREDENTIALS no se estableció, ADC usa la cuenta de servicio predeterminada que proporcionan Compute Engine, Google Kubernetes Engine, App Engine, Cloud Run y Cloud Functions.

  3. Se mostrará un error si ADC no puede usar ninguna de las credenciales ya mencionadas.

En el siguiente ejemplo de código, se ilustra cómo usar la biblioteca ADC en el código de la aplicación:

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

Pasa las credenciales de forma manual

Si tu aplicación se ejecuta fuera de los entornos de Google Cloud que proporcionan una cuenta de servicio predeterminada, debes crear una de forma manual. Luego, puedes crear una o más claves de cuenta de servicio, que son credenciales asociadas con la cuenta de servicio. Las claves de la cuenta de servicio se pueden pasar de forma manual a tu aplicación.

Crea una cuenta de servicio

En los siguientes pasos, se describe cómo crear una cuenta de servicio si no tienes una:

Cloud Console

  1. En Cloud Console, ve a la página Crear una clave de cuenta de servicio.

    Ir a la página Crear clave de la cuenta de servicio
  2. En la lista Cuenta de servicio, selecciona Cuenta de servicio nueva.
  3. Ingresa un nombre en el campo Nombre de cuenta de servicio.
  4. En la lista Función, selecciona Proyecto > Propietario.

    Nota: El campo Función autoriza tu cuenta de servicio para acceder a los recursos. Puedes ver y cambiar este campo más adelante mediante Cloud Console. Si desarrollas una app de producción, especifica permisos más detallados que Proyecto > Propietario. Para obtener más información, consulta Cómo otorgar funciones a las cuentas de servicio.
  5. Haz clic en Crear. Se descargará un archivo JSON que contiene tus claves a tu computadora.

Línea de comandos

Puedes ejecutar los siguientes comandos mediante el SDK de Cloud en tu máquina local o en Cloud Shell.

  1. Crea la cuenta de servicio. Reemplaza [NAME] por un nombre para la cuenta de servicio.

    gcloud iam service-accounts create [NAME]
  2. Otorga permisos a la cuenta de servicio. Reemplaza [PROJECT_ID] por el ID del proyecto.

    gcloud projects add-iam-policy-binding [PROJECT_ID] --member "serviceAccount:[NAME]@[PROJECT_ID].iam.gserviceaccount.com" --role "roles/owner"
    Nota: El campo Función autoriza a la cuenta de servicio a acceder a los recursos. Puedes ver y cambiar este campo más adelante mediante Cloud Console. Si desarrollas una app de producción, especifica permisos más detallados que Proyecto > Propietario. Para obtener más información, consulta Otorga funciones a las cuentas de servicio.
  3. Genera el archivo de claves. Reemplaza [FILE_NAME] por un nombre para el archivo de claves.

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

Pasa las credenciales a través de la variable de entorno

Configura la variable de entorno GOOGLE_APPLICATION_CREDENTIALS para proporcionar credenciales de autenticación al código de la aplicación. Reemplaza [PATH] por la ruta de acceso del archivo JSON que contiene la clave de tu cuenta de servicio. Esta variable solo se aplica a la sesión actual de shell. Por lo tanto, si abres una sesión nueva, deberás volver a configurar la variable.

Linux o macOS

export GOOGLE_APPLICATION_CREDENTIALS="[PATH]"

Por ejemplo:

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

Windows

Con PowerShell:

$env:GOOGLE_APPLICATION_CREDENTIALS="[PATH]"

Por ejemplo:

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

Con el símbolo del sistema:

set GOOGLE_APPLICATION_CREDENTIALS=[PATH]

Después de completar los pasos anteriores, ADC puede encontrar tus credenciales de forma automática, como se describe en la sección anterior. Recomendamos usar ADC porque requiere menos código y este es portátil en entornos diferentes.

Pasa las credenciales mediante el uso de código

También puedes apuntar de forma explícita hacia el archivo de la cuenta de servicio en el código, como se muestra en el siguiente ejemplo. Instala la biblioteca cliente de Cloud Storage para ejecutar el siguiente ejemplo.

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

Prácticas recomendadas para administrar credenciales

Las credenciales proporcionan acceso a datos sensibles. Con las siguientes prácticas, podrás proteger el acceso a tus credenciales.

  • No incorpores secretos relacionados con la autenticación en el código fuente, como claves de API, tokens de OAuth y claves de cuentas de servicio. Puedes usar una variable de entorno que apunte hacia las credenciales externas al código fuente de la aplicación, como Cloud Key Management Service.

  • Crea y usa credenciales distintas para contextos diferentes, como en entornos de pruebas y de producción.

  • Transfiere las credenciales solo mediante un canal seguro, como HTTPS, para evitar que terceros las intercepten. Nunca las transfieras en texto no encriptado o como parte de una URL.

  • Nunca incorpores credenciales de larga duración en la aplicación del cliente. Por ejemplo, no incorpores claves de cuentas de servicio en una app para dispositivos móviles. Las apps del cliente se pueden examinar, y un tercero puede encontrar y usar las credenciales con facilidad.

  • Revoca un token si ya no lo necesitas.

Soluciona problemas de API

Revisa la sección sobre errores de las API de Cloud para obtener más información sobre cómo solucionar problemas de las solicitudes a la API con errores.

Próximos pasos