Emitir certificados para certificar la identidad de terceros

En este tutorial se muestra cómo emitir certificados que acrediten la identidad de un tercero mediante la reflexión de identidad y los grupos de identidades de carga de trabajo.

Puedes usar la reflexión de identidad para crear certificados que coincidan con la identidad verificada de un solicitante de certificados. Con la reflexión de identidad, puedes limitar a un solicitante de certificados sin privilegios para que solo solicite certificados con un nombre alternativo de entidad (SAN) que corresponda a la identidad de sus credenciales.

Objetivos

En este tutorial se explica cómo puedes usar el servicio de CA con grupos de Workload Identity para federar una identidad de terceros y obtener un certificado que acredite esta identidad.

Antes de empezar

Antes de empezar, asegúrate de que entiendes los siguientes conceptos:

  • Grupos de identidades de carga de trabajo: los grupos de identidades de carga de trabajo te permiten gestionar proveedores de identidades de terceros. Para obtener más información, consulta Gestionar grupos y proveedores de Workload Identity.
  • Federación de identidades de cargas de trabajo: la federación de identidades de cargas de trabajo aprovecha los grupos de identidades de cargas de trabajo para dar acceso a servicios de terceros. Google CloudPara obtener más información, consulta Federación de Workload Identity.
  • Servicio de tokens de seguridad (STS): el servicio de tokens de seguridad te permite intercambiar credenciales de terceros por tokens propios (Google Cloud). Para obtener más información, consulta Servicio de tokens de seguridad.
  • Reflejo de identidad: la función de reflejo de identidad permite que la identidad verificada de un solicitante de certificado se incluya en el certificado solicitado. Para obtener más información, consulta Reflexión de identidad.

Asegúrate de que tienes los siguientes roles de gestión de identidades y accesos (IAM):

  • Para gestionar autoridades de certificación (CAs) y grupos de CAs, así como para solicitar certificados, debes tener el rol Gestor de operaciones del Servicio de Autoridades de Certificación (privateca.caManager). Para obtener más información sobre los roles de gestión de identidades y accesos de Servicio de Autoridades de Certificación, consulta el artículo Control de acceso con IAM.
  • Para gestionar grupos y proveedores de Workload Identity, debes tener el rol Administrador de grupos de Workload Identity (iam.workloadIdentityPoolAdmin).
  • Para crear una cuenta de servicio, debes tener el rol Administrador de cuentas de servicio (iam.serviceAccountAdmin).

Para obtener información sobre cómo conceder roles de gestión de identidades y accesos, consulta el artículo Gestionar el acceso a proyectos, carpetas y organizaciones. Puedes conceder los roles de IAM necesarios a una cuenta de Google, una cuenta de servicio, un grupo de Google, una cuenta de Google Workspace o un dominio de Cloud Identity.

Configurar un grupo y un proveedor de identidades de carga de trabajo

En este tutorial se explica cómo puedes usar un proveedor Google OpenID Connect (OIDC) combinado con una cuenta de servicio para actuar como identidad de terceros. El proveedor de OIDC de cuentas de Google actúa como proveedor de identidades (IDP) de terceros y la cuenta de servicio Google Cloud es una cuenta de terceros de ejemplo cuya identidad se ha verificado mediante este IDP.

Los grupos de identidades de carga de trabajo admiten varios proveedores de identidades, incluidos Microsoft Azure/Active Directory local, AWS y proveedores de identidades basados en SAML.

Para configurar un grupo de identidades de carga de trabajo y un proveedor, haz lo siguiente: 1. Para representar un conjunto de identidades federadas de confianza, crea un grupo de identidades de carga de trabajo:

```
gcloud iam workload-identity-pools create IDENTITY_POOL_ID --location global --display-name "tutorial-wip"
```

Replace the following:

