Como criar credenciais de conta de serviço de curta duração

Nesta página, explicamos como criar credenciais de curta duração para representar as identidades das contas de serviço.

As contas de serviço podem usar credenciais de curta duração para autenticar chamadas a APIs do Google Cloud e outras APIs que não são do Google. As credenciais de curta duração têm uma vida útil limitada, com durações de apenas algumas horas ou menos. Elas são úteis em cenários onde é preciso conceder acesso limitado a recursos de contas de serviço confiáveis, além de reduzirem o risco de comparação com o uso de credenciais de longa duração, como chaves de conta de serviço.

Os tipos de credenciais aceitos incluem tokens de acesso do OAuth 2.0, tokens de ID do OpenID Connect, JSON Web Tokens (JWTs) autoassinados e objetos binários autoassinados (blobs). Os tipos de credenciais mais usados são os tokens de acesso do OAuth 2.0 e os tokens de ID do OpenID Connect (OIDC). Alguns cenários de exemplo:

  • Token de acesso do OAuth 2.0: um token de acesso do OAuth 2.0 é útil para autenticar a identidade de uma conta de serviço nas APIs do Google Cloud. Considere o exemplo de caso de uso a seguir: para receber permissões elevadas em um projeto, um administrador de serviço pode personificar uma conta de serviço para chamar APIs do Google Cloud criando um token de acesso do OAuth 2.0 pertencente a essa conta de serviço. O token tem uma vida útil curta, por isso as permissões elevadas são temporárias. Isso é útil especialmente quando há uma emergência em um ambiente de produção, e um administrador de serviço precisa de uma autorização elevada de curto prazo para depuração.

  • Token de ID do OIDC: útil para autenticar a identidade de uma conta de serviço nos serviços que aceitam o OpenID Connect. Considere o seguinte caso de uso de exemplo: ao criar um token de ID OIDC pertencente a uma conta de serviço, um serviço em execução no Google Cloud pode se autenticar em outro serviço implantado em um provedor de nuvem terceirizado, como um job de pipeline de dados. Se o serviço de destino estiver configurado com OIDC, a autenticação será bem-sucedida.

Antes de começar

Criar uma conta de serviço

Para começar, crie uma nova conta de serviço.

Como conceder as permissões exigidas

Há dois fluxos diferentes que permitem que o autor da chamada crie credenciais de curta duração para uma conta de serviço. Cada fluxo requer as permissões adequadas:

  • Solicitação direta: o autor da chamada é autenticado como uma Conta do Google ou uma conta de serviço e faz uma solicitação direta para criar credenciais de curta duração. Duas identidades estão envolvidas nesse fluxo: o autor da chamada e a conta de serviço para quem a credencial é criada.
  • Solicitação delegada: o autor da chamada é autenticado como uma Conta do Google ou uma conta de serviço, mas delega a solicitação a uma ou mais contas de serviço em uma cadeia de delegação. Nesse fluxo, várias contas de serviço atuam como intermediárias entre o autor da chamada original e a conta de serviço para que a credencial é criada. Cada conta de serviço na cadeia de delegação precisa ter as permissões exigidas para passar a solicitação.

    Esse fluxo é útil em cenários onde um projeto contém camadas de contas de serviço com privilégios limitados, cada uma configurada para realizar uma função específica ou limitada em determinados recursos. Por exemplo, uma conta de serviço só recebe permissões para recursos do Cloud Storage, outra só recebe permissões para recursos do Compute Engine e assim por diante. Para delegar com êxito uma solicitação nas contas de serviço, cada uma precisa constar da cadeia de delegação.

Permissões de solicitação direta

Conforme descrito acima, uma solicitação direta envolve apenas duas identidades: o autor da chamada e a conta de serviço para quem a credencial é criada. Nesse fluxo, considere as seguintes identidades:

  • Conta de serviço 1 (SA-1, na sigla em inglês), o autor da chamada que emite uma solicitação para as credenciais de curta duração.
  • Conta de serviço 2 (SA-2), a conta de privilégios limitados para que a credencial é criada.

