Como criar e ativar contas de serviço para instâncias

Os aplicativos sendo executados nas suas instâncias podem autorizar e interagir com as APIs do Google Cloud por meio de uma conta de serviço. Quando as contas têm os papéis de IAM do Compute Engine necessários, é possível executar solicitações de API específicas no código do aplicativo.

Para saber mais sobre contas de serviço, leia a visão geral.

Antes de começar

Como criar uma conta de serviço

É possível criar e configurar uma nova conta de serviço usando o IAM. Depois de criar uma conta, conceda a ela um ou mais papéis do IAM. Em seguida, autorize a execução de uma instância de máquina virtual como essa conta de serviço.

Para criar uma nova conta de serviço:

  1. Crie uma nova conta de serviço conforme descrito nesta página.

  2. Consiga o e-mail da conta de serviço. Você precisa dele para configurar uma instância para ser executada como essa conta de serviço. Verifique o e-mail da conta de serviço no Console:

    1. Acesse a página Contas de serviço no Console do Cloud.

      Acessar a página "Contas de serviço"

    2. Se solicitado, selecione um projeto.
    3. Procure a nova conta de serviço e anote o e-mail da conta de serviço.

    Normalmente, o e-mail da conta de serviço é derivado do ID dela com este formato:

    [SERVICE-ACCOUNT-NAME]@[PROJECT_ID].iam.gserviceaccount.com
    
  3. Conceda papéis do IAM à conta de serviço. Se você não conceder papéis, a conta de serviço não terá acesso a nenhum serviço. Para acessar uma lista completa de papéis do IAM, consulte Noções básicas sobre papéis na documentação do IAM.

  4. Em seguida, configure uma instância para ser executada como uma conta de serviço. Siga as instruções relacionadas.

Como configurar uma nova instância para ser executada como conta de serviço

Depois de criar uma nova conta de serviço, crie novas instâncias de máquina virtual para serem executadas como a conta de serviço. Se quiser atribuir ou alterar uma conta de serviço em uma instância atual, consulte Como alterar a conta de serviço e os escopos de acesso de uma instância.

Você pode ativar várias instâncias de máquina virtual para usar a mesma conta de serviço, mas uma instância de máquina virtual só pode ter uma identidade de conta de serviço. Se você atribuir a mesma conta de serviço a várias instâncias de máquinas virtuais, alterações subsequentes feitas na conta de serviço afetarão as instâncias que usam a conta de serviço. Isso inclui quaisquer alterações feitas nas funções do IAM concedidas à conta de serviço. Por exemplo, se você remover um papel, todas as instâncias que usam a conta de serviço perderão as permissões concedidas por aquele papel.

Geralmente, é possível definir apenas o escopo de acesso cloud-platform para permitir acesso total a todas as APIs do Cloud e, em seguida, conceder à conta de serviço apenas papéis relevantes do IAM. A combinação de escopos de acesso concedidos à instância de máquina virtual e os papéis do IAM atribuídos à conta de serviço determinam a quantidade de acesso que a conta de serviço tem nessa instância. A conta de serviço poderá executar métodos de API somente se eles tiverem permissão do escopo de acesso e do papel do IAM.

Também é possível definir escopos específicos que autorizem o acesso aos métodos de API específicos que serão chamados pelo serviço. Por exemplo, para chamar o método instances.insert, você precisa de autorização com os escopos https://www.googleapis.com/auth/compute ou https://www.googleapis.com/auth/cloud-platform e de um papel do IAM que conceda acesso a esse método. É possível definir o escopo compute em vez de cloud-platform. Isso dá autorização ao serviço para chamar métodos no Compute Engine, mas não para chamar métodos de API fora dele.

É possível configurar uma nova instância para ser executada como uma conta de serviço por meio do Console do Google Cloud, da ferramenta de linha de comando gcloud ou diretamente por meio da API.

Console

  1. No Console do Cloud, acesse a página Instâncias de VM.

    Acessar instâncias de VM

  2. Clique em Criar instância.
  3. Na página Criar uma nova instância, preencha as propriedades da sua instância.
  4. Na seção Identidade e acesso à API, selecione na lista suspensa a conta de serviço que você quer usar.
  5. Clique em Criar para criar a instância.

