Emissione di certificati che attestano l'identità di terze parti

Questo tutorial mostra come emettere certificati che attestano l'identità di terze parti utilizzando il reflection dell'identità e i pool di identità del workload.

Puoi utilizzare il reflection dell'identità per creare certificati che corrispondono all'identità verificata di un richiedente di certificati. Utilizzando il reflection dell'identità, puoi limitare un richiedente di certificati senza privilegi a richiedere solo certificati con un nome alternativo del soggetto (SAN) corrispondente all'identità nelle sue credenziali.

Obiettivi

Questo tutorial fornisce informazioni su come utilizzare CA Service con i pool di identità del workload per federare un'identità di terze parti e ottenere un certificato che attesta questa identità.

Prima di iniziare

Prima di iniziare, assicurati di comprendere i seguenti concetti:

  • Pool di identità del workload: i pool di identità del workload consentono di gestire i provider di identità di terze parti. Per saperne di più, consulta Gestire i fornitori e i pool di identità del workload.
  • Federazione delle identità per i workload: la federazione delle identità per i workload sfrutta i pool di identità del workload per consentire alle identità di terze parti di accedere ai Google Cloud servizi. Per saperne di più, consulta Federazione delle identità del workload.
  • Servizio token di sicurezza (STS): il servizio token di sicurezza consente di scambiare le credenziali di terze parti con token di prima parte (Google Cloud). Per saperne di più, consulta Servizio token di sicurezza.
  • Reflection dell'identità: la funzionalità di reflection dell'identità consente all'identità verificata di un richiedente di certificati di passare al certificato richiesto. Per saperne di più, consulta Reflection dell'identità.

Assicurati di disporre dei seguenti ruoli IAM:

  • Per gestire le autorità di certificazione (CA) e i pool di CA e richiedere i certificati, devi disporre del ruolo Gestore operazioni CA Service (privateca.caManager). Per saperne di più sui ruoli IAM per CA Service, consulta Controllo dell'accesso con IAM.
  • Per gestire i fornitori e i pool di identità del workload, devi disporre del ruolo Amministratore pool di identità del workload (iam.workloadIdentityPoolAdmin).
  • Per creare un service account, devi disporre del ruolo Amministratore account di servizio (iam.serviceAccountAdmin).

Per informazioni sulla concessione dei ruoli IAM, consulta Gestire l'accesso a progetti, cartelle e organizzazioni. Puoi concedere i ruoli IAM richiesti a un Account Google, un account di servizio, un gruppo Google, un account Google Workspace o un dominio Cloud Identity.

Configurare un pool di identità del workload e un provider

Questo tutorial spiega come utilizzare un provider Google OpenID Connect (OIDC) combinato con un account di servizio per fungere da identità di terze parti. Il provider OIDC degli Account Google funge da provider di identità (IdP) di terze parti e il Google Cloud service account è un'identità di terze parti di esempio asserita da questo IdP.

I pool di identità del workload supportano una varietà di provider di identità, tra cui Microsoft Azure/Active Directory on-premise, AWS e provider di identità basati su SAML.

Per configurare un pool di identità del workload e un provider:

  1. Per rappresentare un insieme attendibile di identità federate, crea un pool di identità del workload:

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

    Sostituisci quanto segue:

    • IDENTITY_POOL_ID: l'identificatore univoco del nuovo pool di identità del workload.
  2. Crea un provider di pool di identità del workload per il tuo provider di identità di terze parti:

    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"
    

    Sostituisci quanto segue:

    • PROVIDER_ID: l'identificatore univoco del provider di identità che vuoi creare nel pool di identità del workload.

    Puoi personalizzare i seguenti flag in base al tuo caso d'uso:

    • attribute-mapping: questo flag imposta il mapping tra le attestazioni di terze parti e l'attestazione dell'entità Google, google.subject. google.subject è un mapping obbligatorio che puoi impostare su qualsiasi attestazione o combinazione di attestazioni utilizzando un'espressione CEL. Per saperne di più, consulta Definire un mapping e una condizione degli attributi.
    • issuer-uri: per i provider OIDC, questo flag è un endpoint accessibile pubblicamente a cui Google si rivolge per la verifica dei token di terze parti. Per saperne di più, consulta Preparare un provider di identità esterno.

    Per saperne di più sulla configurazione di un provider di identità del workload, consulta Configurare la federazione delle identità del workload.

