Accede a los recursos desde AWS

En este documento, se muestra cómo usar la federación de identidades para acceder a los recursos de Google Cloud desde Amazon Web Services (AWS).

En general, las aplicaciones que se ejecutan fuera de Google Cloud usan claves de cuentas de servicio para acceder a los recursos de Google Cloud. Mediante la federación de identidades, puedes permitir que un usuario o una función de AWS actúen en nombre de una cuenta de servicio. Esto permite que la carga de trabajo acceda a los recursos de Google Cloud directamente mediante un token de acceso de corta duración y quita la carga de seguridad y mantenimiento asociada con las claves de la cuenta de servicio.

Antes de comenzar

  1. Habilita las API de IAM, Resource Manager, Service Account Credentials, and Security Token Service (STS).

    Habilita las API

  2. Asegúrate de tener la función de administrador de grupo de Workload Identity (roles/iam.workloadIdentityPoolAdmin).

    De manera alternativa, la función básica de propietario de IAM (roles/owner) también incluye permisos para configurar la federación de identidades. No deberías otorgar funciones básicas en un entorno de producción, pero puedes otorgarlas en un entorno de desarrollo o de prueba.

  3. Actualiza la política de la organización para permitir la federación de AWS.

    De manera opcional, también puedes especificar qué ID de cuentas de AWS pueden acceder a tus recursos de Google Cloud.

  4. Crea una función de AWS y toma nota de Amazon Resource Name (ARN).

  5. Crea una cuenta de servicio de Google Cloud.

  6. Otorga acceso a la cuenta de servicio para llamar a las API de Google Cloud que requiere la carga de trabajo.

Crea un grupo de Workload Identity

Puedes usar un grupo de identidad de carga de trabajo para organizar y administrar identidades externas. Los grupos de Workload Identity se aíslan unos de otros, pero un solo grupo puede actuar en nombre de cualquier cantidad de cuentas de servicio. En general, recomendamos crear un grupo nuevo para cada uno de los entornos, como desarrollo, etapa de pruebas o producción, que por lo general significa un grupo por cuenta de AWS.

Para crear un nuevo grupo de Workload Identity, debes proporcionar un ID. También puedes proporcionar una descripción y un nombre visible opcionales.

gcloud

Ejecuta el comando gcloud iam workload-identity-pools create para crear un grupo de Workload Identity:

gcloud iam workload-identity-pools create pool-id \
    --location="global" \
    --description="description" \
    --display-name="display-name"

La respuesta es similar a la siguiente:

Created workload identity pool [pool-id].

REST

El método projects.locations.workloadIdentityPools.create crea un grupo de Workload Identity.

Método HTTP y URL:

POST https://iam.googleapis.com/v1beta/projects/project-id/locations/global/workloadIdentityPools?workloadIdentityPoolId=pool-id

Cuerpo JSON de la solicitud:

{
  "description": "description",
  "display-name": "display-name"
}

Para enviar tu solicitud, expande una de estas opciones:

Mediante este método, se muestra una Operation de larga duración similar a la siguiente:

{
  "name": "projects/project-number/locations/global/workloadIdentityPools/pool-id/operations/operation-id"
}

Agrega AWS como proveedor de identidad

A fin de configurar AWS como proveedor de identidad para el grupo de Workload Identity, proporciona al menos lo siguiente:

  • Un ID para el proveedor.

  • El ID del grupo de Workload Identity de la sección anterior de este documento

  • El ID de la cuenta de AWS.