gcloud

Para criar uma nova instância e permitir que ela seja executada como conta de serviço personalizada por meio da ferramenta de linha de comando gcloud, forneça o e-mail da conta de serviço e os escopos de acesso pretendidos para a instância.

gcloud compute instances create [INSTANCE_NAME] \
    --service-account [SERVICE_ACCOUNT_EMAIL] \
    --scopes [SCOPES,...]

em que:

  • [SERVICE_ACCOUNT_EMAIL] é o e-mail da conta de serviço que você quer usar. Por exemplo, my-sa-123@my-project-123.iam.gserviceaccount.com. Se você não sabe qual é o e-mail, veja como consegui-lo;
  • [INSTANCE_NAME] é o nome da instância;
  • [SCOPES] é uma lista separada por vírgulas de todos os URIs de escopo ou aliases de escopo fornecidos na descrição da sinalização --scopes.

Exemplo:

gcloud compute instances create example-vm \
    --service-account 123-my-sa@my-project-123.iam.gserviceaccount.com \
    --scopes https://www.googleapis.com/auth/cloud-platform

A ferramenta gcloud também oferece aliases de escopo em vez de URIs de escopo mais longos. Por exemplo, o escopo para acesso total ao Cloud Storage é https://www.googleapis.com/auth/devstorage.full_control. O alias desse escopo é storage-full.

Veja uma lista de escopos e aliases de escopo na descrição da sinalização --scopes da página instances create. A ajuda do comando instances create também lista estes escopos e aliases:

gcloud compute instances create --help

Especifique o alias da mesma maneira que você determina o URI de escopo normal. Por exemplo:

gcloud compute instances create [INSTANCE_NAME] \
    --service-account [SERVICE_ACCOUNT_EMAIL] \
    --scopes cloud-platform

API

Na API, faça uma solicitação padrão para criar uma instância, mas inclua a propriedade serviceAccounts. Consiga o e-mail da conta de serviço e inclua-o na propriedade email com os escopos de acesso pretendidos para a instância.

POST https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances

{
  "machineType": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/machineTypes/[MACHINE_TYPE]",
  "name": "[INSTANCE_NAME]",
  "serviceAccounts": [
   {
    "email": "[SERVICE_ACCOUNT_EMAIL]",
    "scopes": ["https://www.googleapis.com/auth/cloud-platform"]
   }
  ],
  ...
}

Depois de definir uma instância para executar como a conta de serviço, será possível usar as credenciais da conta de serviço de dentro da instância de várias formas:

Como autenticar aplicativos usando credenciais da conta de serviço

Depois de configurar uma instância para executar como uma conta de serviço, você poderá usar as credenciais da conta de serviço para autenticar aplicativos em execução na instância.

Como autenticar aplicativos com uma biblioteca de cliente

As bibliotecas de cliente podem usar o Application Default Credentials para fazer a autenticação com as APIs do Google e enviar solicitações a elas. Com o Application Default Credentials, os aplicativos conseguem credenciais de várias fontes. Assim, você testa os aplicativos no local e os implanta em uma instância do Compute Engine sem alterar o código deles. Ao desenvolver o aplicativo localmente, é possível autenticá-lo por meio de uma variável de ambiente ou do SDK do Cloud. Quando o aplicativo é executado em uma instância, é possível autenticá-lo por meio da conta de serviço que foi ativada na instância.

Neste exemplo, a Biblioteca de cliente Python é usada para autenticar e fazer uma solicitação à API do Cloud Storage para listar os buckets em um projeto. Este é o procedimento seguido:

  1. Consiga as credenciais de autenticação necessárias para a API do Cloud Storage e inicie o serviço do produto com o método build() e as credenciais.
  2. Liste os buckets no Cloud Storage.

Execute esta amostra em uma instância que tenha acesso para gerenciar buckets no Cloud Storage.


import argparse

import googleapiclient.discovery

