Crea credenciales para cuentas de servicio de corta duración

En esta página, se explica cómo crear credenciales de corta duración para que las cuentas de servicio simulen sus identidades.

Las cuentas de servicio pueden usar credenciales de corta duración para autenticar llamadas a las API de Google Cloud y a otras API que no sean de Google. Las credenciales de corta duración tienen una vida útil limitada, con una duración de unas pocas horas o menos. Las credenciales de cuenta de servicio de corta duración son útiles en situaciones en las que necesitas otorgar acceso limitado a recursos para cuentas de servicio de confianza. También crean menos riesgo que las credenciales de larga duración, como las claves de cuenta de servicio.

Los tipos de credenciales admitidos incluyen tokens de acceso de OAuth 2.0, tokens de ID de OpenID Connect, tokens web JSON (JWT) autofirmados y objetos binarios autofirmados (BLOB). Los tipos de credenciales que más se usan son los tokens de acceso de OAuth 2.0 y los tokens de ID de OpenID Connect (OIDC). A continuación, se muestran algunas situaciones de ejemplo:

  • Token de acceso de OAuth 2.0: Este es útil para autenticar la identidad de una cuenta de servicio en las API de Google Cloud. Considera el siguiente caso práctico de ejemplo: a fin de obtener permisos elevados en un proyecto, un administrador de servicios puede simular la identidad de una cuenta de servicio para llamar a API de Google Cloud mediante la creación de un token de acceso de OAuth 2.0 que pertenezca a esa cuenta de servicio. El token tiene una vida útil corta, por lo que los permisos elevados son temporales. Esto es útil en especial cuando hay una emergencia en un entorno de producción y un administrador de servicios necesita una autorización elevada de corta duración para realizar la depuración.

  • Token de ID de OIDC: Este es útil para autenticar la identidad de una cuenta de servicio de los servicios que acepten OpenID Connect. Considera el siguiente caso práctico de ejemplo: si se crea un token de ID de OIDC que pertenece a una cuenta de servicio, un servicio que se ejecuta en Google Cloud se puede autenticar en otro servicio implementado en un proveedor de servicios en la nube de terceros, como un trabajo de canalización de datos. Si el servicio de destino se configura con OIDC, la autenticación tendrá éxito.

Antes de comenzar

Crea una cuenta de servicio

Para comenzar, crea una cuenta de servicio nueva.

Otorga los permisos necesarios

Hay dos flujos diferentes que permiten al emisor crear credenciales de corta duración para una cuenta de servicio. Cada flujo requiere los permisos adecuados:

  • Solicitud directa: El emisor se autentica como una Cuenta de Google o una cuenta de servicio y realiza una solicitud directa para crear credenciales de corta duración. En este flujo, participan dos identidades: el emisor y la cuenta de servicio para la que se creó la credencial.
  • Solicitud delegada: Al igual que en el flujo de solicitud directa, el emisor se autentica como una Cuenta de Google o una cuenta de servicio, pero la solicitud se delega a una o más cuentas de servicio en una cadena de delegación. En este flujo, varias cuentas de servicio actúan como intermediarias entre el emisor original y la cuenta de servicio para la que se creó la credencial. Cada cuenta de servicio en la cadena de delegación debe tener los permisos necesarios para pasar la solicitud.

    Este flujo es útil para situaciones en las que un proyecto contiene niveles de cuentas de servicio con privilegios limitados, cada una configurada para realizar una función específica o limitada en ciertos recursos. Por ejemplo, a una cuenta de servicio solo se le otorgan permisos para los recursos de Cloud Storage, a otra solo se le otorgan permisos para los recursos de Compute Engine, etcétera. Para delegar con éxito una solicitud entre cuentas de servicio, cada una debe estar incluida en la cadena de delegación.

Permisos de solicitud directa

Como se describe en Otorga permisos necesarios en esta página, una solicitud directa involucra solo dos identidades: el emisor y la cuenta de servicio para la que se crea la credencial. En este flujo, considera las siguientes identidades:

  • Cuenta de servicio 1 (sa-1): El emisor de una solicitud para las credenciales de corta duración
  • Cuenta de servicio 2 (sa-2): La cuenta con privilegios limitados para la que se crea la credencial

A fin de otorgar permisos a sa-1 para crear credenciales de corta duración, otórgale la función de creador de tokens de cuenta de servicio (roles/iam.serviceAccountTokenCreator) en sa-2. Este es un ejemplo de una cuenta de servicio a la que se trata como un recurso en lugar de como una identidad: sa-1 debe tener el permiso para emitir credenciales para sa-2. A fin de obtener más información sobre cómo tratar las cuentas de servicio como una identidad o un recurso, consulta Permisos de cuenta de servicio.

