Emitir certificados que atestam a identidade de terceiros

Este tutorial demonstra como pode emitir certificados que atestam uma identidade de terceiros através da reflexão de identidade e dos grupos de identidades de cargas de trabalho.

Pode usar a reflexão de identidade para criar certificados que correspondam à identidade validada de um requerente de certificado. Através da reflexão de identidade, pode limitar um requerente de certificado não privilegiado a pedir apenas certificados com um nome alternativo do assunto (SAN) correspondente à identidade nas respetivas credenciais.

Objetivos

Este tutorial fornece informações sobre como pode usar o serviço de AC com pools de identidades de cargas de trabalho para federar uma identidade de terceiros e obter um certificado que ateste esta identidade.

Antes de começar

Antes de começar, certifique-se de que compreende os seguintes conceitos:

  • Workload Identity Pools: os Workload Identity Pools permitem-lhe gerir fornecedores de identidades de terceiros. Para mais informações, consulte o artigo Faça a gestão de Workload Identity Pools e fornecedores.
  • Federação de identidades da carga de trabalho: a federação de identidades da carga de trabalho tira partido dos Workload Identity Pools para conceder às identidades de terceiros acesso aos Google Cloudserviços. Para mais informações, consulte o artigo Federação de identidades de carga de trabalho.
  • Security Token Service (STS): o Security Token Service permite-lhe trocar credenciais de terceiros por tokens originais (Google Cloud). Para mais informações, consulte o artigo Serviço de tokens de segurança.
  • Reflexão de identidade: a funcionalidade de reflexão de identidade permite que a identidade validada de um requerente de certificado seja incluída no certificado pedido. Para mais informações, consulte o artigo Reflexão de identidade.

Certifique-se de que tem as seguintes funções do IAM:

  • Para gerir autoridades de certificação (ACs) e conjuntos de ACs, e pedir certificados, tem de ter a função de gestor de operações do serviço de AC (privateca.caManager). Para mais informações sobre as funções da IAM para o serviço de AC, consulte o artigo Controlo de acesso com a IAM.
  • Para gerir Workload Identity Pools e fornecedores, tem de ter a função de administrador do Workload Identity Pool (iam.workloadIdentityPoolAdmin).
  • Para criar uma conta de serviço, tem de ter a função de administrador da conta de serviço (iam.serviceAccountAdmin).

Para obter informações sobre como conceder funções de IAM, consulte o artigo Faça a gestão do acesso a projetos, pastas e organizações. Pode conceder as funções do IAM necessárias a uma Conta Google, uma conta de serviço, um grupo Google, uma conta do Google Workspace ou um domínio do Cloud ID.

Configure um Workload Identity Pool e um fornecedor

Este tutorial explica como pode usar um fornecedor Google OpenID Connect (OIDC) combinado com uma conta de serviço para atuar como uma identidade de terceiros. O fornecedor OIDC de Contas Google atua como um fornecedor de identidade (IDP) de terceiros e a Google Cloud conta de serviço é uma identidade de terceiros de exemplo afirmada por este IDP.

Os Workload Identity Pools suportam uma variedade de fornecedores de identidades, incluindo o Microsoft Azure/On-premises Active Directory, a AWS e fornecedores de identidades baseados em SAML.

Para configurar um Workload Identity Pool e um fornecedor, faça o seguinte: 1. Para representar um conjunto fidedigno de identidades federadas, crie um Workload Identity Pool:

