Antes de que una aplicación envíe información sensible a una instancia de máquina virtual (VM), puede verificar la identidad de la instancia mediante tokens de identidad de instancia firmados por Google. Cada instancia tiene un JSON Web Token (JWT) único que incluye detalles sobre la instancia, así como la firma RS256 de Google. Tus aplicaciones pueden verificar la firma con los certificados públicos de OAuth2 de Google para confirmar la identidad de la instancia con la que han establecido una conexión.
Compute Engine genera tokens de instancia firmados solo cuando una instancia los solicita a los metadatos de instancia. Las instancias solo pueden acceder a su propio token único y no a los tokens de otras instancias.
Puede que quieras verificar las identidades de tus instancias en los siguientes casos:
- Cuando inicias una instancia por primera vez, es posible que tus aplicaciones tengan que asegurarse de que la instancia a la que se han conectado tiene una identidad válida antes de transmitir información sensible a la instancia.
- Cuando tus políticas requieren que almacenes las credenciales fuera del entorno de Compute Engine y envíes esas credenciales a tus instancias con regularidad para que las usen temporalmente. Tus aplicaciones pueden confirmar las identidades de las instancias cada vez que necesiten transmitir credenciales.
Los métodos de autenticación de instancias de Google ofrecen las siguientes ventajas:
- Compute Engine crea un token único cada vez que una instancia lo solicita, y cada token caduca en una hora. Puede configurar sus aplicaciones para que acepten el token de identidad de una instancia solo una vez, lo que reduce el riesgo de que un sistema no autorizado pueda reutilizar el token.
- Los tokens de metadatos firmados usan el estándar abierto del sector RFC 7519 y la capa de identidad OpenID Connect 1.0, por lo que las herramientas y bibliotecas actuales funcionarán a la perfección con los tokens de identidad.
Antes de empezar
- Consulta cómo obtener valores de metadatos de instancias.
- Conocer los conceptos básicos de los JSON Web Tokens para saber cómo usarlos en tus aplicaciones.
- Consulta cómo crear y habilitar cuentas de servicio en tus instancias. Tus instancias deben tener una cuenta de servicio asociada para poder recuperar sus tokens de identidad. La cuenta de servicio no requiere ningún permiso de gestión de identidades y accesos para obtener estos tokens de identidad.
-
Si aún no lo has hecho, configura la autenticación.
La autenticación verifica tu identidad para acceder a Google Cloud servicios y APIs. Para ejecutar código o ejemplos desde un entorno de desarrollo local, puedes autenticarte en Compute Engine seleccionando una de las siguientes opciones:
Para usar las Python muestras de esta página en un entorno de desarrollo local, instala e inicializa la CLI de gcloud y, a continuación, configura las credenciales predeterminadas de la aplicación con tus credenciales de usuario.
Instala Google Cloud CLI.
Si utilizas un proveedor de identidades (IdP) externo, primero debes iniciar sesión en la CLI de gcloud con tu identidad federada.
If you're using a local shell, then create local authentication credentials for your user account:
gcloud auth application-default login
You don't need to do this if you're using Cloud Shell.
If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.
Para obtener más información, consulta Set up authentication for a local development environment.
Verificar la identidad de una instancia
En algunos casos, tus aplicaciones deben verificar la identidad de una instancia que se ejecuta en Compute Engine antes de transmitir datos sensibles a esa instancia. En un ejemplo típico, hay un sistema que se ejecuta fuera de Compute Engine llamado "Host1" y una instancia de Compute Engine llamada "VM1". VM1 puede conectarse a Host1 y validar la identidad de esa instancia mediante el siguiente proceso:
VM1 establece una conexión segura con Host1 mediante un protocolo de conexión segura de tu elección, como HTTPS.
La VM1 solicita su token de identidad único al servidor de metadatos y especifica la audiencia del token. En este ejemplo, el valor de la audiencia es el URI de Host1. La solicitud al servidor de metadatos incluye el URI de la audiencia para que Host1 pueda comprobar el valor más adelante durante el paso de verificación del token.
Google genera un nuevo token de identidad de instancia único en formato JWT y se lo proporciona a VM1. La carga útil del token incluye varios detalles sobre la instancia y también el URI de audiencia. Consulta la sección Contenido del token para ver una descripción completa del contenido del token.
La VM1 envía el token de identidad al Host1 a través de la conexión segura.
Host1 decodifica el token de identidad para obtener los valores del encabezado y de la carga útil del token.
El host 1 verifica que el token esté firmado por Google comprobando el valor del público y verificando la firma del certificado con el certificado público de Google.
Si el token es válido, Host1 continúa con la transmisión y cierra la conexión cuando termina. Host1 y cualquier otro sistema deben solicitar un nuevo token para las conexiones posteriores a VM1.
Obtener el token de identidad de la instancia
Cuando tu instancia de máquina virtual recibe una solicitud para proporcionar su token de identidad, la instancia solicita ese token al servidor de metadatos mediante el proceso normal para obtener metadatos de la instancia. Por ejemplo, puedes usar uno de los siguientes métodos:
cURL
Crea una solicitud curl
e incluye un valor en el parámetro audience
.
También puede incluir el parámetro format
para especificar si quiere incluir o no los detalles del proyecto y de la instancia en la carga útil. Si usa el formato full
, puede incluir el parámetro licenses
para especificar si quiere incluir códigos de licencia en la carga útil.
curl -H "Metadata-Flavor: Google" \ 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=AUDIENCE&format=FORMAT&licenses=LICENSES'
Haz los cambios siguientes:
AUDIENCE
: el URI único acordado tanto por la instancia como por el sistema que verifica la identidad de la instancia. Por ejemplo, la audiencia podría ser una URL para la conexión entre los dos sistemas.FORMAT
: parámetro opcional que especifica si los detalles del proyecto y de la instancia se incluyen en la carga útil. Especifiquefull
para incluir esta información en la carga útil ostandard
para omitirla de la carga útil. El valor predeterminado esstandard
. Para obtener más información, consulta Formato de token de identidad.LICENSES
: parámetro opcional que especifica si se incluyen en la carga útil los códigos de licencia de las imágenes asociadas a esta instancia. EspecificaTRUE
para incluir esta información oFALSE
para omitirla de la carga útil. El valor predeterminado esFALSE
. No tiene ningún efecto a menos queformat
seafull
El servidor de metadatos responde a esta solicitud con un JSON Web Token firmado con el algoritmo RS256. El token incluye una firma de Google e información adicional en la carga útil. Puedes enviar este token a otros sistemas y aplicaciones para que puedan verificar el token y confirmar la identidad de tu instancia.
Python
Puedes enviar una solicitud sencilla desde tu instancia al servidor de metadatos mediante métodos de la biblioteca requests
de Python. En el siguiente ejemplo se solicita y, a continuación, se imprime un token de identidad de instancia. El token es único
para la instancia que hace esta solicitud.
El servidor de metadatos responde a esta solicitud con un JSON Web Token firmado con el algoritmo RS256. El token incluye una firma de Google e información adicional en la carga útil. Puedes enviar este token a otros sistemas y aplicaciones para que puedan verificar el token y confirmar la identidad de tu instancia.
Verificar el token
Una vez que tu aplicación recibe un token de identidad de instancia de una instancia de Compute Engine, puede verificar el token mediante el siguiente proceso.
Recibe el token de la instancia de máquina virtual, decodifícalo con un decodificador de JWT RS256 y lee el contenido del encabezado para obtener el valor de
kid
.Verifica que el token esté firmado comprobándolo con el certificado público de Google. Cada certificado público tiene un valor
kid
que corresponde al valorkid
del encabezado del token.Si el token es válido, compara el contenido de la carga útil con los valores esperados. Si la carga útil del token incluye detalles sobre la instancia y el proyecto, tu aplicación puede comprobar los valores
instance_id
,project_id
yzone
. Estos valores son una tupla única a nivel global que confirma que tu aplicación se comunica con la instancia correcta del proyecto deseado.
Puedes decodificar y verificar el token con la herramienta que quieras, pero un método habitual es usar las bibliotecas del lenguaje que prefieras. Por ejemplo, puedes usar el método verify_token
de la biblioteca de Google OAuth 2.0 para Python. El método verify_token
asocia el valor kid
con el certificado adecuado, verifica la firma, comprueba la reclamación de audiencia y devuelve el contenido de la carga útil del token.
Una vez que tu aplicación verifique el token y su contenido, podrá comunicarse con esa instancia a través de una conexión segura y, después, cerrar la conexión cuando haya terminado. Para las conexiones posteriores, solicita un nuevo token a la instancia y vuelve a verificar su identidad.
Contenido del token
El token de identidad de instancia contiene tres partes principales:
Header
El encabezado incluye el valor kid
para identificar qué certificados OAuth2 públicos debes usar para verificar la firma. El encabezado también incluye el valor alg
para confirmar que la firma se ha generado con el
algoritmo RS256.
{
"alg": "RS256",
"kid": "511a3e85d2452aee960ed557e2666a8c5cedd8ae",
}
Carga útil
La carga útil contiene la reclamación de audiencia aud
. Si la instancia especificó format=full
al solicitar el token, la carga útil también incluye reclamaciones sobre la instancia de máquina virtual y su proyecto.
Al solicitar un token de formato completo, si se especifica licenses=TRUE
, también se incluirán las reclamaciones sobre las licencias asociadas a la instancia.
{
"iss": "[TOKEN_ISSUER]",
"iat": [ISSUED_TIME],
"exp": [EXPIRED_TIME],
"aud": "[AUDIENCE]",
"sub": "[SUBJECT]",
"azp": "[AUTHORIZED_PARTY]",
"google": {
"compute_engine": {
"project_id": "[PROJECT_ID]",
"project_number": [PROJECT_NUMBER],
"zone": "[ZONE]",
"instance_id": "[INSTANCE_ID]",
"instance_name": "[INSTANCE_NAME]",
"instance_creation_timestamp": [CREATION_TIMESTAMP],
"instance_confidentiality": [INSTANCE_CONFIDENTIALITY],
"license_id": [
"[LICENSE_1]",
...
"[LICENSE_N]"
]
}
}
}
Donde:
[TOKEN_ISSUER]
: una URL que identifica quién ha emitido el token. En el caso de Compute Engine, este valor eshttps://accounts.google.com
.[ISSUED_TIME]
: una marca de tiempo Unix que indica cuándo se emitió el token. Este valor se actualiza cada vez que la instancia solicita un token al servidor de metadatos.[EXPIRED_TIME]
: marca de tiempo Unix que indica cuándo caduca el token.[AUDIENCE]
: el URI único acordado tanto por la instancia como por el sistema que verifica la identidad de la instancia. Por ejemplo, la audiencia podría ser una URL para la conexión entre los dos sistemas.[SUBJECT]
: el asunto del token, que es el ID único de la cuenta de servicio que has asociado a tu instancia.[AUTHORIZED_PARTY]
: la parte a la que se emitió el token de ID, que es el ID único de la cuenta de servicio que has asociado a tu instancia.[PROJECT_ID]
: el ID del proyecto en el que has creado la instancia.[PROJECT_NUMBER]
: el número único del proyecto en el que has creado la instancia.[ZONE]
: la zona en la que se encuentra la instancia.[INSTANCE_ID]
: el ID único de la instancia a la que pertenece este token. Este ID es único en el proyecto y en la zona.[INSTANCE_NAME]
: el nombre de la instancia a la que pertenece este token. Si tu proyecto usa DNS zonal, este nombre se puede reutilizar en varias zonas, por lo que debes usar una combinación de los valoresproject_id
,zone
yinstance_id
para identificar un ID de instancia único. Los proyectos con DNS global habilitado tienen un nombre de instancia único en todo el proyecto.[CREATION_TIMESTAMP]
: marca de tiempo Unix que indica cuándo creaste la instancia.[INSTANCE_CONFIDENTIALITY]
:1
si la instancia es una VM confidencial.[LICENSE_1]
a[LICENSE_N]
: los códigos de licencia de las imágenes asociadas a esta instancia.
Su carga útil podría tener un aspecto similar al del siguiente ejemplo:
{
"iss": "https://accounts.google.com",
"iat": 1496953245,
"exp": 1496956845,
"aud": "https://www.example.com",
"sub": "107517467455664443765",
"azp": "107517467455664443765",
"google": {
"compute_engine": {
"project_id": "my-project",
"project_number": 739419398126,
"zone": "us-west1-a",
"instance_id": "152986662232938449",
"instance_name": "example",
"instance_creation_timestamp": 1496952205,
"instance_confidentiality": 1,
"license_id": [
"1000204"
]
}
}
}
Firma
Google genera la firma codificando en base64url el encabezado y la carga útil, y concatenando los dos valores. Puede comparar este valor con los certificados públicos de OAuth2 para verificar el token.
Siguientes pasos
- Consulta el Google Cloud framework de arquitectura correcta.
- Autenticar cargas de trabajo en otras cargas de trabajo mediante mTLS.