En este instructivo, se describe cómo usar la federación de identidades para cargas de trabajo para autenticar las cargas de trabajo que se ejecutan fuera de Google Cloud a fin de que puedan acceder a los microservicios que aloja Cloud Run. Este instructivo está dirigido a los administradores que desean integrar la federación de identidades para cargas de trabajo con su proveedor de identidad existente (IdP). La federación de identidades para cargas de trabajo te permite conectar cargas de trabajo externas a cargas de trabajo que se ejecutan en Google Cloud. Cloud Run te permite ejecutar microservicios sin estado alojados en contenedores.
En este instructivo, se proporcionan instrucciones para configurar Jenkins como la carga de trabajo externa, Keycloak como IdP, Cloud Run y la federación de identidades para cargas de trabajo. Cuando completas este instructivo, puedes ver cómo la federación de identidades para cargas de trabajo te permite autenticar la aplicación de Jenkins con Google Cloud mediante la autenticación de OpenID Connect.
Autenticación externa de cargas de trabajo mediante la federación de identidades para cargas de trabajo
La federación de identidades para cargas de trabajo te permite autenticar cargas de trabajo fuera de Google Cloud sin usar una clave de cuenta de servicio estática. Cualquier carga de trabajo externa que necesite consumir servicios en Google Cloud puede beneficiarse de esta función.
La federación de identidades para cargas de trabajo te permite usar tu IdP para autenticarte directamente con Google Cloud. Para autenticar, usa OpenID Connect. Cloud Run acepta tokens de OpenID Connect de tu IdP para la autenticación.
El proceso de autenticación cuando se usa la federación de identidades para cargas de trabajo es el siguiente:
- Tu biblioteca de autenticación (AUTHN) envía una solicitud de token web JSON (JWT) al IdP.
- Tu IdP firma los tokens web JSON (JWT). La biblioteca AUTHN lee estos datos de una variable.
- La biblioteca envía un comando POST al Servicio de tokens de seguridad que incluye el token firmado.
- El servicio de tokens de seguridad analiza el proveedor de grupos de Workload Identity que configuraste para compilar la relación de confianza y verifica la identidad en la credencial.
- El servicio de tokens de seguridad devuelve un token federado.
- La biblioteca envía el token a IAM.
- IAM intercambia el token por un token de OpenID Connect de una cuenta de servicio. Para obtener más información, consulta Genera tokens de ID de OpenID Connect.
- La biblioteca proporciona el token de OpenID Connect a Jenkins.
- Jenkins usa este token para autenticarse con Cloud Run.
En el siguiente diagrama, se muestra el flujo de autenticación:
Objetivos
- Configura Jenkins como la carga de trabajo externa.
- Configura Keycloak como el proveedor de identidad compatible con OpenID Connect.
- Conecta Jenkins con Keycloak.
- Instala las bibliotecas cliente de Cloud para obtener el token JWT de Keycloak en Google Cloud.
- Conecta Google Cloud a Keycloak y Jenkins
- Obtén el JWT del usuario autenticado de Keycloak.
Aunque en este instructivo se usa Keycloak, puedes usar cualquier proveedor de identidad que admita OpenID Connect, como GitLab, Okta o OneLogin.
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.
Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.
Antes de comenzar
-
In the Google Cloud console, go to the project selector page.
-
Select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
- Configura un microservicio en Cloud Run. Para obtener más información, consulta la Guía de inicio rápido: Implementa un contenedor en Cloud Run.
Configura Jenkins
Completa estas tareas en un entorno que no sea de Google Cloud, como tu entorno local o en otra nube.
Si ya tienes un proveedor de identidad que admite OpenID Connect y una carga de trabajo externa, puedes omitir este paso y pasar a Cómo instalar bibliotecas cliente de Cloud.
Para simular una carga de trabajo externa, puedes usar una VM con Jenkins instalado. Puedes ejecutar Jenkins como una imagen de Docker o instalarlo directamente en tu servidor. En los siguientes pasos, se demuestra cómo instalarlo directamente en el servidor.
- En la VM que elijas, abre una línea de comandos.
Instala Java:
$ sudo apt update $ sudo apt install openjdk-11-jre $ java -version
Instala Jenkins:
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo tee \ /usr/share/keyrings/jenkins-keyring.asc > /dev/null echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \ https://pkg.jenkins.io/debian-stable binary/ | sudo tee \ /etc/apt/sources.list.d/jenkins.list > /dev/null sudo apt-get update sudo apt-get install jenkins
Verifica que puedas acceder a tu servidor de Jenkins en el puerto 8080. Si usas una VM que se encuentra detrás de un firewall, asegúrate de que los puertos adecuados estén abiertos.
Obtén tu contraseña de administrador y configura Jenkins. Para obtener instrucciones, consulta el Asistente de configuración posterior a la instalación.
Completa las siguientes acciones para configurar SSL:
- Si tienes un proveedor de dominio, puedes usar su autoridad certificadora (CA) para solicitar un certificado firmado. Como alternativa, puedes obtener un certificado firmado gratis que dura 90 días desde zerossl.com.
Descarga el archivo ZIP del certificado y transfiérelo al servidor que ejecuta Jenkins:
scp -i CERTFILE.pem -r CERTFILE.zip VM_FQDN:/home/USERNAME
Reemplaza lo siguiente:
CERTFILE
por el nombre del archivo de certificado que incluye tu clave pública.VM_FQDN
con el FQDN de tu servidor fuera de Google Cloud.USERNAME
por tu nombre de usuario.
Cambia el nombre de los archivos y genera un archivo .pkcs12 que Jenkins pueda usar:
openssl rsa -in KEYFILE.com.key -out KEYFILE.com.key
Reemplaza
KEYFILE
por el nombre del archivo.
Actualiza el archivo
/etc/sysconfig/jenkins
:Abre el archivo en un editor de texto:
vi /etc/sysconfig/jenkins
Establece
JENKINS_PORT
en-1
.Establece
JENKINS_HTTPS_PORT
en8443
.En la parte inferior del archivo, agrega los siguientes argumentos:
JENKINS_ARGS="--httpsCertificate=/var/lib/jenkins/.ssl/CERTFILE.crt --httpsPrivateKeys=/var/lib/jenkins/.ssl/KEYFILE.pkcs1.key"
Reemplaza lo siguiente:
CERTFILE
por el nombre del archivo de certificado con el formato .crt.KEYFILE
por el nombre de archivo de la clave PKCS.
Reinicia el servidor de Jenkins.
Verifica que el puerto 8443 esté abierto en el firewall y accede a Jenkins en el puerto 8443.
Instala el complemento de Jenkins que necesitas para integrar Keycloak en Jenkins. Puedes elegir una de las siguientes opciones:
Para instalar el complemento, haz lo siguiente:
- En el panel de Jenkins, ve a Administrar Jenkins > Administrar complementos.
Selecciona Disponible y busca el complemento que prefieras. En la siguiente captura de pantalla, se muestra el Administrador de complementos con la pestaña Disponible.
Instala el complemento.
Configura Keycloak
En este instructivo, Keycloak administra los usuarios, grupos y roles. Keycloak usa dominios para administrar usuarios.
En la VM que se ejecuta fuera de Google Cloud, instala el servidor de Keycloak. Para este instructivo, recomendamos instalar Keycloak desde un contenedor de Docker.
Abre la Consola del administrador de Keycloak.
Ve a Configuración de dominios.
En la pestaña General, verifica que los campos estén configurados de la siguiente manera:
- Habilitada: ACTIVADO
- Acceso administrado por el usuario: DESACTIVADO
- Extremos: Configuración de extremos de OpenID y Metadatos del proveedor de identidad de SAML 2.0
La siguiente captura de pantalla muestra los campos que debes configurar.
Crea un cliente para que tengas una entidad que pueda solicitar a Keycloak que autentique a un usuario. A menudo, los clientes son aplicaciones y servicios que usan Keycloak para proporcionar una solución de inicio de sesión único (SSO).
- En la Consola del administrador de Keycloak, haz clic en Clientes > Crear.
Ingresa el siguiente comando:
- ID de cliente: jenkins
- Protocolo de cliente: openid-connect
- URL raíz: http://JENKINS_IP_ADDRESS:8080, donde JENKINS_IP_ADDRESS es la dirección IP de tu servidor de Jenkins.
La siguiente captura de pantalla muestra los campos que debes configurar.
Haz clic en Guardar.
En la pestaña Instalación, verifica que el formato del token sea JSON de OIDC de Keycloak. Haz una copia de este token, ya que lo necesitarás para completar la configuración de Jenkins.
Para crear un grupo, haz lo siguiente:
- En la Consola del administrador de Keycloak, haz clic en Grupos > Nuevo.
- Ingresa un nombre para el grupo y haz clic en Guardar.
- Crea otro grupo de prueba. Puedes asignar roles a tus grupos, pero este instructivo no las requiere.
Para crear un usuario de prueba y agregarlo al grupo, haz lo siguiente:
- En la Consola del administrador de Keycloak, haz clic en Administrar usuario > Agregar usuarios.
Completa la información del usuario y haz clic en Guardar.
En la siguiente captura de pantalla, se muestra un ejemplo de información de una cuenta de usuario.
Haz clic en la pestaña Credentials y verifica que Temporal esté configurado como Desactivado.
Restablece la contraseña.
Usarás esta cuenta más adelante en el JWT para la autenticación.
En la siguiente captura de pantalla, se muestra la pestaña Credentials con los campos que debes configurar.
Haz clic en la pestaña Grupos y selecciona uno de los grupos que creaste antes.
Haz clic en Unirse.
Repite este paso para crear más usuarios de prueba.
Configura Jenkins para la configuración de OpenID Connect
En esta sección, se describe cómo configurar el complemento OpenID Connect para Jenkins.
- En tu servidor de Jenkins, ve a Administrar Jenkins > Configurar seguridad global.
En Dominio de seguridad, selecciona Complemento de autenticación de Keycloak. Haz clic en Guardar.
Haz clic en Configurar sistema.
En la configuración de Keycloak global, copia el archivo JSON de instalación de Keycloak que creaste en Configura Keycloak. Si necesitas volver a obtener los datos JSON, completa lo siguiente:
En la Consola del administrador de Keycloak, ve a Clientes.
Haga clic en el nombre de tu cliente.
En la pestaña Instalación, haz clic en Opción de formato y selecciona JSON de OIDC de Keycloak.
El siguiente es un ejemplo de JSON de Keycloak:
{ "realm":"master" "auth-server-url":"AUTHSERVERURL" "ssl-required":"none" "resource":"jenkins" "public-client":true "confidential-port":0 }
AUTHSERVERURL es la URL de tu servidor de autenticación.
Para guardar la configuración de OIDC, haz clic en Guardar.
Jenkins ahora puede redireccionar a Keycloak para obtener información del usuario.
Instala bibliotecas cliente de Cloud
Para enviar un JWT de Keycloak a Google Cloud, debes instalar las bibliotecas cliente de Cloud en el servidor de Jenkins. En este instructivo, se usa Python para interactuar con Google Cloud mediante el SDK.
En el servidor de Jenkins, instala Python. En los siguientes pasos, se muestra cómo instalar python3:
sudo apt update sudo apt install software-properties-common sudo add-apt-repository ppa:deadsnakes/ppa sudo apt update sudo apt install python3.8
Instala pip3 para que puedas descargar e importar las bibliotecas cliente de Cloud:
pip3 –version sudo apt update sudo apt install python3-pip pip3 –version
Instala las bibliotecas cliente de Cloud para Python con pip3:
pip3 install –upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
Por ejemplo:
pip3 install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib Collecting google-api-python-client Downloading google_api_python_client-2.42.0-py2.py3-none-any.whl (8.3 MB) USERNAME | 8.3 MB 19.9 MB/s Collecting google-auth-httplib2 Downloading google_auth_httplib2-0.1.0-py2.py3-none-any.whl (9.3 MB) Collecting google-auth-oauthlib Downloading google_auth_oauthlib-0.5.1-py2.py3-non-any.whl (19 KB)
Reemplaza USERNAME por tu nombre de usuario.
Instala Google Cloud CLI en tu servidor de Jenkins. Para obtener instrucciones, consulta la Guía de inicio rápido: Instala gcloud CLI.
Configura tu entorno de Google Cloud
En esta sección, se describen los pasos que debes completar para asegurarte de que tu entorno de Google Cloud que aloja tu contenedor sin servidor pueda conectarse con Jenkins y Keycloak.
En Google Cloud, crea una cuenta de servicio para que el microservicio en Cloud Run pueda acceder a los permisos que se le adjuntan. Por ejemplo, para crear una cuenta de servicio con gcloud CLI, haz lo siguiente:
gcloud iam service-accounts create cloudrun-oidc \ –-description="cloud run oidc sa" \ –-display-name="cloudrun-oidc"
De forma predeterminada, Cloud Run crea una cuenta de servicio predeterminada por ti. Sin embargo, usar la cuenta de servicio predeterminada no es una práctica recomendada de seguridad porque la cuenta tiene un conjunto amplio de permisos. Por lo tanto, te recomendamos que crees una cuenta de servicio independiente para tu microservicio. Para obtener instrucciones sobre cómo crear una cuenta de servicio para Cloud Run, consulta Crea y administra cuentas de servicio.
Crea un grupo de Workload Identity. Para crear un grupo con gcloud CLI, ejecuta lo siguiente:
gcloud iam workload-identity-pools create cloudrun-oidc-pool \ --location="global" \ —-description="cloudrun-oidc" \ —-display-name="cloudrun-oidc"
Crea un proveedor de grupos de federación de Workload Identity para OpenID Connect:
gcloud iam workload-identity-pools providers create-oidc cloud-run-provider \ --workload-identity-pool="cloudrun-oidc-pool" \ --issuer-uri="VAR_LINK_TO_ENDPOINT" \ --location="global" \ --attribute-mapping ="google.subject=assertion.sub,attribute.isadmin-assertion.isadmin,attribute.aud=assertion.aud" \ --attribute-condition="attribute.isadmin=='true'"
Reemplaza
VAR_LINK_TO_ENDPOINT
por una variable que contenga el vínculo al extremo OIDC de Keycloak. Para encontrar este vínculo, en la ventana Dominio de la Consola del administrador de KeyCloud, haz clic en la pestaña General. El extremo debe ser HTTPS, lo que significa que debes configurar tu servidor de Keycloak con HTTPS.
Obtén el JWT del usuario autenticado de Keycloak
En la VM que ejecuta Keycloak, descarga el token en un archivo de texto. Por ejemplo, en Linux, ejecuta lo siguiente:
curl -L -X POST 'https://IP_FOR_KEYCLOAK:8080/auth/realms/master/protocol/openid-connect/token' -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id=jenks' \ --data-urlencode 'grant_type=password' \ --data-urlencode 'client_secret=CLIENT_SECRET \ --data-urlencode 'scope=openid' \ --data-urlencode 'username=USERNAME' \ --data-urlencode 'password=PASSWORD' | grep access_token | cut -c18-1490 > token.txt
Reemplaza lo siguiente:
IP_FOR_KEYCLOAK
por la dirección IP del servidor de KeycloakCLIENT_SECRET
por el secreto del cliente de Keycloak.USERNAME
con un usuario de KeycloakPASSWORD
por la contraseña del usuario de Keycloak.
Este comando incluye el ID de cliente, el secreto del cliente, el nombre de usuario y la contraseña. Como práctica recomendada de seguridad, te recomendamos que uses variables de entorno para enmascarar estos valores en lugar de usar la línea de comandos. El comando de ejemplo redirecciona las credenciales a un archivo llamado
token.txt
.De manera opcional, para automatizar este paso, puedes crear una secuencia de comandos de Bash.
Valida tu token en jwt.io.
En la VM, crea tu archivo de credenciales:
gcloud iam workload-identity-pools create-cred-config \ projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/cloudrun-oidc-pool/providers/cloud-run/provider \ --output-file=sts-creds.json \ --credential-source-file=token.txt
Para obtener más información, consulta gcloud iam workload-identity-pools create-cred-config.
Tu archivo de salida debería verse de la siguiente manera:
{ "type": "external_account", "audience": "//iam.google.apis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/cloudrun-oidc-pool/subject/USER_EMAIL", "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", "token_url": "https://sts.googleapis.com/v1/token", "credential_source": { "file" "token.txt" } }
PROJECT_NUMBER
es tu número de proyecto.En la VM, establece el archivo
sts.creds.json
como una variable para ADC:export GOOGLE_APPLICATION_CREDENTIALS=/Users/USERNAME/sts-creds.json
Reemplaza USERNAME por tu nombre de usuario de UNIX.
Antes de que se lanzara la federación de identidades para cargas de trabajo, este valor era la clave de la cuenta de servicio. Con la federación de identidades para cargas de trabajo, este valor es el archivo de credenciales recién creado.
Crea una vinculación de rol para que el usuario actúe en nombre de la cuenta de servicio:
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT \ --role roles/iam.workloadIdentityUser \ --member "principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/cloudrun-oidc-pool/subject/USER_EMAIL
Reemplaza lo siguiente:
SERVICE_ACCOUNT
por la dirección de correo electrónico de la cuenta de servicio que creaste en Configura tu entorno de Google Cloud. Para obtener más información, consulta gcloud iam service-accounts add-iam-policy-binding.USER_EMAIL
por tu dirección de correo electrónico.
Permite que la cuenta de servicio acceda al servicio de Cloud Run:
gcloud run services add-iam-policy-binding SERVICE_NAME --member-"serviceAccount:SERVICE_ACCOUNT" \ --role="roles/run.invoker"
Reemplaza lo siguiente:
SERVICE_NAME
por el nombre del microservicio que se ejecuta en Cloud Run.SERVICE_ACCOUNT
con la dirección de correo electrónico de la cuenta de servicio de Cloud Run.
Para obtener más información, consulta gcloud run services add-iam-policy-binding.
Genera un token de ID:
#!/usr/bin/python from google.auth import credentials from google.cloud import iam_credentials_v1 import google.auth import google.oauth2.credentials from google.auth.transport.requests import AuthorizedSession, Request url = "https://WORKLOAD_FQDN" aud = "https://WORKLOAD_FQDN" service_account = 'SERVICE_ACCOUNT' name = "projects/-/serviceAccounts/{}".format(service_account) id_token = client.generate_id_token(name=name,audience=aud, include_email=True) print(id_token.token) creds = google.oauth2.credentials.Credentials(id_token.token) authed_session = AuthorizedSession(creds) r = authed_session.get(url) print(r.status_code) print(r.text)
Reemplaza lo siguiente:
WORKLOAD_FQDN
con el FQDN de tu carga de trabajo.SERVICE_ACCOUNT
por la dirección de correo electrónico de la cuenta de servicio de Cloud Run.
El token que uses puede llamar a la API de Identity and Access Management, lo que te dará el JWT nuevo que necesitas para invocar tu servicio de Cloud Run.
Puedes usar tu token dentro de una canalización de Jenkins para invocar el contenedor sin servidores que ejecutas en Cloud Run. Sin embargo, estos pasos están fuera del alcance de este instructivo.
Realiza una limpieza
Puedes borrar tu proyecto para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo.
Borra el proyecto
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
¿Qué sigue?
- Obtén más información sobre la federación de identidades para cargas de trabajo.
- Para obtener más información sobre las arquitecturas de referencia, los diagramas y las prácticas recomendadas, explora Cloud Architecture Center.