```
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. Crie um fornecedor do Workload Identity Pool para o seu fornecedor de identidade de terceiros:

    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"
    

    Substitua o seguinte:

    • PROVIDER_ID: o identificador exclusivo do fornecedor de identidade que quer criar no Workload Identity Pool.

    Pode personalizar as seguintes flags de acordo com o seu exemplo de utilização:

    • attribute-mapping: esta flag define o mapeamento entre as reivindicações de terceiros e a reivindicação principal da Google, google.subject. google.subject é um mapeamento obrigatório que pode definir para quaisquer reivindicações ou combinação de reivindicações através de uma expressão CEL. Para mais informações, consulte o artigo Defina um mapeamento de atributos e uma condição.
    • issuer-uri: para fornecedores de OIDC, esta flag é um ponto final acessível publicamente que a Google contacta para validação de tokens de terceiros. Para mais informações, consulte o artigo Preparar um fornecedor de identidades externo.

    Para mais informações sobre a configuração de um fornecedor de identidade de carga de trabalho, consulte o artigo Configurar a federação de identidade de carga de trabalho.

Crie um grupo de ACs e uma AC de emissão

Esta secção explica como pode criar um conjunto de CAs e adicionar-lhe uma CA de raiz. Pode usar este conjunto de ACs para emitir certificados refletidos na identidade. Se quiser usar um conjunto de ACs e uma AC existentes, pode ignorar esta secção.

Em alternativa a uma AC raiz, também pode optar por criar uma AC subordinada. A criação de uma AC raiz ajuda a encurtar o procedimento.

  1. Crie um grupo de ACs no nível DevOps:

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

    Substitua o seguinte:

    • CA_POOL_ID - O ID do conjunto de ACs do serviço de AC que emite certificados.
    • LOCATION: a localização do grupo de ACs.

    Para mais informações sobre a criação de conjuntos de ACs, consulte o artigo Crie um conjunto de ACs.

  2. Crie uma AC de raiz:

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

    Substitua o seguinte:

    • CA_ID - O ID da autoridade de certificação que emite certificados.
    • CA_POOL_ID - O ID do conjunto de ACs do serviço de AC que emite certificados.
    • LOCATION: a localização do grupo de ACs.

    Para mais informações sobre como criar uma CA de raiz, consulte o artigo Crie uma CA de raiz.

  3. Permitir que as identidades federadas a partir do Workload Identity Pool emitam certificados a partir do CA Pool. A reflexão de identidade requer a função de IAM CA Service Workload Certificate Requester (roles/privateca.workloadCertificateRequester) para os requerentes de CreateCertificate.

    Pode representar os principais do Workload Identity Pool em várias granularidades, desde um único assunto a todas as identidades no pool em todos os fornecedores. Para mais informações, consulte os diretores ou os conjuntos de diretores disponíveis (use o separador da CLI Google Cloud) para se adequarem melhor ao seu exemplo de utilização.

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

    Substitua o seguinte:

    • LOCATION: a localização do grupo de ACs
    • PROJECT_ID: o ID do projeto no qual criou o Workload Identity Pool Google Cloud

Crie uma conta de serviço que represente uma identidade de terceiros

O procedimento seguinte pressupõe que uma conta de serviço representa um terceiro. Esta secção mostra como pode usar o ponto final da IAM para obter uma identidade de terceiros sob a forma de um token OIDC.GenerateIdToken Consoante o exemplo de utilização, pode precisar de passos diferentes para obter o token de identidade de terceiros à sua escolha.

gcloud iam service-accounts create SERVICE_ACCOUNT

Substitua o seguinte:

  • SERVICE_ACCOUNT: o ID da conta de serviço que representa a identidade de terceiros.

Emitir um certificado que ateste a identidade de terceiros

Antes de começar, certifique-se de que tem a função IAM de criador de tokens de conta de serviço (roles/iam.serviceAccountTokenCreator). Precisa desta função do IAM para chamar a API GenerateIdToken.

Para obter um certificado que ateste uma identidade de terceiros, faça o seguinte:

  1. Obtenha um token de identidade de terceiros do seu fornecedor de identidade de terceiros.

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

    Substitua o seguinte:

    • PROJECT_ID - O Google Cloud project id do projeto no qual quer criar recursos.

    Bibliotecas cliente

    Para aceder ao token de terceiros de forma programática, pode obter um token a partir de uma credencial de origem de ficheiro ou de uma credencial de origem de URL. Para mais informações, consulte o artigo Autenticação através de bibliotecas de cliente, da CLI gcloud ou do Terraform. Neste tutorial, seguimos um fluxo de trabalho de credenciais de origem de ficheiros.

    Carregue a sua credencial num caminho legível pelo requerente do 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
    

    Substitua o seguinte:

    • PROJECT_ID: o ID do projeto no qual quer criar recursos.
  2. Troque o seu token de terceiros por um token OAuth federado através do ponto final do 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 cliente

    1. Crie um ficheiro de configuração de credenciais denominado oidc_token.txt que o código de pedido de certificado possa ler para realizar uma troca 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. Leia o ficheiro oidc_token.txt para definir o mecanismo de autorização na biblioteca do 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. Faça um pedido ao serviço de AC com o modo de pedido de assunto REFLECTED_SPIFFE:

    curl

    1. Opcional: se não tiver um CSR, crie um executando o seguinte comando.

      export TUTORIAL_CSR=$(openssl req -newkey rsa:2048 -nodes -subj / -keyout tutorial_do_not_use.key)
      
    2. Peça um certificado com o CSR, uma duração e um modo de pedido de assunto refletido:

      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 cliente

    Para encaminhar o token original para o serviço de CA, tem de criar um cliente com credenciais. Em seguida, pode usar este cliente com credenciais para fazer pedidos de certificados:

    1. Inicie um cliente do serviço de AC com credenciais:

      python

      caServiceClient = privateca_v1.CertificateAuthorityServiceClient(credentials=scoped_credentials)
      
    2. Peça um certificado.

      Python

      Para se autenticar no serviço de AC, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento 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. Valide o certificado. O seu certificado deve ter um assunto que contenha um único SAN URI. O SAN que atesta uma identidade está no seguinte formato:

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

      Substituir:

      • IDENTITY_POOL_ID: o identificador exclusivo do Workload Identity Pool.
      • PROJECT_NUMBER - O número do projeto no qual criou o Workload Identity Pool.

Limpar

Para evitar incorrer em cobranças na sua Google Cloud conta pelos recursos do serviço de AC criados de acordo com este documento, execute as seguintes operações através da CLI do Google Cloud:

  1. Elimine a CA que criou.

    1. Desative a AC:

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

      Substituir:

      • CA_ID: o identificador exclusivo da AC.
      • CA_POOL_ID: o identificador exclusivo do conjunto de ACs.
      • LOCATION: A localização do grupo de ACs.
    2. Elimine a CA:

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

      Substituir:

      • CA_ID: o identificador exclusivo da AC.
      • CA_POOL_ID: o identificador exclusivo do conjunto de ACs.
      • LOCATION: A localização do grupo de ACs.
  2. Elimine o conjunto de CA que criou.

    gcloud privateca pools delete CA_POOL_ID --location LOCATION
    

    Substituir:

    • CA_POOL_ID: o identificador exclusivo do conjunto de ACs.
    • LOCATION: A localização do grupo de ACs.

    Para mais informações sobre o comando gcloud privateca pools delete, consulte gcloud privateca pools delete.

  3. Elimine o Workload Identity Pool que criou:

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

    Substituição:

    • IDENTITY_POOL_ID: o identificador exclusivo do Workload Identity Pool.
  4. Elimine a conta de serviço que criou:

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

    Substituir:

    • SERVICE_ACCOUNT: o identificador exclusivo do Workload Identity Pool.
    • PROJECT_ID: o projeto proprietário da conta de serviço.

A função do IAM de requerente de certificado do serviço de AC (privateca.workloadCertificateRequester) restringe o assunto do certificado emitido apenas à identidade do requerente. Certifique-se de que os utilizadores ou as cargas de trabalho que usam a funcionalidade de reflexão de identidade só têm a função do IAM (privateca.workloadCertificateRequester) de requerente de certificado de carga de trabalho do serviço de AC. Para agir de acordo com o princípio do menor privilégio, pode evitar conceder a função de IAM CA Service Certificate Requester (privateca.certificateRequester).

O que se segue?