Para conceder a SA-1 permissões para criar credenciais de curta duração, conceda a ela o papel Criador do token da conta de serviço (roles/iam.serviceAccountTokenCreator) em SA-2. Esse é um exemplo em que uma conta de serviço é tratada como um recurso em vez de uma identidade: SA-1 precisa receber permissão para emitir credenciais para SA-2. Para mais informações sobre como tratar contas de serviço como identidade ou recurso, consulte Permissões da conta de serviço.

As etapas a seguir usam a API REST para conceder as permissões exigidas, mas também é possível usar o Console do Cloud ou a ferramenta de linha de comando gcloud.

API

Primeiro, consiga a política do Cloud IAM para SA-2. Consulte a referência serviceAccounts.getIamPolicy() para mais informações.

Nos snippets de código abaixo, SA-2@PROJECT- ID.iam.gserviceaccount.com representa SA-2 e SA-1@PROJECT-ID.iam.gserviceaccount.com representa SA-1, que é o autor da chamada que está solicitando credenciais de curta duração.

Observe que todas as solicitações a essa API usam um hífen (.../projects/-/serviceAccounts...) como caractere curinga do ID do projeto na primeira parte do URL.

Solicitação:

    POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/SA-2@PROJECT-ID.iam.gserviceaccount.com:getIamPolicy
    

Saída:

    {
      "etag": "BwUqLaVeua8=",
      "bindings": [
        {
          "role": "roles/iam.serviceAccountUser",
          "members": [
              "user:alice@example.com"
          ]
        }
      ]
    }
    

Se você não atribuiu um papel à conta de serviço, a resposta conterá apenas um valor de etag:

    {
      "etag": "ACAB"
    }
    

O valor de ETag recebido na etapa acima deve ser incluído na próxima etapa, seja BwUqLaVeua8= ou ACAB. Em seguida, crie uma política para conceder a SA-1 o papel Criador do token da conta de serviço (roles/iam.serviceAccountTokenCreator):

    {
        "policy":
        {
            "etag": "BwUqLaVeua8=",
            "bindings": [
            {
                "role": "roles/iam.serviceAccountUser",
                "members": [
                    "user:alice@example.com"
                ]
            },
            {
                "role": "roles/iam.serviceAccountTokenCreator",
                "members": [
                    "serviceAccount:SA-1@PROJECT-ID.iam.gserviceaccount.com"
                ]
            },
            ]
        },
    }
    

Para atualizar a política, faça uma solicitação serviceAccounts.setIamPolicy() contendo a política atualizada no corpo:

    POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/SA-2@PROJECT-ID.iam.gserviceaccount.com:setIamPolicy
    

A resposta contém a política atualizada:

    {
        "etag": "BwUqMqbViM8=",
        "bindings": [
          {
            "role": "roles/iam.serviceAccountUser",
            "members": [
                "user:alice@example.com"
            ]
          },
          {
            "role": "roles/iam.serviceAccountTokenCreator",
            "members": [
                "serviceAccount:SA-1@PROJECT-ID.iam.gserviceaccount.com"
            ]
          }
        ]
    }
    

Permissões de solicitação delegada

Como descrito acima, uma solicitação delegada envolve mais de duas identidades: o autor da chamada, uma ou mais contas de serviço em uma cadeia de delegação e, finalmente, a conta de serviço. Nesse fluxo, considere as seguintes identidades:

  • Conta de serviço 1 (SA-1, na sigla em inglês), o autor da chamada que emite uma solicitação para as credenciais de curta duração.
  • Conta de serviço 2 (SA-2), uma conta de serviço intermediária que delegará a solicitação inicial a SA-3.
  • Conta de serviço 3 (SA-3), a conta de privilégios limitados para que a credencial é criada.

Para permitir a delegação, cada conta precisa conceder o papel Criador do token da conta de serviço (roles/iam.serviceAccountTokenCreator) à conta anterior na cadeia.