- <var>IDENTITY_POOL_ID</var>: The unique identifier of the new workload
  identity pool.
  1. Crea un proveedor de grupos de identidades de carga de trabajo para tu proveedor de identidades externo:

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID --location global --workload-identity-pool IDENTITY_POOL_ID --display-name "tutorial-oidc" --attribute-mapping "google.subject=assertion.sub" --issuer-uri="https://accounts.google.com"
    

    Haz los cambios siguientes:

    • PROVIDER_ID: identificador único del proveedor de identidades que quiere crear en el grupo de identidades de carga de trabajo.

    Puedes personalizar las siguientes marcas según tu caso práctico:

    • attribute-mapping: esta marca define la asignación entre las reclamaciones de terceros y la reclamación principal de Google, google.subject. google.subject es una asignación obligatoria que puedes definir en cualquier reclamación o combinación de reclamaciones mediante una expresión CEL. Para obtener más información, consulta Definir una asignación de atributos y una condición.
    • issuer-uri: en el caso de los proveedores de OIDC, esta marca es un endpoint de acceso público al que Google se conecta para verificar tokens de terceros. Para obtener más información, consulta Preparar un proveedor de identidades externo.

    Para obtener más información sobre cómo configurar un proveedor de identidad de carga de trabajo, consulta Configurar federación de identidades de cargas de trabajo.

Crear un grupo de AC y una AC emisora

En esta sección se explica cómo crear un grupo de CAs y añadirle una CA raíz. Puede usar este grupo de ACs para emitir certificados de identidad reflejada. Si quieres usar un grupo y una AC, puedes saltarte esta sección.

En lugar de una CA raíz, también puedes crear una CA subordinada. Crear una CA raíz ayuda a acortar el procedimiento.

  1. Crea un grupo de autoridades de certificación en el nivel de DevOps:

    gcloud privateca pools create CA_POOL_ID --location LOCATION --tier devops
    

    Haz los cambios siguientes:

    • CA_POOL_ID: el ID del grupo de AC del Servicio de Autoridades de Certificación que emite certificados.
    • LOCATION: ubicación del grupo de autoridades de certificación.

    Para obtener más información sobre cómo crear grupos de autoridades de certificación, consulta el artículo Crear un grupo de autoridades de certificación.

  2. Crea una CA raíz:

    gcloud privateca roots create CA_ID --pool CA_POOL_ID  --location LOCATION --subject "CN=test,O=test-org"
    

    Haz los cambios siguientes:

    • CA_ID: el ID de la autoridad de certificación que emite los certificados.
    • CA_POOL_ID: el ID del grupo de AC del Servicio de Autoridades de Certificación que emite certificados.
    • LOCATION: ubicación del grupo de autoridades de certificación.

    Para obtener más información sobre cómo crear una CA raíz, consulta el artículo Crear una CA raíz.

  3. Permite que las identidades federadas del grupo de identidades de carga de trabajo emitan certificados del grupo de CAs. La reflexión de identidad requiere el rol de gestión de identidades y accesos Solicitante de certificados de carga de trabajo del servicio de CA (roles/privateca.workloadCertificateRequester) para los solicitantes de CreateCertificate.

    Puedes representar los principales de grupos de identidades de carga de trabajo con distintos niveles de granularidad, desde un solo asunto hasta todas las identidades del grupo en todos los proveedores. Para obtener más información, consulta los principales o conjuntos de principales disponibles (usa la pestaña de Google Cloud CLI) que mejor se adapten a tu caso práctico.

    gcloud privateca pools add-iam-policy-binding CA_POOL_ID \
        --location LOCATION \
        --role "roles/privateca.workloadCertificateRequester" \
        --member "group:PROJECT_ID.svc.id.goog:/allAuthenticatedUsers/"
    

    Haz los cambios siguientes:

    • LOCATION: la ubicación del grupo de autoridades de certificación
    • PROJECT_ID: el ID del Google Cloud proyecto en el que has creado el grupo de identidades de carga de trabajo

Crear una cuenta de servicio que represente una identidad de terceros