Creare un pool di CA e una CA di emissione

Questa sezione spiega come creare un pool di CA e aggiungervi una CA radice. Puoi utilizzare questo pool di CA per emettere certificati con reflection dell'identità. Se vuoi utilizzare un pool di CA e una CA esistenti, puoi saltare questa sezione.

Anziché una CA radice, puoi anche scegliere di creare una CA subordinata. La creazione di una CA radice contribuisce a ridurre la procedura.

  1. Crea un pool di CA nel livello DevOps:

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

    Sostituisci quanto segue:

    • CA_POOL_ID - l'ID del pool di CA Service che emette i certificati.
    • LOCATION - la località del pool di CA.

    Per saperne di più sulla creazione di pool di CA, consulta Creare un pool di CA.

  2. Crea una CA radice:

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

    Sostituisci quanto segue:

    • CA_ID - l'ID dell'autorità di certificazione che emette i certificati.
    • CA_POOL_ID - l'ID del pool di CA Service che emette i certificati.
    • LOCATION - la località del pool di CA.

    Per saperne di più sulla creazione di una CA radice, consulta Creare una CA radice.

  3. Consenti alle identità federate dal pool di identità del workload di emettere certificati dal pool di CA. Il reflection dell'identità richiede il ruolo IAM CA Service Workload Certificate Requester (roles/privateca.workloadCertificateRequester) per i richiedenti di CreateCertificate.

    Puoi rappresentare le entità del pool di identità del workload in varie granularità, da un singolo soggetto a tutte le identità nel pool tra i provider. Per saperne di più, consulta le entità o gli insiemi di entità disponibili (utilizza la scheda Google Cloud CLI) più adatti al tuo caso d'uso.

    gcloud privateca pools add-iam-policy-binding CA_POOL_ID --location LOCATION --role roles/privateca.workloadCertificateRequester --member "principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/IDENTITY_POOL_ID/*"
    

    Sostituisci quanto segue:

    • CA_POOL_ID: l'ID del pool di CA Service che emette i certificati.
    • LOCATION: la località del pool di CA.
    • PROJECT_NUMBER: il numero del progetto in cui hai creato il pool di identità del workload.
    • IDENTITY_POOL_ID: l'identificatore univoco del nuovo pool di identità del workload.

Creare un account di servizio che rappresenti un'identità di terze parti

La seguente procedura presuppone che un account di servizio rappresenti una terza parte. Questa sezione mostra come utilizzare l' GenerateIdToken endpoint IAM per recuperare un'identità di terze parti sotto forma di un token OIDC. A seconda del tuo caso d'uso, potresti aver bisogno di passaggi diversi per ottenere il token di identità di terze parti di tua scelta.

gcloud iam service-accounts create SERVICE_ACCOUNT

Sostituisci quanto segue:

  • SERVICE_ACCOUNT - l'ID del account di servizio che rappresenta l' identità di terze parti.

Emettere un certificato che attesta l'identità di terze parti

Prima di iniziare, assicurati di disporre del ruolo IAM Creatore token account di servizio (roles/iam.serviceAccountTokenCreator). Questo ruolo IAM è necessario per chiamare l'API GenerateIdToken.