Neste exemplo específico, SA-1 precisa receber o papel Criador de token da conta de serviço (roles/iam.serviceAccountTokenCreator) em SA-2. Trata-se de um exemplo de conta de serviço tratada como um recurso em vez de uma identidade: SA-1 precisa receber permissão para delegar acesso a SA-2. Para mais informações sobre como tratar contas de serviço como identidade ou recurso, consulte Permissões da conta de serviço.

Nesse fluxo de exemplo, há apenas uma conta de serviço intermediária. Para delegar acesso por meio de mais de uma conta de serviço, você também precisa atribuir esse papel a qualquer outra conta de serviço na cadeia.

Em seguida, SA-2 também precisa receber o papel Criador do token da conta de serviço (roles/iam.serviceAccountTokenCreator) em SA-3. Isso permite que SA-2 crie credenciais de curta duração para SA-3.

As etapas a seguir usam a API REST para conceder as permissões exigidas, mas também é possível usar o Console do Cloud ou a ferramenta de linha de comando gcloud.

API

Primeiro, receba a política do Cloud IAM para SA-2 (a conta de serviço intermediária). Consulte a referência serviceAccounts.getIamPolicy() para mais informações.

Nos snippets de código abaixo, SA-2@PROJECT- ID.iam.gserviceaccount.com representa SA-2 e SA-1@PROJECT-ID.iam.gserviceaccount.com representa SA-1, que é o autor da chamada que está solicitando credenciais de curta duração.

Observe que todas as solicitações a essa API usam um hífen (.../projects/-/serviceAccounts...) como caractere curinga do ID do projeto na primeira parte do URL.

Solicitação:

    POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/SA-2@PROJECT-ID.iam.gserviceaccount.com:getIamPolicy
    

Saída:

    {
      "etag": "BwUqLaVeua8=",
      "bindings": [
        {
          "role": "roles/iam.serviceAccountUser",
          "members": [
              "user:alice@example.com"
          ]
        }
      ]
    }
    

Se você não atribuiu um papel à conta de serviço, a resposta conterá apenas um valor de etag:

    {
      "etag": "ACAB"
    }
    

O valor de ETag recebido na etapa acima deve ser incluído na próxima etapa, seja BwUqLaVeua8= ou ACAB. Atualize a política para conceder a SA-2 o papel roles/iam.serviceAccountTokenCreator:

    {
        "policy":
        {
            "etag": "BwUqLaVeua8=",
            "bindings": [
              {
                "role": "roles/iam.serviceAccountUser",
                "members": [
                    "user:alice@example.com"
                ]
              },
              {
                "role": "roles/iam.serviceAccountTokenCreator",
                "members": [
                    "serviceAccount:SA-1@PROJECT-ID.iam.gserviceaccount.com"
                ]
            },
            ]
        },
    }
    

Com a política atualizada, execute uma solicitação serviceAccounts.setIamPolicy():

    POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/SA-2@PROJECT-ID.iam.gserviceaccount.com:setIamPolicy
    

A resposta contém a política atualizada:

    {
        "etag": "BwUqMqbViM8=",
        "bindings": [
        {
            "role": "roles/iam.serviceAccountUser",
            "members": [
                "user:alice@example.com"
            ]
        },
        {
            "role": "roles/iam.serviceAccountTokenCreator",
            "members": [
                "serviceAccount:SA-1@PROJECT-ID.iam.gserviceaccount.com"
            ]
        }
        ]
    }
    

Em seguida, consiga a política do Cloud IAM para SA-3 (conta de serviço para que a credencial é criada).

Solicitação:

    POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/SA-3@PROJECT-ID.iam.gserviceaccount.com:getIamPolicy
    

Saída:

    {
        "etag": "BwUqLaVeua8=",
        "bindings": [
        {
            "role": "roles/iam.serviceAccountUser",
            "members": [
                "user:alice@example.com"
            ]
        }
        ]
    }
    

Se você não atribuiu um papel à conta de serviço, a resposta conterá apenas um valor de etag:

    {
      "etag": "ACAB"
    }
    