def create_service():
    # Construct the service object for interacting with the Cloud Storage API -
    # the 'storage' service, at version 'v1'.
    # Authentication is provided by application default credentials.
    # When running locally, these are available after running
    # `gcloud auth application-default login`. When running on Compute
    # Engine, these are available from the environment.
    return googleapiclient.discovery.build('storage', 'v1')

def list_buckets(service, project_id):
    buckets = service.buckets().list(project=project_id).execute()
    return buckets

def main(project_id):
    service = create_service()
    buckets = list_buckets(service, project_id)
    print(buckets)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('project_id', help='Your Google Cloud Project ID.')

    args = parser.parse_args()

    main(args.project_id)

Como autenticar aplicativos diretamente com tokens de acesso

Em alguns aplicativos, talvez seja necessário solicitar um token de acesso OAuth2 e usá-lo diretamente sem uma biblioteca de cliente ou as ferramentas gcloud ou gsutil. Há várias opções para conseguir e usar esses tokens de acesso para autenticar os aplicativos. Por exemplo, use o curl para criar uma solicitação simples ou utilize uma linguagem de programação como o Python para ter mais flexibilidade.

cURL

Para usar o curl para solicitar um token de acesso e enviar uma solicitação a uma API:

  1. Na instância em que o aplicativo é executado, consulte o servidor de metadados para conseguir um token de acesso. Basta executar o comando a seguir:

    $ curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
    -H "Metadata-Flavor: Google"

    A solicitação retorna uma resposta assim:

    {
          "access_token":"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_QtAS08i85nHq39HE3C2LTrCARA",
          "expires_in":3599,
          "token_type":"Bearer"
     }
  2. Copie o valor da propriedade access_token da resposta e use-o para enviar solicitações para a API. Por exemplo, a solicitação a seguir imprime uma lista de instâncias no projeto a partir de uma determinada zona:

    $ curl https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances \
    -H "Authorization":"Bearer [ACCESS_TOKEN]"
    

    em que:

    • [PROJECT_ID] é o ID do projeto da solicitação;
    • [ZONE] é a zona das instâncias que serão listadas;
    • [ACCESS_TOKEN] é o valor do token de acesso conseguido na primeira etapa.

    Para mais informações sobre os parâmetros que podem ser definidos na solicitação, consulte a documentação relacionada.

Python

Veja neste exemplo como solicitar um token para acessar a API Cloud Storage em um aplicativo Python. Este é o procedimento seguido:

  1. Solicite um token de acesso do servidor de metadados.
  2. Extraia o token de acesso da resposta do servidor.
  3. Use o token de acesso para fazer uma solicitação ao Cloud Storage.
  4. Se a solicitação for bem-sucedida, o script imprimirá a resposta.

import argparse

import requests

METADATA_URL = 'http://metadata.google.internal/computeMetadata/v1/'
METADATA_HEADERS = {'Metadata-Flavor': 'Google'}
SERVICE_ACCOUNT = 'default'

def get_access_token():
    url = '{}instance/service-accounts/{}/token'.format(
        METADATA_URL, SERVICE_ACCOUNT)

    # Request an access token from the metadata server.
    r = requests.get(url, headers=METADATA_HEADERS)
    r.raise_for_status()

    # Extract the access token from the response.
    access_token = r.json()['access_token']

    return access_token

def list_buckets(project_id, access_token):
    url = 'https://www.googleapis.com/storage/v1/b'
    params = {
        'project': project_id
    }
    headers = {
        'Authorization': 'Bearer {}'.format(access_token)
    }

    r = requests.get(url, params=params, headers=headers)
    r.raise_for_status()

    return r.json()

def main(project_id):
    access_token = get_access_token()
    buckets = list_buckets(project_id, access_token)
    print(buckets)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument('project_id', help='Your Google Cloud project ID.')

    args = parser.parse_args()

    main(args.project_id)

Os tokens de acesso expiram depois de um período curto. O servidor de metadados armazena em cache os tokens de acesso até que tenham 60 segundos de tempo remanescente antes que expirem. Você pode solicitar novos tokens com a frequência que quiser, mas os aplicativos precisam ter um token de acesso válido para que as chamadas da API tenham êxito.

