Integrar Cloud Run y la federación de identidades de cargas de trabajo


En este tutorial se describe cómo usar la federación de identidades de carga de trabajo para autenticar cargas de trabajo que se ejecutan fuera de Google Cloud para que puedan acceder a microservicios alojados en Cloud Run. Este tutorial está dirigido a administradores que quieran integrar la federación de identidades de cargas de trabajo con su proveedor de identidades. Federación de identidades de cargas de trabajo te permite conectar cargas de trabajo externas con cargas de trabajo que se ejecutan en Google Cloud. Cloud Run te permite ejecutar microservicios en contenedores sin reconocimiento del estado.

En este tutorial se explica cómo configurar Jenkins como carga de trabajo externa, Keycloak como proveedor de identidades, Cloud Run y la federación de identidades de carga de trabajo. Cuando completes este tutorial, podrás ver cómo la federación de identidades de cargas de trabajo te permite autenticar tu aplicación Jenkins con Google Cloud mediante la autenticación OpenID Connect.

Autenticación de cargas de trabajo externas mediante la federación de identidades de cargas de trabajo

La federación de identidades de 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 enGoogle Cloud puede beneficiarse de esta función.

La federación de identidades de cargas de trabajo te permite usar tu IdP para autenticarte directamente conGoogle Cloud. Para autenticarte, usa OpenID Connect. Cloud Run acepta tokens de OpenID Connect de tu proveedor de identidades para la autenticación.

El proceso de autenticación al usar la federación de identidades de cargas de trabajo es el siguiente:

  1. Tu biblioteca de autenticación (AUTHN) envía una solicitud de token web JSON (JWT) al IdP.
  2. Tu proveedor de identidades firma los JSON Web Tokens (JWTs). La biblioteca AUTHN lee estos datos de una variable.
  3. La biblioteca envía un comando POST al servicio de tokens de seguridad, que incluye el token firmado.
  4. El servicio de token de seguridad consulta el proveedor de grupos de identidades de carga de trabajo que has configurado para generar confianza y verifica la identidad de la credencial.
  5. El servicio de tokens de seguridad devuelve un token de acceso federado.
  6. La biblioteca envía el token de acceso federado a IAM.
  7. IAM intercambia el token de acceso federado por un token de ID. Para obtener más información, consulta Crear un token de ID de OpenID Connect (OIDC).
  8. La biblioteca proporciona el token de ID a Jenkins.
  9. Jenkins usa este token para autenticarse en Cloud Run.

En el siguiente diagrama se muestra el flujo de autenticación:

Flujo de autenticación.

Objetivos

  • Configura Jenkins como carga de trabajo externa.
  • Configura Keycloak como el IdP compatible con OpenID Connect.
  • Conecta Jenkins con Keycloak.
  • Instala las bibliotecas de cliente de Cloud para obtener el token JWT de Keycloak en Google Cloud.
  • Conecta Google Cloud a Keycloak y Jenkins.
  • Obtiene el JWT del usuario autenticado de Keycloak.

Aunque en este tutorial se usa Keycloak, puedes usar cualquier proveedor de identidades que admita OpenID Connect, como GitLab, Okta o OneLogin.

Costes

En este documento, se utilizan los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costes basada en el uso previsto, utiliza la calculadora de precios.

Los usuarios nuevos Google Cloud pueden disfrutar de una prueba gratuita.

Cuando termines las tareas que se describen en este documento, puedes evitar que se te siga facturando eliminando los recursos que has creado. Para obtener más información, consulta la sección Limpiar.

Antes de empezar

  1. In the Google Cloud console, go to the project selector page.

    Go to project selector

  2. Select or create a Google Cloud project.

  3. Verify that billing is enabled for your Google Cloud project.

  4. Configura un microservicio en Cloud Run. Para obtener más información, consulta la guía de inicio rápido sobre cómo desplegar un contenedor en Cloud Run.

Configurar Jenkins