También puedes proporcionar varios parámetros opcionales:

  • Un nombre visible y una descripción.

  • Una lista de mapas de atributos que mapean los atributos de un token de AWS a los atributos en un token de Google. De forma predeterminada, cada grupo usa los siguientes mapas de atributos, que abarcan las situaciones más comunes:

    Google AWS Descripción
    google.subject assertion.arn La principal que IAM autentica. Este también es el tema que aparece en las entradas de registro de Cloud Logging. Esta asignación se propaga de forma automática con el ARN mediante el formato arn:aws:sts::account-id:assumed-role/aws-role/aws-session-name.
    attribute.aws_role Función de AWS La función de AWS, con el formato arn:aws:sts::account-id:assumed-role/aws-role.

    También puedes especificar asignaciones personalizadas, a las que puedes hacer referencia en las vinculaciones de funciones de IAM. Usa assertion a fin de hacer referencia a la credencial de AWS, google para los atributos de Google y attribute para los atributos personalizados. Por ejemplo, lo siguiente mapea attribute.aws_account a assertion.account (además de la asignación predeterminada para google.subject):

    google.subject=assertion.arn,
    attribute.aws_account=assertion.account
    

    Consulta la documentación de GetCallerIdentity() para obtener una lista de atributos en los tokens de AWS a los que puedes hacer referencia. Ten en cuenta que los atributos en la documentación de AWS usan mayúsculas y minúsculas, mientras que la asignación de atributos usa minúsculas. Por ejemplo, Account se convierte en assertion.account.

    Para aserciones más complejas, puedes usar Common Expression Language. Por ejemplo:

    attribute.environment=assertion.arn.contains(":instance-profile/Production") ? "prod" : "test"
    

    Para hacer referencia a una parte específica de un atributo en una expresión, usa la función extract() de CEL, que extrae un valor de un atributo a partir de una plantilla que proporciones. Para obtener más información sobre extract(), consulta Extrae valores de atributos.

    Para verificar si una credencial contiene un atributo, usa la función has().

  • Una condición que especifica los atributos que debe mostrar el principal. La condición puede aplicarse a credenciales externas y de Google. Se rechaza cualquier solicitud que no cumpla con la condición.

    Las condiciones de los atributos tienen el formato de una expresión CEL que muestra un valor booleano. Por ejemplo, a continuación, se rechazan las solicitudes de cualquier identidad que no tenga una función específica de AWS:

    attribute.aws_role == "role-mapping"
    

    Para obtener más información sobre casos de uso comunes para las condiciones, consulta la descripción general de la federación de Workload Identity.

En el siguiente ejemplo, se muestra cómo agregar AWS como proveedor de identidad:

gcloud

Ejecuta el comando gcloud iam workload-identity-pools providers create-aws para agregar AWS como proveedor de identidad:

gcloud iam workload-identity-pools providers create-aws provider-id \
    --workload-identity-pool="pool-id" \
    --account-id="aws-account-id" \
    --location="global"

La respuesta es similar a la siguiente:

Created workload identity pool provider [provider-id].

REST

Mediante el método projects.locations.workloadIdentityPools.providers.create, se agrega AWS como proveedor.

Método HTTP y URL:

POST https://iam.googleapis.com/v1beta/projects/project-id/locations/global/workloadIdentityPools/pool-id/providers?workloadIdentityPoolProviderId=provider-id

Cuerpo JSON de la solicitud:

{
  "aws": {
    "accountId": "aws-account-id"
  }
}

Para enviar tu solicitud, expande una de estas opciones:

Mediante este método, se muestra una Operation de larga duración similar a la siguiente:

{
  "name": "projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id/operations/operation-id"
}

Otorga permiso para actuar en nombre de una cuenta de servicio

Las identidades externas no pueden acceder de forma directa a la mayoría de los recursos de Google Cloud. En su lugar, les otorgas la función de usuario de Workload Identity (roles/iam.workloadIdentityUser) para permitir que actúen en nombre de una cuenta de servicio.

Para agregar esta vinculación de función a una función de AWS, usa el siguiente formato:

attribute.aws_role/arn:aws:sts::aws-account-id:assumed-role/aws-role-name

Por ejemplo:

gcloud iam service-accounts add-iam-policy-binding service-account-email \
    --role roles/iam.workloadIdentityUser \
    --member "principalSet://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/attribute.aws_role/arn:aws:sts::aws-account-id:assumed-role/aws-role-name"