O valor de ETag recebido na etapa acima deve ser incluído na próxima etapa, seja BwUqLaVeua8= ou ACAB. Atualize a política para conceder a SA-2 o papel roles/iam.serviceAccountTokenCreator:

    {
        "policy":
        {
            "etag": "BwUqLaVeua8=",
            "bindings": [
            {
                "role": "roles/iam.serviceAccountUser",
                "members": [
                    "user:alice@example.com"
                ]
            },
            {
                "role": "roles/iam.serviceAccountTokenCreator",
                "members": [
                    "serviceAccount:SA-2@PROJECT-ID.iam.gserviceaccount.com"
                ]
            },
            ]
        },
    }
    

Com a política atualizada, execute uma solicitação serviceAccounts.setIamPolicy():

    POST https://iam.googleapis.com/v1/projects/-/serviceAccounts/SA-3@PROJECT-ID.iam.gserviceaccount.com:setIamPolicy
    

A resposta contém a política atualizada:

    {
        "etag": "BwUqMqbViM8=",
        "bindings": [
        {
            "role": "roles/iam.serviceAccountUser",
            "members": [
                "user:alice@example.com"
            ]
        },
        {
            "role": "roles/iam.serviceAccountTokenCreator",
            "members": [
                "serviceAccount:SA-2@PROJECT-ID.iam.gserviceaccount.com"
            ]
        }
        ]
    }
    

Como solicitar credenciais de curta duração

Depois de conceder as devidas permissões para cada identidade, é possível solicitar credenciais de curta duração que pertençam à conta de serviço pretendida. Os seguintes tipos de credenciais são aceitos:

Para entender como especificar uma cadeia de delegação para essas solicitações, consulte a seção Como especificar uma cadeia de delegação abaixo.

Como gerar um token de acesso do OAuth 2.0

Os tokens de acesso do OAuth 2.0 são válidos por 1 hora (ou 3.600 segundos). Para gerar um token de acesso do OAuth 2.0 para uma conta de serviço:

API

Execute uma solicitação generateAccessToken, em que SA-4@PROJECT-ID.iam.gserviceaccount.com é o nome da conta de serviço para que o token será criado.

A solicitação precisa ser autenticada incluindo um token de acesso no cabeçalho Authorization da solicitação. Para mais informações sobre como conseguir um token de acesso para chamar as APIs do Google, consulte os tópicos Visão geral do OAuth 2.0 e OAuth 2.0 para contas de serviço.

    POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA-4@PROJECT-ID.iam.gserviceaccount.com:generateAccessToken
    

Especifique os campos a seguir no corpo da solicitação:

    {
      "delegates": [],
      "scope": [
          "https://www.googleapis.com/auth/cloud-platform"
      ],
      "lifetime": "300s"
    }
    

Cada um desses campos e respectivos valores de exemplo são descritos abaixo:

  • delegates[]: se você estiver usando um fluxo de solicitação delegada, consulte a seção Como especificar uma cadeia de delegação abaixo. Se você estiver usando um fluxo de solicitação direta sem delegação, omita o campo delegates[] no corpo da solicitação.
  • scope: o escopo do OAuth 2.0 para a solicitação. Os escopos a seguir são válidos ao chamar a API generateAccessToken:
    • https://www.googleapis.com/auth/iam
    • https://www.googleapis.com/auth/cloud-platform
    Considere o seguinte exemplo de campo scope:
        ...
        "scope": [
          "https://www.googleapis.com/auth/cloud-platform"
        ]
        ...
        
  • lifetime: duração do token de acesso em segundos. Após esse tempo, o token expira. A vida útil máxima do token é de 1 hora (3.600 segundos).

    Considere o seguinte exemplo de campo lifetime que define a duração do token como 5 minutos:
        ...
        "lifetime": "300s"
        ...
        

Se a solicitação generateAccessToken for bem-sucedida, o corpo da resposta conterá um token de acesso do OAuth 2.0 e um prazo de validade:

    {
       "accessToken": "eyJ0eXAi...NiJ9",
       "expireTime": "2018-05-07T15:01:23.045123456Z"
    }
    

O accessToken poderá ser usado para autenticar uma solicitação em nome da conta de serviço até que o expireTime seja atingido.