Completa estas tareas en un entorno que no sea deGoogle Cloud , como tu entorno local u otra nube.

Si ya tienes un proveedor de identidades que admite OpenID Connect y una carga de trabajo externa, puedes saltarte este paso e ir a Instalar bibliotecas de cliente de Cloud.

Para simular una carga de trabajo externa, puedes usar una VM con Jenkins instalado. Puedes ejecutar Jenkins como una imagen Docker o instalarlo directamente en tu servidor. En los siguientes pasos se muestra cómo instalarlo directamente en el servidor.

  1. En la VM que elijas, abre una línea de comandos.
  2. Instala Java:

    $ sudo apt update
    $ sudo apt install openjdk-11-jre
    $ java -version
    
  3. Instala Jenkins:

    curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.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
    
  4. Verifica que puedes acceder a tu servidor Jenkins en el puerto 8080. Si usas una VM que está detrás de un cortafuegos, asegúrate de que los puertos correspondientes estén abiertos.

  5. Obtén tu contraseña de administrador y configura Jenkins. Para obtener instrucciones, consulta el artículo Asistente de configuración posterior a la instalación.

  6. Sigue estos pasos para configurar SSL:

    1. Si tienes un proveedor de dominio, puedes usar su autoridad de certificación (CA) para solicitar un certificado firmado. También puedes obtener un certificado firmado gratuito que dure 90 días en zerossl.com.
    2. 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
      

      Haz los cambios siguientes:

      • CERTFILE con 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 con tu nombre de usuario.
    3. Cambia el nombre de los archivos y genera un archivo .pkcs12 que pueda usar Jenkins:

      openssl rsa -in KEYFILE.com.key -out KEYFILE.com.key

      Sustituye KEYFILE por el nombre del archivo de certificado.

  7. Actualiza el archivo de /etc/sysconfig/jenkins:

    1. Abre el archivo en un editor de texto:

      vi /etc/sysconfig/jenkins
      
    2. Asigna el valor -1 a JENKINS_PORT.

    3. Asigna el valor 8443 a JENKINS_HTTPS_PORT.

    4. En la parte inferior del archivo, añade los siguientes argumentos:

      JENKINS_ARGS="--httpsCertificate=/var/lib/jenkins/.ssl/CERTFILE.crt --httpsPrivateKeys=/var/lib/jenkins/.ssl/KEYFILE.pkcs1.key"

      Haz los cambios siguientes:

      • CERTFILE con el nombre de archivo del certificado en formato .crt.
      • KEYFILE con el nombre de archivo de la clave PKCS.
  8. Reinicia el servidor de Jenkins.

  9. Verifica que el puerto 8443 esté abierto en tu cortafuegos y accede a Jenkins en el puerto 8443.

  10. Instala un complemento de Jenkins que necesites para integrar Keycloak con Jenkins. Puedes elegir una de las siguientes opciones:

    Para instalar el complemento, sigue estos pasos:

    1. En el panel de control de Jenkins, ve a Manage Jenkins > Manage Plugins (Gestionar Jenkins > Gestionar complementos).
    2. Selecciona Disponible y busca el complemento que quieras. En la siguiente captura de pantalla se muestra el gestor de complementos con la pestaña Disponible seleccionada.

      Gestor de complementos de Jenkins.

    3. Instala el complemento.

Configurar Keycloak