Para agregar esta vinculación a un usuario de AWS, usa el siguiente formato:

subject/arn:aws:sts::aws-account-id:assumed-role/aws-role-name/aws-session-name

Consulta la documentación de AWS sobre los identificadores de IAM para obtener información para extraer la sesión de función de AWS desde un ARN de AWS.

En el siguiente ejemplo, se demuestra cómo agregar una vinculación a un usuario de AWS:

gcloud iam service-accounts add-iam-policy-binding service-account-email \
    --role roles/iam.workloadIdentityUser \
    --member "principal://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/subject/arn:aws:sts::aws-account-id:assumed-role/aws-role-name/aws-session-name"

También puedes otorgar acceso en función de atributos personalizados. Por ejemplo:

gcloud iam service-accounts add-iam-policy-binding service-account-email \
    --role="roles/iam.workloadIdentityUser" \
    --member="principalSet://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/attribute.custom-attribute/arn:aws:sts::aws-account-id:aws-role-name"

Para revocar el acceso, reemplaza add-iam-policy-binding por remove-iam-policy-binding.

También puedes agregar o revocar vinculaciones mediante la API de REST o las bibliotecas cliente. Para obtener más información, consulta Otorga, cambia y revoca el acceso a los recursos.

Genera credenciales de Google

Si usas una biblioteca cliente compatible, puedes configurar la biblioteca cliente para que genere credenciales de Google automáticamente. De forma alternativa, puedes generar credenciales de AWS de forma manual y, luego, cambiarlas por credenciales de Google.

Te recomendamos que, cuando sea posible, generes las credenciales de forma automática para que no tengas que implementar el proceso de intercambio de tokens tú mismo.

Genera credenciales automáticamente

Si accedes a Google Cloud con una biblioteca cliente para uno de los siguientes lenguajes, puedes configurar la biblioteca cliente para que genere credenciales de forma automática mediante la federación de identidades:

C++

La mayoría de las bibliotecas cliente de Google Cloud para C++ admiten la federación de identidades mediante un objeto ChannelCredentials, que se crea mediante una llamada a grpc::GoogleDefaultCredentials(). Para inicializar esta credencial, debes compilar las bibliotecas cliente con la versión 1.36.0 o posterior de gRPC.

La biblioteca cliente de Cloud Storage para C++ usa la API de REST, no gRPC, por lo que no admite la federación de identidades.

Comienza a usarlo

Las bibliotecas cliente para Go admiten la federación de identidades si usan la versión v0.0.0-20210218202405-ba52d332ba99 o una versión posterior del módulo golang.org/x/oauth2.

Para verificar qué versión de este módulo usa tu biblioteca cliente, ejecuta los siguientes comandos:

cd $GOPATH/src/cloud.google.com/go
go list -m golang.org/x/oauth2

Java

Las bibliotecas cliente para Java admiten la federación de identidades si usan la versión 0.24.0 o posterior del artefacto com.google.auth:google-auth-library-oauth2-http.

Para verificar qué versión de este artefacto usa tu biblioteca cliente, ejecuta el siguiente comando de Maven en el directorio de tu aplicación:

mvn dependency:list -DincludeArtifactIds=google-auth-library-oauth2-http

Node.js

Las bibliotecas cliente de Node.js admiten la federación de identidades si usan la versión 7.0.2 o una versión posterior del paquete google-auth-library.

Para verificar qué versión de este paquete usa tu biblioteca cliente, ejecuta el siguiente comando en el directorio de tu aplicación:

npm list google-auth-library

Cuando creas un objeto GoogleAuth, puedes especificar un ID del proyecto o puedes permitir que GoogleAuth encuentre el ID del proyecto de forma automática. Para encontrar el ID del proyecto de manera automática, la cuenta de servicio en el archivo de configuración debe tener la función de Navegador (roles/browser) o una función con permisos equivalentes en tu proyecto. Para obtener más información, consulta el README del paquete google-auth-library.

Python