Como autenticar ferramentas em uma instância usando uma conta de serviço

Alguns aplicativos podem usar comandos das ferramentas gcloud e gsutil, que estão incluídas por padrão na maioria das imagens do Compute Engine. Essas ferramentas reconhecem automaticamente a conta de serviço de uma instância e as permissões relevantes concedidas a ela. Especificamente, se você conceder os papéis corretos à conta de serviço, será possível usar as ferramentas gcloud e gsutil das instâncias sem precisar utilizar gcloud auth login.

Esse reconhecimento da conta de serviço acontece automaticamente e aplica-se somente às ferramentas gcloud e gsutil que estão incluídas na instância. Se você criar novas ferramentas ou adicionar outras personalizadas, será necessário autorizar o aplicativo usando uma biblioteca de cliente ou tokens de acesso diretamente no aplicativo.

Para aproveitar o reconhecimento automático da conta de serviço, conceda os papéis do IAM apropriados à conta de serviço e configure uma instância para ser executada como conta de serviço. Por exemplo, se você conceder o papel roles/storage.objectAdmin a uma conta de serviço, a ferramenta gsutil poderá gerenciar e acessar objetos do Cloud Storage automaticamente.

Da mesma forma, se você ativar roles/compute.instanceAdmin.v1 na conta de serviço, a ferramenta gcloud compute poderá gerenciar instâncias automaticamente.

Como alterar a conta de serviço e os escopos de acesso de uma instância

Se você quiser executar a VM como uma identidade diferente ou se determinar que a instância precisa de um conjunto de escopos diferente para chamar as APIs necessárias, é possível alterar a conta de serviço e os escopos de acesso de uma instância existente. Por exemplo, é possível alterar os escopos de acesso para conceder acesso a uma nova API ou modificar uma instância para que ela seja executada como uma conta de serviço que você criou, em vez da conta de serviço padrão do Compute Engine.

Para alterar a conta de serviço e os escopos de acesso de uma instância, você precisa interromper a instância temporariamente. Para parar a instância, leia a documentação sobre Parar uma instância. Depois de alterar a conta de serviço ou os escopos de acesso, lembre-se de reiniciar a instância. Use um dos seguintes métodos para alterar a conta de serviço ou os escopos de acesso da instância parada.

Console

  1. Acesse a página "Instâncias de VM" no Compute Engine.

    Acessar a página "Instâncias de VM"

  2. Clique no nome da instância de VM para que você quer alterar a conta de serviço.
  3. Se a instância não estiver parada, clique no botão Parar. Espere até que a instância seja parada.
  4. Em seguida, clique no botão Editar.
  5. Role para baixo até a seção Conta de serviço.
  6. No menu suspenso, selecione a conta de serviço desejada.
  7. Para alterar os escopos, na seção Escopos de acesso, defina os que são apropriados às suas necessidades. Como prática recomendada, especifique apenas os necessários à sua instância de VM. Se não tiver certeza de quais definir, escolha Permitir acesso total a todas as APIs do Cloud e restrinja o acesso definindo os papéis do IAM.
  8. Clique no botão Salvar para salvar as alterações.

gcloud

Use o comando instances set-service-account e forneça o nome da instância, o e-mail da conta de serviço e os escopos pretendidos. Também é possível remover a conta de serviço e escopos de acesso de uma instância, impedindo que a instância acesse os serviços do Google Cloud:

gcloud compute instances set-service-account [INSTANCE_NAME] \
   [--service-account [SERVICE_ACCOUNT_EMAIL] | --no-service-account] \
   [--no-scopes | --scopes [SCOPES,...]]

em que:

  • [SERVICE_ACCOUNT_EMAIL] é o e-mail da conta de serviço que você quer usar. Por exemplo, my-sa-123@my-project-123.iam.gserviceaccount.com.
  • [INSTANCE_NAME] é o nome da instância;
  • [SCOPES] é uma lista separada por vírgulas de todos os URIs de escopo ou aliases de escopo fornecidos na descrição da sinalização --scopes. Se você quer remover todos os escopos da instância, use a sinalização --no-scopes.