En este tutorial, Keycloak gestiona los usuarios, los grupos y los roles. Keycloak usa reinos para gestionar usuarios.

  1. En la máquina virtual que se ejecuta fuera de Google Cloud, instala el servidor Keycloak. En este tutorial, te recomendamos que instales Keycloak desde un contenedor Docker.

  2. Abre la consola de administración de Keycloak.

  3. Ve a Ajustes del reino.

  4. En la pestaña General, compruebe que los campos estén configurados de la siguiente manera:

    • Habilitado: ACTIVADO
    • Acceso gestionado por el usuario: DESACTIVADO
    • Endpoints: OpenID Endpoint Configuration (Configuración del endpoint de OpenID) y SAML 2.0 Identity Provider Metadata (Metadatos del proveedor de identidades de SAML 2.0)

    En la siguiente captura de pantalla se muestran los campos que debe configurar.

    Configuración general de Keycloak.

  5. Crea un cliente para tener 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).

    1. En la consola de administración de Keycloak, haz clic en Clientes > Crear.
    2. Introduce lo siguiente:

      • 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 Jenkins.

      En la siguiente captura de pantalla se muestran los campos que debe configurar.

      Añadir cliente de Keycloak.

    3. Haz clic en Guardar.

  6. En la pestaña Instalación, comprueba que el formato del token sea JSON de Keycloak OIDC. Copia este token, ya que lo necesitarás para completar la configuración de Jenkins.

  7. Para crear un grupo de prueba, sigue estos pasos:

    1. En la consola de administración de Keycloak, haz clic en Grupos > Nuevo.
    2. Escribe el nombre del grupo y haz clic en Guardar.
    3. Crea otro grupo de prueba. Puedes asignar roles a tus grupos, pero no es necesario en este tutorial.
  8. Para crear un usuario de prueba que añadir al grupo, sigue estos pasos:

    1. En la consola de administración de Keycloak, haz clic en Gestionar usuarios > Añadir usuarios.
    2. Rellena la información del usuario y haz clic en Guardar.

      En la siguiente captura de pantalla se muestra un ejemplo de la información de una cuenta de usuario.

      Añadir usuario de Keycloak.

    3. Haz clic en la pestaña Credenciales y comprueba que la opción Temporal esté desactivada.

    4. Cambia 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 Credenciales con los campos que debes configurar.

      Cambiar la contraseña de Keycloak.

    5. Haz clic en la pestaña Grupos y selecciona uno de los grupos que hayas creado anteriormente.

    6. Haz clic en Unirme.

    7. Repite este paso para crear más usuarios de prueba.

Configurar Jenkins para la configuración de OpenID Connect

En esta sección se describe cómo configurar el complemento OpenID Connect para Jenkins.

  1. En tu servidor de Jenkins, ve a Gestionar Jenkins > Configurar la seguridad global.
  2. En Ámbito de seguridad, selecciona Complemento de autenticación de Keycloak. Haz clic en Guardar.

  3. Haz clic en Configurar sistema.

  4. En la sección Global Keycloak (Configuración global de Keycloak), copia el JSON de instalación de Keycloak que creaste en Configurar Keycloak. Si necesitas volver a obtener los datos JSON, sigue estos pasos:

    1. En la consola de administración de Keycloak, ve a Clientes.

    2. Haz clic en el nombre del cliente.

    3. En la pestaña Instalación, haz clic en Opción de formato y selecciona JSON de OIDC de Keycloak.

    A continuación, se muestra 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.

  5. Para guardar la configuración de OIDC, haz clic en Guardar.

Ahora, Jenkins puede redirigir a Keycloak para obtener información de los usuarios.

Instalar bibliotecas de cliente de Cloud

Para enviar un JWT de Keycloak a Google Cloud, debes instalar las bibliotecas de cliente de Cloud en el servidor de Jenkins. En este tutorial se usa Python para interactuar conGoogle Cloud mediante el SDK.

  1. En el servidor de Jenkins, instala Python. En los siguientes pasos se muestra cómo instalar Python 3:

    sudo apt update
    sudo apt install software-properties-common
    sudo add-apt-repository ppa:deadsnakes/ppa
    sudo apt update
    sudo apt install python3.8
    
  2. Instala pip3 para poder descargar e importar bibliotecas de cliente de Cloud:

    pip3 –version
    sudo apt update
    sudo apt install python3-pip
    pip3 –version
    
  3. Instala las bibliotecas de 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)
    

    Sustituye USERNAME por tu nombre de usuario.

  4. Instala Google Cloud CLI en tu servidor de Jenkins. Para obtener instrucciones, consulta el artículo Guía de inicio rápido: instala gcloud CLI.