Las bibliotecas cliente para Python admiten la federación de identidades si usan la versión 1.27.0 o posterior del paquete google-auth.

Para verificar qué versión de este paquete usa tu biblioteca cliente, ejecuta el siguiente comando en el entorno en el que está instalado el paquete:

pip show google-auth

Si deseas especificar un ID del proyecto para el cliente de autenticación, puedes configurar la variable de entorno GOOGLE_CLOUD_PROJECT o permitir que el cliente busque el ID del proyecto de forma automática. Para encontrar el ID del proyecto de manera automática, la cuenta de servicio en el archivo de configuración debe tener la función de Navegador (roles/browser) o una función con permisos equivalentes en tu proyecto. Para obtener más información, consulta la guía del usuario del paquete google-auth.

A fin de configurar la biblioteca cliente para que genere credenciales de forma automática, ejecuta el comando gcloud iam workload-identity-pools create-cred-config a fin de generar un archivo de configuración JSON:

gcloud iam workload-identity-pools create-cred-config \
    projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id \
    --service-account=service-account-email \
    --output-file=filepath \
    --aws

Reemplaza los siguientes valores:

  • project-number: El ID numérico del proyecto.
  • pool-id: El ID del grupo de identidades de la carga de trabajo.
  • provider-id: El ID del proveedor de grupos de identidades de la carga de trabajo.
  • service-account-email: La dirección de correo electrónico de la cuenta de servicio que representar.
  • filepath: La ruta de acceso del archivo de configuración.

Después de generar el archivo de configuración, establece la variable de entorno GOOGLE_APPLICATION_CREDENTIALS en la ruta del archivo de configuración. Esta variable de entorno le indica a la biblioteca cliente que use las Credenciales predeterminadas de la aplicación para autenticarse. Para obtener más información, consulta Encuentra credenciales de forma automática.

Intercambia credenciales manualmente

Una vez que una función o un usuario de AWS tiene la capacidad de actuar en nombre de una cuenta de servicio, puedes intercambiar sus credenciales de AWS por las credenciales de Google de forma manual.

Como parte del proceso de intercambio, pasas un token GetCallerIdentity al Servicio de tokens de seguridad. El token GetCallerIdentity contiene la información que normalmente incluirías en una solicitud al método GetCallerIdentity() de AWS, además de la firma que generarías normalmente para la solicitud. Google Cloud usa el token GetCallerIdentity para verificar la identidad de la principal de AWS y confirmar que la principal tiene permiso para actuar como una cuenta de servicio.