En los siguientes pasos, se usa la API de REST para otorgar los permisos necesarios. Sin embargo, también puedes usar Cloud Console o la herramienta de línea de comandos de gcloud.

API

Primero, lee la política de Cloud IAM para sa-2:

Consulta la referencia de serviceAccounts.getIamPolicy() para obtener más información.

Solicitud:

POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/sa-2@project-id.iam.gserviceaccount.com:getIamPolicy

Respuesta:

{
  "etag": "BwUqLaVeua8=",
  "bindings": [
    {
      "role": "roles/iam.serviceAccountUser",
      "members": [
          "user:my-user@example.com"
      ]
    }
  ]
}

Si no asignaste una función a la cuenta de servicio, la respuesta solo contendrá un valor de ETag. Incluye ese valor de ETag en el siguiente paso.

A continuación, modifica la política para otorgar a sa-1 la función de creador de tokens de cuenta de servicio (roles/iam.serviceAccountTokenCreator):

{
  "policy": {
    "etag": "BwUqLaVeua8=",
    "bindings": [
      {
        "role": "roles/iam.serviceAccountUser",
        "members": [
          "user:my-user@example.com"
        ]
      },
      {
        "role": "roles/iam.serviceAccountTokenCreator",
        "members": [
          "serviceAccount:sa-1@project-id.iam.gserviceaccount.com"
        ]
      }
    ]
  }
}

Por último, escribe la política actualizada:

Crea una solicitud serviceAccounts.setIamPolicy() con la política actualizada como el cuerpo de la solicitud:

POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/sa-2@project-id.iam.gserviceaccount.com:setIamPolicy

La respuesta contiene la política actualizada:

{
  "etag": "BwUqMqbViM8=",
  "bindings": [
    {
      "role": "roles/iam.serviceAccountUser",
      "members": [
        "user:my-user@example.com"
      ]
    },
    {
      "role": "roles/iam.serviceAccountTokenCreator",
      "members": [
        "serviceAccount:sa-1@project-id.iam.gserviceaccount.com"
      ]
    }
  ]
}

Permisos de solicitud delegada

Como se describe en Otorga permisos necesarios en esta página, una solicitud delegada involucra más de dos identidades: el emisor, una o más cuentas de servicio en una cadena de delegación y, por último, la cuenta de servicio. En este flujo, considera las siguientes identidades:

  • Cuenta de servicio 1 (sa-1): El emisor de una solicitud para las credenciales de corta duración
  • Cuenta de servicio 2 (sa-2): Una cuenta de servicio intermediaria que delegará la solicitud inicial a sa-3
  • Cuenta de servicio 3 (sa-3): La cuenta con privilegios limitados para la que se crea la credencial

Para permitir la delegación, cada cuenta debe otorgar la función de creador de tokens de cuentas de servicio (roles/iam.serviceAccountTokenCreator) a la cuenta anterior en la cadena.

En este ejemplo en particular, sa-1 debe tener la función de creador de tokens de cuenta de servicio (roles/iam.serviceAccountTokenCreator) en sa-2. Este es un ejemplo de una cuenta de servicio a la que se trata como un recurso en lugar de como una identidad: sa-1 debe tener el permiso para delegar acceso para sa-2. A fin de obtener más información sobre cómo tratar las cuentas de servicio como una identidad o un recurso, consulta Permisos de cuenta de servicio.

En este flujo de ejemplo, hay una sola cuenta de servicio intermediaria. Para delegar el acceso a través de más de una cuenta de servicio, también debes asignar esta función a cualquier otra cuenta de servicio en la cadena.

A continuación, sa-2 también debe tener la función de creador de tokens de cuenta de servicio (roles/iam.serviceAccountTokenCreator) en sa-3. Esto permite que sa-2 cree credenciales de corta duración para sa-3.

En los siguientes pasos, se usa la API de REST para otorgar los permisos necesarios. Sin embargo, también puedes usar Cloud Console o la herramienta de línea de comandos de gcloud.

API

Primero, obtén la política de Cloud IAM para sa-2 (la cuenta de servicio intermediaria):

Consulta la referencia de serviceAccounts.getIamPolicy() para obtener más información.

Solicitud:

POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/sa-2@project-id.iam.gserviceaccount.com:getIamPolicy

Respuesta:

{
  "etag": "BwUqLaVeua8=",
  "bindings": [
    {
      "role": "roles/iam.serviceAccountUser",
      "members": [
          "user:my-user@example.com"
      ]
    }
  ]
}