Configurar el Google Cloud entorno

En esta sección se describen los pasos que debe completar para asegurarse de que su entornoGoogle Cloud , que aloja su contenedor sin servidor, pueda conectarse con Jenkins y Keycloak.

  1. En Google Cloud, crea una cuenta de servicio para que el microservicio de Cloud Run pueda acceder a los permisos que tiene asociados. 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. Sin embargo, no es una práctica recomendada de seguridad usar la cuenta de servicio predeterminada, ya que tiene un amplio conjunto 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 el artículo Crea y administra cuentas de servicio.

  2. Crea un grupo de identidades de carga de trabajo. 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"
    
  3. Crea un proveedor de grupos de identidades de carga de trabajo 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'"
    

    Sustituye VAR_LINK_TO_ENDPOINT por una variable que contenga el enlace al endpoint OIDC de Keycloak. Para encontrar este enlace, en la consola de administración de KeyCloud, en la ventana Realm (Ámbito), haz clic en la pestaña General (General). El endpoint debe ser HTTPS, lo que significa que debes configurar tu servidor Keycloak con HTTPS.

Obtener el JWT del usuario autenticado de Keycloak

  1. 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
    

    Haz los cambios siguientes:

    • IP_FOR_KEYCLOAK con la dirección IP del servidor Keycloak.
    • CLIENT_SECRET con el secreto de cliente de Keycloak.
    • USERNAME con un usuario de Keycloak.
    • PASSWORD con la contraseña del usuario de Keycloak.

    Este comando incluye el ID de cliente, el secreto de cliente, el nombre de usuario y la contraseña. Como práctica recomendada de seguridad, te sugerimos que uses variables de entorno para enmascarar estos valores en lugar de usar la línea de comandos. El comando de ejemplo redirige las credenciales a un archivo llamado token.txt.

    Si quieres automatizar este paso, puedes crear una secuencia de comandos bash.

  2. Valida tu token en jwt.io.

  3. En la VM, crea el 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.

    El archivo de salida debería tener este aspecto:

    {
        "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 el número de tu proyecto.

  4. En la VM, define el archivo sts.creds.json como una variable para ADC:

    export GOOGLE_APPLICATION_CREDENTIALS=/Users/USERNAME/sts-creds.json
    

    Sustituye USERNAME por tu nombre de usuario de UNIX.

    Antes de que se lanzara la federación de identidades de carga de trabajo, este valor era la clave de la cuenta de servicio. Con la federación de identidades de cargas de trabajo, este valor es el archivo de credenciales recién creado.

  5. Crea un enlace de rol para que el usuario pueda suplantar 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
    

    Haz los cambios siguientes:

  6. 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"
    

    Haz los cambios siguientes:

    • SERVICE_NAME con el nombre del microservicio que se ejecuta en Cloud Run.

    • SERVICE_ACCOUNT con la dirección de correo de la cuenta de servicio de Cloud Run.

    Para obtener más información, consulta gcloud run services add-iam-policy-binding.

  7. 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'
    
    client = iam_credentials_v1.IAMCredentialsClient()
    
    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)
    

    Haz los cambios siguientes:

    • WORKLOAD_FQDN con el FQDN de tu carga de trabajo.

    • SERVICE_ACCOUNT con la dirección de correo de la cuenta de servicio de Cloud Run.

El token que utilices puede llamar a la API Identity and Access Management, que te proporcionará el nuevo JWT que necesitas para invocar tu servicio de Cloud Run.

Puedes usar tu token en una canalización de Jenkins para invocar el contenedor sin servidor que estés ejecutando en Cloud Run. Sin embargo, estos pasos no se incluyen en este tutorial.

Limpieza

Para evitar que se apliquen cargos en tu cuenta por los recursos utilizados en este tutorial, puedes eliminar el proyecto. Google Cloud

Eliminar el proyecto

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Siguientes pasos