Para intercambiar credenciales, haz lo siguiente:

  1. Obtén credenciales de AWS temporales.

  2. Crea un token GetCallerIdentity. El token contiene la información para una solicitud al método GetCallerIdentity() de AWS, al igual que la firma de AWS para la información de la solicitud. Usar la versión 4 de la firma.

    La solicitud contiene los siguientes campos:

    • url: La URL del extremo de AWS STS para GetCallerIdentity(), con el cuerpo de una solicitud GetCallerIdentity() estándar anexada como parámetros de consulta. Por ejemplo, https://sts.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15 También se admiten extremos regionales.
    • method: Es el método de solicitud HTTP: POST.
    • headers: Son los encabezados de la solicitud HTTP, que deben incluir lo siguiente:

      • Authorization: La firma de la solicitud
      • host: El nombre de host del campo url; por ejemplo, sts.amazonaws.com
      • x-amz-date: La hora a la que enviarás la solicitud, con el formato de una string simple ISO 8601. Por lo general, este valor se establece en la hora actual y se usa para evitar ataques de repetición.
      • x-goog-cloud-target-resource: El nombre completo del recurso del proveedor de identidad. Por ejemplo:
      //iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id
      
      • x-amz-security-token: Solo se requiere si usas credenciales de seguridad temporales. El token de sesión de AWS que se debe incluir.

    Un token GetCallerIdentity es similar al que se muestra a continuación:

    {
      "url": "https://sts.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
      "method": "POST",
      "headers": [
        {
          "key": "Authorization",
          "value" : "AWS4-HMAC-SHA256 Credential=AKIASOZTBDV4D7ABCDEDF/20200228/us-east-1/sts/aws4_request, SignedHeaders=host;x-amz-date,Signature=abcedefdfedfd"
        },
        {
          "key": "host",
          "value": "sts.amazonaws.com"
        },
        {
          "key": "x-amz-date",
          "value": "20200228T225005Z"
        },
        {
          "key": "x-goog-cloud-target-resource",
          "value": "//iam.googleapis.com/projects/12345678/locations/global/workloadIdentityPools/my-pool/providers/my-aws-provider"
        },
        {
          "key": "x-amz-security-token",
          "value": "GizFWJTqYX...xJ55YoJ8E9HNU="
        }
      ]
    }
    
  3. A fin de intercambiar la credencial de AWS por un token de acceso federado, pasa el token GetCallerIdentity al método token() del servicio de tokens de seguridad:

    REST

    El método token intercambia un token de terceros por un token de Google.

    Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

    • project-number: Es el número de tu proyecto de Google Cloud.
    • pool-id: Es el ID del grupo de Workload Identity que creaste con anterioridad en este instructivo.
    • provider-id: Es el ID del proveedor de identidad de AWS que configuraste con anterioridad en este instructivo.
    • aws-request: El token GetCallerIdentity, con formato JSON con escape de URL.

    Método HTTP y URL:

    POST https://sts.googleapis.com/v1beta/token

    Cuerpo JSON de la solicitud:

    {
      "audience": "//iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id",
      "grantType": "urn:ietf:params:oauth:grant-type:token-exchange",
      "requestedTokenType": "urn:ietf:params:oauth:token-type:access_token",
      "scope": "https://www.googleapis.com/auth/cloud-platform",
      "subjectTokenType": "urn:ietf:params:aws:token-type:aws4_request",
      "subjectToken": "aws-request"
    }
    

    Para enviar tu solicitud, expande una de estas opciones:

     

    El método muestra un token federado.

  4. Para intercambiar el token federado por un token de acceso a una cuenta de servicio, llama al método generateAccessToken(). Una cantidad limitada de API de Google Cloud admite tokens federados. Sin embargo, todas las API de Google Cloud admiten tokens de acceso a la cuenta de servicio.

    REST

    Mediante el método serviceAccounts.generateAccessToken de la API de credenciales de la cuenta de servicio, se genera un token de acceso de OAuth 2.0 para una cuenta de servicio.

    Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

    • project-id: El ID del proyecto de Google Cloud.
    • sa-id: El ID de la cuenta de servicio. Puede ser la dirección de correo electrónico de la cuenta de servicio con el formato sa-name@project-id.iam.gserviceaccount.com o el ID numérico único de la cuenta de servicio.
    • token: Es el token de acceso federado.

    Método HTTP y URL:

    POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/sa-name@project-id.iam.gserviceaccount.com:generateAccessToken

    Cuerpo JSON de la solicitud:

    {
      "scope": [
        "https://www.googleapis.com/auth/cloud-platform"
      ]
    }
    

    Para enviar tu solicitud, expande una de estas opciones:

    Si la solicitud generateAccessToken tiene éxito, el cuerpo de la respuesta contendrá un token de acceso de OAuth 2.0 y un tiempo de caducidad. El accessToken se puede usar para autenticar una solicitud en nombre de la cuenta de servicio hasta que se haya alcanzado el expireTime.

    {
      "accessToken": "eyJ0eXAi...NiJ9",
      "expireTime": "2020-04-07T15:01:23.045123456Z"
    }
    

Cuando tienes un token de acceso para una cuenta de servicio, puedes usar el token a fin de llamar a las API de Google Cloud si incluyes el token en el encabezado Authorization de tus solicitudes:

Authorization: Bearer access-token

La solicitud está autorizada como la cuenta de servicio.

Próximos pasos