Si no asignaste una función a la cuenta de servicio, la respuesta solo contendrá un valor de ETag. Incluye ese valor de ETag en el siguiente paso.

A continuación, modifica la política para otorgar a sa-1 la función de creador de tokens de cuenta de servicio (roles/iam.serviceAccountTokenCreator):

{
  "policy": {
    "etag": "BwUqLaVeua8=",
    "bindings": [
      {
        "role": "roles/iam.serviceAccountUser",
        "members": [
          "user:my-user@example.com"
        ]
      },
      {
        "role": "roles/iam.serviceAccountTokenCreator",
        "members": [
          "serviceAccount:sa-1@project-id.iam.gserviceaccount.com"
        ]
      }
    ]
  }
}

Luego, escribe la política actualizada para sa-2:

Con la política actualizada, ejecuta una solicitud serviceAccounts.setIamPolicy():

POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/sa-2@project-id.iam.gserviceaccount.com:setIamPolicy

La respuesta contiene la política actualizada:

{
  "etag": "BwUqMqbViM8=",
  "bindings": [
    {
      "role": "roles/iam.serviceAccountUser",
      "members": [
        "user:my-user@example.com"
      ]
    },
    {
      "role": "roles/iam.serviceAccountTokenCreator",
      "members": [
        "serviceAccount:sa-1@project-id.iam.gserviceaccount.com"
      ]
    }
  ]
}

Ahora, obtén la política de Cloud IAM para sa-3 (la cuenta de servicio para la que se crea la credencial):

Solicitud:

POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/sa-3@project-id.iam.gserviceaccount.com:getIamPolicy

Respuesta:

{
  "etag": "BwUqLaVeua8=",
  "bindings": [
    {
      "role": "roles/iam.serviceAccountUser",
      "members": [
        "user:my-user@example.com"
      ]
    }
  ]
}

Si no asignaste una función a la cuenta de servicio, la respuesta solo contendrá un valor de ETag. Incluye ese valor de ETag en el siguiente paso.

A continuación, modifica la política a fin de otorgar a sa-2 la función roles/iam.serviceAccountTokenCreator:

{
  "policy": {
    "etag": "BwUqLaVeua8=",
    "bindings": [
      {
        "role": "roles/iam.serviceAccountUser",
        "members": [
          "user:my-user@example.com"
        ]
      },
      {
        "role": "roles/iam.serviceAccountTokenCreator",
        "members": [
          "serviceAccount:sa-2@project-id.iam.gserviceaccount.com"
        ]
      }
    ]
  }
}

Por último, escribe la política actualizada:

Con la política actualizada, ejecuta una solicitud serviceAccounts.setIamPolicy():

POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/sa-3@project-id.iam.gserviceaccount.com:setIamPolicy

La respuesta contiene la política actualizada:

{
  "etag": "BwUqMqbViM8=",
  "bindings": [
    {
      "role": "roles/iam.serviceAccountUser",
      "members": [
        "user:my-user@example.com"
      ]
    },
    {
      "role": "roles/iam.serviceAccountTokenCreator",
      "members": [
        "serviceAccount:sa-2@project-id.iam.gserviceaccount.com"
      ]
    }
  ]
}

Solicita credenciales de corta duración

Después de otorgar los permisos adecuados para cada identidad, puedes solicitar credenciales de corta duración que pertenezcan a la cuenta de servicio deseada. Se admiten los siguientes tipos de credenciales:

A fin de comprender cómo especificar una cadena de delegación para estas solicitudes, consulta la sección Especifica una cadena de delegación en esta página.

Genera un token de acceso de OAuth 2.0

Los tokens de acceso de OAuth 2.0 son válidos por 1 hora (3,600 segundos). Si deseas generar un token de acceso de OAuth 2.0 para una cuenta de servicio, haz lo siguiente:

API

Ejecuta una solicitud generateAccessToken, en la que sa-4@project-id.iam.gserviceaccount.com sea el nombre de la cuenta de servicio para la que se creó el token.

La solicitud debe autenticarse mediante la inclusión de un token de acceso en el encabezado Authorization de la solicitud. Si quieres obtener más información sobre cómo obtener un token de acceso a fin de llamar a las API de Google, consulta los temas de la Descripción general de OAuth 2.0 y de OAuth 2.0 para cuentas de servicio.

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

Especifica los siguientes campos en el cuerpo de la solicitud:

{
  "delegates": [],
  "scope": [
    "https://www.googleapis.com/auth/cloud-platform"
  ],
  "lifetime": "300s"
}