En el siguiente procedimiento se da por hecho que una cuenta de servicio representa a un tercero. En esta sección se muestra cómo usar el endpoint IAM de GenerateIdToken para obtener una identidad de terceros en forma de token OIDC. En función de tu caso práctico, es posible que tengas que seguir otros pasos para obtener el token de identidad de terceros que elijas.

gcloud iam service-accounts create SERVICE_ACCOUNT

Haz los cambios siguientes:

  • SERVICE_ACCOUNT: el ID de la cuenta de servicio que representa la identidad de terceros.

Emitir un certificado para certificar la identidad de terceros

Antes de empezar, asegúrate de que tienes el rol de gestión de identidades y accesos Creador de tokens de cuenta de servicio (roles/iam.serviceAccountTokenCreator). Necesita este rol de gestión de identidades y accesos para llamar a la API GenerateIdToken.

Para obtener un certificado que certifique la identidad de un tercero, sigue estos pasos:

  1. Obtén un token de identidad de terceros de tu proveedor de identidades externo.

    curl

    export ID_TOKEN=`curl -d '{"audience":"//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/IDENTITY_POOL_ID/providers/PROVIDER_ID"}' -H 'Content-Type: application/json' -H "Authorization: Bearer $(gcloud auth print-access-token)" https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com:generateIdToken | python3 -c "import sys;import json;print(json.load(sys.stdin)['token'])"`
    

    Haz los cambios siguientes:

    • PROJECT_ID: el ID del proyecto en el que quieres crear recursos. Google Cloud

    Bibliotecas de cliente

    .

    Para acceder al token de terceros de forma programática, puedes obtener un token de una credencial de origen de archivo o de una credencial de origen de URL. Para obtener más información, consulta Autenticar mediante bibliotecas de cliente, la CLI de gcloud o Terraform. En este tutorial, seguimos un flujo de trabajo de credenciales de origen de archivo.

    Carga tu credencial en una ruta que pueda leer el solicitante del certificado:

    curl -d '{"audience":"//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/IDENTITY_POOL_ID/providers/PROVIDER_ID"}' -H 'Content-Type: application/json' -H "Authorization: Bearer $(gcloud auth print-access-token)" https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com:generateIdToken | python3 -c "import sys;import json;       print(json.load(sys.stdin)['token']) > /tmp/oidc_token.txt
    

    Haz los cambios siguientes:

    • PROJECT_ID: el ID del proyecto en el que quieras crear recursos.
  2. Intercambia tu token de terceros por un token de OAuth federado mediante el endpoint STS token:

    curl

    export STS_TOKEN=`curl -L -X POST 'https://sts.googleapis.com/v1/token' -H 'Content-Type: application/json' \
    -d '{
        "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
        "audience": "//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/IDENTITY_POOL_ID/providers/PROVIDER_ID",
        "requested_token_type": "urn:ietf:params:oauth:token-type:access_token",
        "scope": "https://www.googleapis.com/auth/cloud-platform",
        "subject_token": "'$ID_TOKEN'",
        "subject_token_type": "urn:ietf:params:oauth:token-type:jwt"
    }' | python3 -c "import sys;import json; print(json.load(sys.stdin)['access_token'])"`
    

    Bibliotecas de cliente

    1. Crea un archivo de configuración de credenciales llamado oidc_token.txt que el código que solicita el certificado pueda leer para realizar un intercambio de tokens.
    gcloud iam workload-identity-pools create-cred-config projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/IDENTITY_POOL_ID --output-file=/tmp/cred_config.json --credential-source-file=/tmp/oidc_token.txt
    
    1. Lee el archivo oidc_token.txt para definir el mecanismo de autorización en la biblioteca del cliente:

    python

    import json
    
    from google.auth import identity_pool
    
    with open('/tmp/cred_config.json', 'r') as f:
      json_config_info = json.loads(f.read())
    credentials = identity_pool.Credentials.from_info(json_config_info)
    scoped_credentials = credentials.with_scopes(
        ['https://www.googleapis.com/auth/cloud-platform'])
    
  3. Haz una solicitud al Servicio de Autoridades de Certificación con el modo de solicitud de asunto REFLECTED_SPIFFE:

    curl

    1. Opcional: Si no tienes un CSR, créalo ejecutando el siguiente comando.

      export TUTORIAL_CSR=$(openssl req -newkey rsa:2048 -nodes -subj / -keyout tutorial_do_not_use.key)
      
    2. Solicita un certificado con la CSR, un tiempo de validez y un modo de solicitud de sujeto reflejado:

      curl -H "Authorization: Bearer $(echo $STS_TOKEN)" https://privateca.googleapis.com/v1/projects/PROJECT_NUMBER/locations/LOCATION/caPools/CA_POOL_ID/certificates\?alt\=json  -X POST -H "Content-Type: application/json" -H 'Accept: application/json' --data '{"lifetime": "100s", "pemCsr": "'$TUTORIAL_CSR'", "subjectMode": "REFLECTED_SPIFFE"}'
      

    Bibliotecas de cliente

    Para reenviar el token propio al servicio de AC, debe crear un cliente con credenciales. Después, puedes usar este cliente con credenciales para hacer solicitudes de certificado:

    1. Inicia un cliente del servicio de CA con credenciales:

      python

      caServiceClient = privateca_v1.CertificateAuthorityServiceClient(credentials=scoped_credentials)
      
    2. Solicita un certificado.

      Python

      Para autenticarte en el servicio de AC, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación en un entorno de desarrollo local.

      import google.cloud.security.privateca_v1 as privateca_v1
      from google.protobuf import duration_pb2
      
      
      def create_certificate(
          project_id: str,
          location: str,
          ca_pool_name: str,
          ca_name: str,
          certificate_name: str,
          common_name: str,
          domain_name: str,
          certificate_lifetime: int,
          public_key_bytes: bytes,
      ) -> None:
          """
          Create a Certificate which is issued by the Certificate Authority present in the CA Pool.
          The key used to sign the certificate is created by the Cloud KMS.
      
          Args:
              project_id: project ID or project number of the Cloud project you want to use.
              location: location you want to use. For a list of locations, see: https://cloud.google.com/certificate-authority-service/docs/locations.
              ca_pool_name: set a unique name for the CA pool.
              ca_name: the name of the certificate authority which issues the certificate.
              certificate_name: set a unique name for the certificate.
              common_name: a title for your certificate.
              domain_name: fully qualified domain name for your certificate.
              certificate_lifetime: the validity of the certificate in seconds.
              public_key_bytes: public key used in signing the certificates.
          """
      
          caServiceClient = privateca_v1.CertificateAuthorityServiceClient()
      
          # The public key used to sign the certificate can be generated using any crypto library/framework.
          # Also you can use Cloud KMS to retrieve an already created public key.
          # For more info, see: https://cloud.google.com/kms/docs/retrieve-public-key.
      
          # Set the Public Key and its format.
          public_key = privateca_v1.PublicKey(
              key=public_key_bytes,
              format_=privateca_v1.PublicKey.KeyFormat.PEM,
          )
      
          subject_config = privateca_v1.CertificateConfig.SubjectConfig(
              subject=privateca_v1.Subject(common_name=common_name),
              subject_alt_name=privateca_v1.SubjectAltNames(dns_names=[domain_name]),
          )
      
          # Set the X.509 fields required for the certificate.
          x509_parameters = privateca_v1.X509Parameters(
              key_usage=privateca_v1.KeyUsage(
                  base_key_usage=privateca_v1.KeyUsage.KeyUsageOptions(
                      digital_signature=True,
                      key_encipherment=True,
                  ),
                  extended_key_usage=privateca_v1.KeyUsage.ExtendedKeyUsageOptions(
                      server_auth=True,
                      client_auth=True,
                  ),
              ),
          )
      
          # Create certificate.
          certificate = privateca_v1.Certificate(
              config=privateca_v1.CertificateConfig(
                  public_key=public_key,
                  subject_config=subject_config,
                  x509_config=x509_parameters,
              ),
              lifetime=duration_pb2.Duration(seconds=certificate_lifetime),
          )
      
          # Create the Certificate Request.
          request = privateca_v1.CreateCertificateRequest(
              parent=caServiceClient.ca_pool_path(project_id, location, ca_pool_name),
              certificate_id=certificate_name,
              certificate=certificate,
              issuing_certificate_authority_id=ca_name,
          )
          result = caServiceClient.create_certificate(request=request)
      
          print("Certificate creation result:", result)
      
      

    3. Verifica el certificado. Tu certificado debe tener un asunto que contenga un único SAN URI. El SAN que certifica una identidad tiene el siguiente formato:

      spiffe://IDENTITY_POOL_ID.PROJECT_NUMBER.global.workload.id.goog/subject/<oidc_subject_number>
      

      Sustituye:

      • IDENTITY_POOL_ID: identificador único del grupo de identidades de carga de trabajo.
      • PROJECT_NUMBER: el número del proyecto en el que has creado el grupo de identidades de carga de trabajo.