Por exemplo, com o comando a seguir, você atribui a conta de serviço my-sa-123@my-project-123.iam.gserviceaccount.com a uma instância chamada "example-instance". Além disso, você define escopos de acesso nessa instância para permitir o acesso de leitura/gravação ao Compute Engine e o acesso somente leitura ao Cloud Storage:

gcloud compute instances set-service-account example-instance \
   --service-account my-sa-123@my-project-123.iam.gserviceaccount.com \
   --scopes compute-rw,storage-ro

API

Na API, faça uma solicitação POST para o método setServiceAccount:

https://compute.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/instances/[INSTANCE_NAME]/setServiceAccount

em que:

  • [PROJECT_ID] é o ID do projeto da solicitação;
  • [ZONE] é a zona a que essa instância pertence;
  • [INSTANCE_NAME] é o nome da instância.

No corpo da solicitação, forneça o endereço de e-mail da conta de serviço e os URIs do escopo pretendido para a instância.

{
  "email": "[SERVICE_ACCOUNT_EMAIL]",
  "scopes": [
    "[SCOPE_URI]",
    "[SCOPE_URI]",
    ...
  ]
}

Por exemplo, na solicitação a seguir, o e-mail da conta de serviço my-sa-123@my-project-123.iam.gserviceaccount.com é usado, e um escopo do Cloud Storage e do BigQuery é definido:

{
  "email": "my-sa-123@my-project-123.iam.gserviceaccount.com",
  "scopes": [
    "https://www.googleapis.com/auth/bigquery",
    "https://www.googleapis.com/auth/devstorage.read_only"
  ]
}

Como conseguir o e-mail de uma conta de serviço

Para identificar uma conta de serviço, você precisa do e-mail da conta de serviço. Consiga o e-mail de uma conta de serviço com uma das seguintes opções:

Console

  1. Acesse a página Contas de serviço no Console do Cloud.

    Acessar a página "Contas de serviço"

  2. Se solicitado, selecione um projeto. A página de contas de serviço lista todas as contas de serviço do projeto e seus e-mails.

gcloud

Use o comando gcloud compute instances describe no computador local:

gcloud compute instances describe [INSTANCE_NAME] --format json
{
      ...
      "serviceAccounts":[
         {
            "email":"123845678986-compute@developer.gserviceaccount.com",
            "scopes":[
               "https://www.googleapis.com/auth/devstorage.full_control"
            ]
         }
      ]
      ...
   }

Se a instância não estiver usando uma conta de serviço, você receberá uma resposta sem a propriedade serviceAccounts.

Servidor de metadados

Consulte o servidor de metadados de dentro da própria instância. Faça uma solicitação para http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/:

user@myinst:~$ curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/" \
-H "Metadata-Flavor: Google"

Se você ativou uma ou mais contas de serviço ao criar a instância, o comando curl retornará uma saída como esta:

123845678986-compute@developer.gserviceaccount.com/
default/

Se a instância não estiver usando uma conta de serviço, você receberá uma resposta vazia.

API

Faça uma solicitação à API Service Accounts.

Como usar a conta de serviço padrão do Compute Engine

Se você está familiarizado com a conta de serviço padrão do Compute Engine e quer usar as credenciais fornecidas por ela, em vez de criar novas contas de serviço, poderá conceder funções do IAM para a conta de serviço padrão.

Por padrão, todas as instâncias do Compute Engine podem executar como a conta de serviço padrão. Ao criar uma instância usando a ferramenta de linha de comando gcloud ou o Console do Cloud e omitindo especificações da conta de serviço, a conta de serviço padrão é atribuída à instância.

Antes de atribuir papéis do IAM à conta de serviço padrão, observe o seguinte:

  • Conceder um papel do IAM à conta de serviço padrão afeta todas as instâncias que estão sendo executadas como a conta de serviço padrão. Por exemplo, se você conceder o papel roles/storage.objectAdmin à conta de serviço padrão, todas as instâncias em execução como a conta de serviço padrão com os escopos de acesso necessários terão as permissões concedidas pelo papel roles/storage.objectAdmin. Da mesma forma, se você limitar o acesso omitindo determinados papéis, isso afetará todas as instâncias que estão sendo executadas como a conta de serviço padrão.

  • Você precisa revogar a permissão do editor de projeto para a conta de serviço. Por padrão, a conta de serviço padrão é adicionada como um editor de projeto aos projetos. Para usar os papéis do IAM, você precisa revogar a permissão de editor de projeto.