Cada uno de estos campos y sus valores de ejemplo se describen a continuación:

  • delegates[]: Si usas un flujo de solicitud delegada, consulta la sección Especifica una cadena de delegación en esta página. Si usas un flujo de solicitud directa sin delegación, omite el campo delegates[] en el cuerpo de la solicitud.
  • scope: El permiso de OAuth 2.0 para la solicitud. Los siguientes permisos son válidos cuando se llama a la API de generateAccessToken:

    • https://www.googleapis.com/auth/iam
    • https://www.googleapis.com/auth/cloud-platform

    Por ejemplo:

    {
      "scope": [
        "https://www.googleapis.com/auth/cloud-platform"
      ]
    }
    
  • lifetime: La duración del token de acceso en segundos, luego de la cual el token caduca. La vida útil máxima del token es de 1 hora (3,600 segundos).

    Por ejemplo, para establecer la duración del token en 5 minutos, haz lo siguiente:

    {
      "lifetime": "300s"
    }
    

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:

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

El accessToken se puede usar para autenticar una solicitud en nombre de la cuenta de servicio hasta que se haya alcanzado el expireTime.

Genera tokens de ID de OpenID Connect

Los tokens de ID de OpenID Connect son válidos por 1 hora (3,600 segundos). Para generar un token de ID en nombre de una cuenta de servicio, haz lo siguiente:

API

Ejecuta una solicitud generateIdToken, en la que sa-4@project-id.iam.gserviceaccount.com sea el nombre de la cuenta de servicio para la que se creó el token.

La solicitud debe autenticarse mediante la inclusión de un token de acceso en el encabezado Authorization de la solicitud. Si quieres obtener más información sobre cómo obtener un token de acceso a fin de llamar a las API de Google, consulta los temas de la Descripción general de OAuth 2.0 y de OAuth 2.0 para cuentas de servicio.

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

Especifica los siguientes campos en el cuerpo de la solicitud:

{
  "delegates": [],
  "audience": "sa-4@project-id.iam.gserviceaccount.com",
  "includeEmail": "true"
}

Cada uno de estos campos y sus valores de ejemplo se describen a continuación:

  • delegates[]: Si usas un flujo de solicitud delegada, consulta la sección Especifica una cadena de delegación en esta página. Si usas un flujo de solicitud directa sin delegación, omite el campo delegates[] en el cuerpo de la solicitud.
  • audience: La URL de un servicio o la dirección de correo electrónico de la cuenta de servicio para la que se creó la credencial. Por ejemplo:

    {
      "audience": "sa-4@project-id.iam.gserviceaccount.com"
    }
    
  • includeEmail: Si se establece en true, la reclamación email en el token de ID incluirá el correo electrónico de la cuenta de servicio. Además, una reclamación email_verified se establecerá en true y se incluirá en el token de ID. Por ejemplo:

    {
      "includeEmail": true
    }
    

Si la solicitud generateIdToken tuvo éxito, el cuerpo de la respuesta contendrá un token de ID válido por 1 hora:

{
  "token": "eyJ0eXAi...NiJ9"
}

El token se puede usar para autenticar una solicitud en nombre de la cuenta de servicio.

Crea un token web JSON (JWT) autofirmado

Los JWT autofirmados son útiles en varias situaciones, como las que se mencionan a continuación:

  • Autenticación de una llamada a una API de Google como se describe en la Guía de autenticación de Google
  • Comunicación segura entre servicios de Google Cloud o servicios que no sean de Google, como las aplicaciones de App Engine. En esta situación, una aplicación puede firmar un token que otra aplicación puede verificar con fines de autenticación.
  • Tratar una cuenta de servicio como un proveedor de identidad mediante la firma de un JWT que contiene reclamaciones arbitrarias sobre un usuario, una cuenta o un dispositivo.

Para generar un token web JSON (JWT) autofirmado en nombre de una cuenta de servicio, haz lo siguiente:

API

Ejecuta una solicitud signJwt, en la que sa-4@project-id.iam.gserviceaccount.com sea el nombre de la cuenta de servicio para la que se creó el JWT.

La solicitud debe autenticarse mediante la inclusión de un token de acceso en el encabezado Authorization de la solicitud. Si quieres obtener más información sobre cómo obtener un token de acceso a fin de llamar a las API de Google, consulta los temas de la Descripción general de OAuth 2.0 y de OAuth 2.0 para cuentas de servicio.

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

Especifica los siguientes campos en el cuerpo de la solicitud:

{
  "delegates": [],
  "payload": "{ \"iss\": \"sa-4@project-id.iam.gserviceaccount.com\", \"sub\": \"sa-4@project-id.iam.gserviceaccount.com\", \"aud\": \"https://firestore.googleapis.com/google.firestore.v1.Firestore\", \"iat\": 1529350000, \"exp\": 1529353600 }"
}

Cada uno de estos campos y sus valores de ejemplo se describen a continuación:

  • delegates[]: Si usas un flujo de solicitud delegada, consulta la sección Especifica una cadena de delegación en esta página. Si usas un flujo de solicitud directa sin delegación, omite el campo delegates[] en el cuerpo de la solicitud.
  • payload: La carga útil de JWT que se firmará, que es un objeto JSON que contiene un conjunto de reclamaciones JWT. Incluye las reclamaciones necesarias para tu caso práctico deseado a fin de cumplir con los requisitos de validación del servicio posterior. Si llamas a una API de Google, consulta la Guía de autenticación de Google para conocer los requisitos de reclamación.

    La reclamación exp (tiempo de caducidad) debe establecerse en no más de 12 horas. De lo contrario, no se validará. Si el JWT se usa para llamar a una API de Google, la reclamación exp debe establecerse en no más de 1 hora.

    El siguiente conjunto de reclamaciones de ejemplo contiene reclamaciones para llamar a una API de Google con una vida útil máxima de 1 hora (3,600 segundos):

    {
      "payload": "{ \"iss\": \"sa-4@project-id.iam.gserviceaccount.com\", \"sub\": \"sa-4@project-id.iam.gserviceaccount.com\", \"aud\": \"https://firestore.googleapis.com/google.firestore.v1.Firestore\", \"iat\": 1529350000, \"exp\": 1529353600 }"
    }
    

Si la solicitud signJwt se realizó con éxito, el cuerpo de la respuesta contendrá un JWT firmado y el ID de la clave de firma que se usó para firmarlo. El token es válido hasta que venza el tiempo de caducidad especificado en la solicitud:

{
  "keyId": "42ba1e...fc0a",
  "signedJwt": "eyJ0eXAi...NiJ9"
}

El valor signedJwt se puede usar como un token del portador para autenticar directamente una solicitud en nombre de la cuenta de servicio.

Crea un BLOB autofirmado

Los BLOB autofirmados son útiles en situaciones en las que necesitas transmitir de forma segura datos binarios arbitrarios, por lo general, con fines de autenticación. Por ejemplo, si deseas usar un protocolo o tipo de token personalizado (no JWT), puedes incluir esos datos en un BLOB firmado para que los use un servicio posterior.

Para generar un BLOB autofirmado en nombre de una cuenta de servicio, haz lo siguiente:

API

Ejecuta una solicitud signBlob, en la que sa-4@project-id.iam.gserviceaccount.com sea el nombre de la cuenta de servicio para la que se creó el BLOB.

La solicitud debe autenticarse mediante la inclusión de un token de acceso en el encabezado Authorization de la solicitud. Si quieres obtener más información sobre cómo obtener un token de acceso a fin de llamar a las API de Google, consulta los temas de la Descripción general de OAuth 2.0 y de OAuth 2.0 para cuentas de servicio.

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

Especifica los siguientes campos en el cuerpo de la solicitud:

{
  "delegates": [],
  "payload": "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu"
}

Cada uno de estos campos y sus valores de ejemplo se describen a continuación:

Si la solicitud signBlob se realizó con éxito, el cuerpo de la respuesta contendrá un BLOB firmado y el ID de la clave de firma que se usó para firmarlo. El token es válido hasta que venza el tiempo de caducidad especificado en la solicitud:

{
  "keyId": "42ba1e...fc0a",
  "signedBlob": "eyJ0eXAi...NiJ9"
}

Especifica una cadena de delegación

Cuando usas un flujo de solicitud delegada a fin de crear credenciales de cuenta de servicio de corta duración, el cuerpo de la solicitud para cada API debe especificar la cadena de delegación de cuentas de servicio en el orden correcto y en el siguiente formato:

projects/-/serviceAccounts/account-email-or-unique-id

Por ejemplo, en una cadena de delegación que fluye desde sa-1 (emisor) y pasa por sa-2 (delegada) y sa-3 (delegada) hasta llegar a sa-4, el campo delegates[] contendrá a sa-2 y sa-3 en el siguiente orden:

{
  "delegates": [
    "projects/-/serviceAccounts/sa-2@project-id.iam.gserviceaccount.com",
    "projects/-/serviceAccounts/sa-3@project-id.iam.gserviceaccount.com"
  ]
}

El emisor y la cuenta de servicio para la que se creó la credencial no se incluyen en la cadena de delegación.