Limpieza

Para evitar que se apliquen cargos en tu cuenta Google Cloud por los recursos del servicio de CA que has creado siguiendo este documento, realiza las siguientes operaciones con la CLI de Google Cloud:

  1. Elimina la AC que has creado.

    1. Inhabilita la AC:

      gcloud privateca roots disable CA_ID --pool CA_POOL_ID  --location LOCATION
      

      Sustituye:

      • CA_ID: identificador único de la autoridad certificadora.
      • CA_POOL_ID: identificador único del grupo de ACs.
      • LOCATION: ubicación del grupo de autoridades de certificación.
    2. Elimina la AC:

      gcloud privateca roots delete CA_ID --pool CA_POOL_ID  --location LOCATION --ignore-active-certificates
      

      Sustituye:

      • CA_ID: identificador único de la autoridad certificadora.
      • CA_POOL_ID: identificador único del grupo de ACs.
      • LOCATION: ubicación del grupo de autoridades de certificación.
  2. Elimina el grupo de autoridades de certificación que has creado.

    gcloud privateca pools delete CA_POOL_ID --location LOCATION
    

    Sustituye:

    • CA_POOL_ID: identificador único del grupo de ACs.
    • LOCATION: ubicación del grupo de autoridades de certificación.

    Para obtener más información sobre el comando gcloud privateca pools delete, consulta gcloud privateca pools delete.

  3. Elimina el grupo de identidades de carga de trabajo que has creado:

    gcloud iam workload-identity-pools delete IDENTITY_POOL_ID --location global
    

    Sustituye:

    • IDENTITY_POOL_ID: identificador único del grupo de identidades de carga de trabajo.
  4. Elimina la cuenta de servicio que has creado:

    gcloud iam service-accounts delete SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com
    

    Sustituye:

    • SERVICE_ACCOUNT: identificador único del grupo de identidades de carga de trabajo.
    • PROJECT_ID: el proyecto propietario de la cuenta de servicio.

El rol de gestión de identidades y accesos de solicitante de certificados de carga de trabajo del servicio de AC (privateca.workloadCertificateRequester) restringe el asunto del certificado emitido únicamente a la identidad del solicitante. Asegúrate de que los usuarios o las cargas de trabajo que usen la función de reflexión de identidad solo tengan asignado el rol de IAM Solicitante del certificado de carga de trabajo del servicio de AC (privateca.workloadCertificateRequester). Para cumplir el principio de mínimos accesos, puedes evitar conceder el rol de gestión de identidades y accesos Solicitante de certificados del servicio de AC (privateca.certificateRequester).

Siguientes pasos