Se não tiver certeza sobre a atribuição de papéis do IAM para a conta de serviço padrão, crie uma nova conta de serviço.

Siga estas instruções para conceder um papel do IAM à conta de serviço padrão:

  1. Acesse a página IAM no Console do Google Cloud:

    Acessar a página "IAM"

  2. Se solicitado, selecione um projeto.
  3. Procure a conta de serviço chamada Conta de serviço padrão do Compute Engine.
  4. Na coluna Funções, expanda o menu suspenso da Conta de serviço padrão do Compute Engine.
  5. Remova o acesso de editor e salve as alterações.
  6. Em seguida, conceda papéis do IAM à conta de serviço.

Agora todas as instâncias de máquina virtual que estiverem sendo executadas como conta de serviço padrão terão acesso a outras APIs do Google Cloud de acordo com os papéis do IAM que você concedeu à conta.

Se você quiser configurar uma nova instância para ser executada como conta de serviço padrão, siga estas instruções:

Console

  1. No Console do Cloud, acesse a página Instâncias de VM.

    Acessar instâncias de VM

  2. Clique em Criar instância.
  3. Na página Criar uma nova instância, preencha as propriedades da sua instância.
  4. Na seção Identidade e acesso à API, selecione a Conta de serviço padrão do Compute Engine na lista suspensa.
  5. Clique em Criar para criar a instância.

gcloud

Para criar uma nova instância e autorizá-la a ter acesso total a todos os serviços do Google Cloud usando a conta de serviço padrão:

gcloud compute instances create [INSTANCE_NAME] \
     --scopes cloud-platform

API

Na API, faça uma solicitação padrão para criar uma instância, mas inclua a propriedade serviceAccounts. Consiga o ID da conta de serviço padrão e inclua-o como email da conta de serviço. Em seguida, defina um ou mais escopos na propriedade scopes.

POST https://compute.googleapis.com/compute/v1/projects/zones/[ZONE]/instances

{
  "machineType": "https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/zones/[ZONE]/machineTypes/[MACHINE_TYPE]",
  "name": "[INSTANCE_NAME]",
  "serviceAccounts": [
   {
    "email": "[DEFAULT_SERVICE_ACCOUNT_EMAIL]",
    "scopes": ["https://www.googleapis.com/auth/cloud-platform"]
   }
  ],
  ...
}

Práticas recomendadas

Em geral, o Google recomenda que cada instância que precisa chamar uma API do Google seja executada como uma conta de serviço com as permissões mínimas necessárias para que a instância faça seu trabalho. Na prática, isso significa que você precisa configurar contas de serviço para as instâncias com o seguinte processo:

  1. Crie uma nova conta de serviço em vez de usar a conta de serviço padrão do Compute Engine.
  2. Conceda papéis do IAM a essa conta de serviço apenas para os recursos de que ela precisa.
  3. Configure a instância para executar como essa conta de serviço.
  4. Conceda à instância o escopo https://www.googleapis.com/auth/cloud-platform para permitir o acesso total a todas as APIs do Google Cloud. Assim, as permissões do IAM da instância serão completamente determinadas pelos papéis do IAM que você concedeu ao serviço da instância. conta. A conta de serviço só pode executar métodos de API permitidos pelo escopo de acesso e pelos papéis específicos do IAM da conta de serviço.

Evite conceder mais acesso do que o necessário e verifique regularmente as permissões da conta de serviço para garantir que estejam atualizadas.

Exclua as contas de serviço com cuidado. Verifique se os aplicativos críticos não estão mais usando uma conta de serviço antes de excluí-la. Se você não tiver certeza se uma conta de serviço está sendo usada, recomendamos desativar a conta de serviço em vez de excluí-la. As contas de serviço desativadas poderão ser reativadas se ainda forem necessárias.

A seguir