Como gerar tokens Connect ID do OpenID

Os tokens de ID do OpenID Connect são válidos por 1 hora (3.600 segundos). Para gerar um token de ID para uma conta de serviço:

API

Execute uma solicitação generateIdToken, em que SA-4@PROJECT-ID.iam.gserviceaccount.com é o nome da conta de serviço para que o token será criado.

A solicitação precisa ser autenticada incluindo um token de acesso no cabeçalho Authorization da solicitação. Para mais informações sobre como conseguir um token de acesso para chamar as APIs do Google, consulte os tópicos Visão geral do OAuth 2.0 e OAuth 2.0 para contas de serviço.

    POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA-4@PROJECT-ID.iam.gserviceaccount.com:generateIdToken
    

Especifique os campos a seguir no corpo da solicitação:

    {
      "delegates": [],
      "audience": "SA-4@PROJECT-ID.iam.gserviceaccount.com",
      "includeEmail": "true"
    }
    

Cada um desses campos e respectivos valores de exemplo são descritos abaixo:

  • delegates[]: se você estiver usando um fluxo de solicitação delegada, consulte a seção Como especificar uma cadeia de delegação abaixo. Se você estiver usando um fluxo de solicitação direta sem delegação, omita o campo delegates[] no corpo da solicitação.
  • audience: o URL de um serviço ou o endereço de e-mail da conta de serviço para que a credencial será criada. Exemplo:
        ...
        "audience": "SA-4@PROJECT-ID.iam.gserviceaccount.com"
        ...
        
  • includeEmail: se definido como true, a declaração email no token de ID incluirá o e-mail da conta de serviço. Além disso, uma declaração email_verified será definida como true e incluída no token de ID. Exemplo:
        ...
        "includeEmail": "true"
        ...
        

Se a solicitação generateIdToken for bem-sucedida, o corpo da resposta conterá um token de ID válido por 1 hora:

    {
       "token": "eyJ0eXAi...NiJ9"
    }
    

O token pode ser usado para autenticar uma solicitação em nome da conta de serviço.

Como criar um JSON Web Token (JWT) autoassinado

Os JWTs autoassinados são úteis em vários cenários, como estes:

  • Autenticação de uma chamada a uma API Google, conforme descrito no Guia de autenticação do Google.
  • Comunicações seguras entre o Google Cloud ou serviços que não são do Google, como aplicativos do App Engine. Nesse cenário, um aplicativo pode assinar um token a ser verificado por outro aplicativo para fins de autenticação.
  • Tratar uma conta de serviço como provedor de identidade assinando um JWT que contenha declarações arbitrárias sobre um usuário, uma conta ou um dispositivo.

Para gerar um JSON Web Token (JWT) autoassinado para uma conta de serviço:

API

Execute uma solicitação signJwt, em que SA-4@PROJECT-ID.iam.gserviceaccount.com é o nome da conta de serviço para a qual o JWT é criado.

A solicitação precisa ser autenticada incluindo um token de acesso no cabeçalho Authorization da solicitação. Para mais informações sobre como conseguir um token de acesso para chamar as APIs do Google, consulte os tópicos Visão geral do OAuth 2.0 e OAuth 2.0 para contas de serviço.

    POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA-4@PROJECT-ID.iam.gserviceaccount.com:signJwt
    

Especifique os campos a seguir no corpo da solicitação:

    {
      "delegates": [],
      "payload": "{ \"iss\": \"SA-4@PROJECT-ID.iam.gserviceaccount.com\", \"sub\": \"SA-4@PROJECT-ID.iam.gserviceaccount.com\", \"aud\": \"https://firestore.googleapis.com/google.firestore.v1beta1.Firestore\", \"iat\": 1529350000, \"exp\": 1529353600 }"
    }
    