Per ottenere un certificato che attesta l'identità di terze parti:

  1. Ottieni un token di identità di terze parti dal tuo provider di identità di terze parti.

    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'])"`
    

    Sostituisci quanto segue:

    • PROJECT_ID - L' Google Cloud ID del progetto in cui vuoi creare le risorse.

    Librerie client

    Per accedere al token di terze parti a livello di programmazione, puoi ottenere un token da una credenziale di origine file o da una credenziale di origine URL. Per saperne di più, consulta Eseguire l'autenticazione utilizzando le librerie client, gcloud CLI, o Terraform. In questo tutorial, seguiamo un flusso di lavoro con credenziali di origine file.

    Carica le credenziali in un percorso leggibile dal richiedente del certificato:

    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
    

    Sostituisci quanto segue:

    • PROJECT_ID: l'ID del progetto in cui vuoi creare le risorse.
  2. Scambia il token di terze parti con un token OAuth federato utilizzando l'endpoint token di STS:

    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'])"`
    

    Librerie client

    1. Crea un file di configurazione delle credenziali denominato oidc_token.txt che il codice di richiesta del certificato può leggere per eseguire uno scambio di token.
    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. Leggi il file oidc_token.txt per impostare il meccanismo di autorizzazione nella libreria client:

    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. Effettua una richiesta a CA Service con la REFLECTED_SPIFFE modalità di richiesta del soggetto:

    curl

    1. (Facoltativo) Se non hai una CSR, creane una eseguendo il seguente comando.

      export TUTORIAL_CSR=$(openssl req -newkey rsa:2048 -nodes -subj / -keyout tutorial_do_not_use.key)
      
    2. Richiedi un certificato con la CSR, una durata e una modalità di richiesta del soggetto con reflection:

      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"}'
      

    Librerie client

    Per inoltrare il token di prima parte a CA Service, devi creare un client con credenziali. Puoi quindi utilizzare questo client con credenziali per effettuare richieste di certificati:

    1. Avvia un client CA Service con credenziali:

      python

      caServiceClient = privateca_v1.CertificateAuthorityServiceClient(credentials=scoped_credentials)
      
    2. Richiedi un certificato.

      Python

      Per eseguire l'autenticazione in CA Service, configura le credenziali predefinite dell'applicazione. Per saperne di più, consulta Configura l'autenticazione per un ambiente di sviluppo locale.

      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 il certificato. Il certificato deve avere un soggetto contenente un singolo SAN URI. Il SAN che attesta un'identità ha il seguente formato:

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

      Sostituisci:

      • IDENTITY_POOL_ID: l'identificatore univoco del pool di identità del workload.
      • PROJECT_NUMBER - PROJECT_NUMBER: il numero del progetto in cui hai creato il pool di identità del workload.

Libera spazio

Per evitare che al tuo Google Cloud account vengano addebitati costi per le risorse CA Service che hai creato seguendo questo documento, esegui le seguenti operazioni utilizzando Google Cloud CLI:

  1. Elimina la CA che hai creato.

    1. Disabilita la CA:

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

      Sostituisci:

      • CA_ID: l'identificatore univoco della CA.
      • CA_POOL_ID: l'identificatore univoco del pool di CA.
      • LOCATION: la località del pool di CA.
    2. Elimina la CA:

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

      Sostituisci:

      • CA_ID: l'identificatore univoco della CA.
      • CA_POOL_ID: l'identificatore univoco del pool di CA.
      • LOCATION: la località del pool di CA.
  2. Elimina il pool di CA che hai creato.

    gcloud privateca pools delete CA_POOL_ID --location LOCATION
    

    Sostituisci:

    • CA_POOL_ID: l'identificatore univoco del pool di CA.
    • LOCATION: la località del pool di CA.

    Per saperne di più sul comando gcloud privateca pools delete, consulta gcloud privateca pools delete.

  3. Elimina il pool di identità del workload che hai creato:

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

    Sostituisci:

    • IDENTITY_POOL_ID: l'identificatore univoco del pool di identità del workload.
  4. Elimina il account di servizio che hai creato:

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

    Sostituisci:

    • SERVICE_ACCOUNT: l'identificatore univoco del pool di identità del workload.
    • PROJECT_ID: il progetto proprietario del account di servizio.

Il ruolo IAM CA Service Workload Certificate Requester (privateca.workloadCertificateRequester) limita il soggetto del certificato emesso alla sola identità del richiedente. Assicurati che agli utenti o ai carichi di lavoro che utilizzano la funzionalità di reflection dell'identità venga concesso solo il ruolo IAM CA Service Workload Certificate Requester (privateca.workloadCertificateRequester). Per rispettare il principio del privilegio minimo, puoi evitare di concedere il ruolo IAM CA Service Certificate Requester (privateca.certificateRequester).

Passaggi successivi