Cada um desses campos e respectivos valores de exemplo são descritos abaixo:

  • delegates[]: se você estiver usando um fluxo de solicitação delegada, consulte a seção Como especificar uma cadeia de delegação abaixo. Se você estiver usando um fluxo de solicitação direta sem delegação, omita o campo delegates[] no corpo da solicitação.
  • payload: o payload de JWT a ser assinado, que é um objeto JSON contendo um conjunto de declarações do JWT. Inclua as declarações necessárias para o caso de uso e para atender aos requisitos de validação do serviço downstream. Se você estiver chamando uma API do Google, consulte o Guia de autenticação do Google para saber os requisitos da declaração.

    A declaração exp (prazo de validade) precisa ser definida como, no máximo, 12 horas no futuro. Caso contrário, ela não será validada. Se o JWT for usado para chamar uma API do Google, a declaração exp precisará ser definida como até uma hora.

    O seguinte exemplo de conjunto de declarações contém declarações para chamar uma API do Google com duração máxima de 1 hora (3.600 segundos):

        ...
        "payload": "{ \"iss\": \"SA-4@PROJECT-ID.iam.gserviceaccount.com\", \"sub\": \"SA-4@PROJECT-ID.iam.gserviceaccount.com\", \"aud\": \"https://firestore.googleapis.com/google.firestore.v1beta1.Firestore\", \"iat\": 1529350000, \"exp\": 1529353600 }"
        ...
        

Se a solicitação signJwt for bem-sucedida, o corpo da resposta conterá um JWT assinado e o ID da chave de assinatura que foi usada para assinar o JWT. O token é válido até o prazo de validade especificado na solicitação:

    {
       "keyId": "42ba1e...fc0a"
       "signedJwt": "eyJ0eXAi...NiJ9"
    }
    

O valor signedJwt poderá, então, ser usado como token do portador para autenticar diretamente uma solicitação em nome da conta de serviço.

Como criar um blob autoassinado

Os blobs autoassinados são úteis em cenários em que você precisa transmitir com segurança dados binários arbitrários, geralmente para fins de autenticação. Por exemplo, se você quiser usar um protocolo/tipo de token personalizado (não JWT), inclua esses dados em um blob assinado para uso por um serviço downstream.

Para gerar um blob autoassinado para uma conta de serviço:

API

Execute uma solicitação signBlob, em que SA-4@PROJECT-ID.iam.gserviceaccount.com é o nome da conta de serviço para que o blob é criado.

A solicitação precisa ser autenticada incluindo um token de acesso no cabeçalho Authorization da solicitação. Para mais informações sobre como conseguir um token de acesso para chamar as APIs do Google, consulte os tópicos Visão geral do OAuth 2.0 e OAuth 2.0 para contas de serviço.

    POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA-4@PROJECT-ID.iam.gserviceaccount.com:signBlob
    

Especifique os campos a seguir no corpo da solicitação:

    {
      "delegates": [],
      "payload": "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu"
    }
    

Cada um desses campos e respectivos valores de exemplo são descritos abaixo:

Se a solicitação signBlob for bem-sucedida, o corpo da resposta conterá um blob assinado e o código da chave de assinatura que foi usada para assinar o blob. O token é válido até o prazo de validade especificado na solicitação:

    {
       "keyId": "42ba1e...fc0a"
       "signedBlob": "eyJ0eXAi...NiJ9"
    }
    

Como especificar uma cadeia de delegação

Quando você usa um fluxo de solicitação delegada para criar credenciais de conta de serviço de curta duração, o corpo da solicitação de cada API precisa especificar a cadeia de delegação da conta de serviço na ordem correta e no seguinte formato:

projects/-/serviceAccounts/ACCOUNT-EMAIL-OR-UNIQUEID

Por exemplo, em uma cadeia de delegação que flui de SA-1 (autor da chamada) para SA-2 (delegada) para SA-3 (delegada) para SA-4, o campo delegates[] conterá SA-2 e SA-3 na seguinte ordem:

    ...
    "delegates": [
        "projects/-/serviceAccounts/SA-2@PROJECT-ID.iam.gserviceaccount.com",
        "projects/-/serviceAccounts/SA-3@PROJECT-ID.iam.gserviceaccount.com"
    ],
    ...
    

O autor da chamada e a conta de serviço para que a credencial é criada não são incluídos na cadeia de delegação.