Antes de enviar informações confidenciais a uma instância de máquina virtual (VM, na sigla em inglês), o aplicativo pode verificar a identidade da instância usando tokens de identidade da instância assinados pelo Google. Cada instância tem um JSON Web Token (JWT) exclusivo que inclui detalhes sobre ela, bem como a assinatura RS256 do Google. Seus aplicativos podem verificar a assinatura dos certificados OAuth2 públicos do Google para confirmar a identidade da instância com que estabeleceram uma conexão.
O Compute Engine gera tokens assinados somente quando uma instância os solicita a partir dos metadados dela. Uma instância só pode acessar o próprio token exclusivo, e não os de outras instâncias.
Verifique as identidades das suas instâncias nos seguintes cenários:
- Quando a instância é iniciada pela primeira vez, os aplicativos podem precisar confirmar se a identidade dela é válida antes de transmitirem informações confidenciais para a instância.
- Quando as políticas exigem o armazenamento das credenciais fora do ambiente do Compute Engine, e você as envia regularmente às instâncias para uso temporário. Os aplicativos podem confirmar a identidade das instâncias sempre que precisarem transmitir credenciais.
Os métodos de autenticação de instâncias do Google têm os seguintes benefícios:
- O Compute Engine cria um token exclusivo sempre que uma instância o solicita. Cada token expira em até uma hora. É possível configurar seus aplicativos para aceitarem um token de identidade somente uma vez. Isso reduz o risco de que o token seja reutilizado por um sistema não autorizado.
- Os tokens de metadados assinados usam o padrão aberto do setor RFC 7519 e a camada de identidade OpenID Connect 1.0 (links em inglês). Assim, as ferramentas e bibliotecas atuais funcionam perfeitamente com os tokens de identidade.
Antes de começar
- Entenda como recuperar os valores de metadados da instância.
- Entenda os conceitos básicos dos JSON Web Tokens para saber como usá-los nos seus aplicativos.
- Entenda como criar e ativar contas de serviço nas instâncias. Elas precisam ter uma conta de serviço associada para recuperar tokens de identidade. Para esse processo, não é necessário ter uma permissão IAM na conta de serviço.
-
Configure a autenticação, caso ainda não tenha feito isso.
A autenticação é
o processo de verificação da sua identidade para acesso a serviços e APIs do Google Cloud.
Para executar códigos ou amostras de um ambiente de desenvolvimento local, autentique-se no
Compute Engine selecionando uma das seguintes opções:
Para usar os exemplos Python desta página em um ambiente de desenvolvimento local, instale e inicialize o gcloud CLI e e configure o Application Default Credentials com suas credenciais de usuário.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
If you're using a local shell, then create local authentication credentials for your user account:
gcloud auth application-default login
You don't need to do this if you're using Cloud Shell.
Confira mais informações em Set up authentication for a local development environment.
Como verificar a identidade de uma instância
Em alguns cenários, os aplicativos precisam verificar a identidade de uma instância em execução no Compute Engine antes de transmitir dados confidenciais para ela. Vejamos um exemplo comum, em que há uma instância do Compute Engine chamada "VM1" e um sistema em execução fora dele chamado "Host1". A VM1 pode se conectar ao Host1 e validar a identidade da instância com o seguinte processo:
A VM1 estabelece uma conexão segura com o Host1 por meio do protocolo de conexão protegida que você escolher, como HTTPS.
A VM1 solicita o token de identidade exclusivo do servidor de metadados e especifica o público do token. Nesse exemplo, o valor do público é o URI do Host1. A solicitação ao servidor de metadados inclui o URI do público para que o Host1 possa confirmar o valor mais tarde, durante a etapa de verificação do token.
O Google gera um novo token exclusivo de identidade da instância no formato JWT e o fornece à VM1. O payload do token inclui vários detalhes sobre a instância, além do URI do público. Veja uma descrição completa sobre o Conteúdo do token na seção correspondente.
A VM1 envia o token de identidade ao Host1 por meio da conexão segura atual.
O Host1 decodifica o token de identidade para receber os valores do cabeçalho e payload.
Para verificar se o token é assinado pelo Google, o Host1 compara o valor do público e a assinatura do certificado com o certificado público do Google.
Se o token for válido, o Host1 prossegue com a transmissão e encerra a conexão quando terminar. O Host1 e quaisquer outros sistemas precisam solicitar um novo token para conexões posteriores com a VM1.
Como receber o token de identidade da instância
Quando recebe uma solicitação para fornecer o token de identidade, a instância de máquina virtual o solicita do servidor de metadados. Para isso, ela usa o processo normal de recebimento de metadados da instância. Por exemplo, você pode usar um dos seguintes métodos:
cURL
Crie uma solicitação curl
e inclua um valor no parâmetro audience
.
Outra opção é incluir o parâmetro format
para especificar se você quer incluir os detalhes do projeto e da instância no payload ou não. Se estiver usando o formato full
, inclua o parâmetro licenses
para especificar se quer incluir códigos de licença no payload ou não.
curl -H "Metadata-Flavor: Google" \ 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=AUDIENCE&format=FORMAT&licenses=LICENSES'
Substitua:
AUDIENCE
: o URI exclusivo aceito pela instância e pelo sistema que verifica a identidade dela. Por exemplo, o público pode ser um URL da conexão entre os dois sistemas;FORMAT
: o parâmetro opcional que especifica se os detalhes do projeto e da instância são incluídos no payload. Especifiquefull
para incluir essas informações oustandard
para omiti-las do payload. O valor padrão éstandard
. Para mais informações, consulte Formato do token de identidade.LICENSES
: um parâmetro opcional que especifica se os códigos de licença para imagens associadas a essa instância estão incluídos no payload. EspecifiqueTRUE
para incluir essas informações ouFALSE
para omiti-las do payload. O valor padrão éFALSE
. Não tem efeito, exceto seformat
forfull
.
O servidor de metadados usa o algoritmo RS256 para responder a essa solicitação com um JSON Web Token assinado. Ele inclui uma assinatura do Google e informações adicionais no payload. É possível enviar esse token para outros sistemas e aplicativos para que eles façam a verificação dele e confirmem a identidade da instância.
Python
Use os métodos na biblioteca requests
do Python para enviar uma solicitação simples da instância para o servidor de metadados. No exemplo a seguir, um token de identidade da instância é solicitado e depois impresso. Ele é exclusivo para a instância que faz a solicitação.
O servidor de metadados usa o algoritmo RS256 para responder a essa solicitação com um JSON Web Token assinado. Ele inclui uma assinatura do Google e informações adicionais no payload. É possível enviar esse token para outros sistemas e aplicativos para que eles façam a verificação dele e confirmem a identidade da instância.
Como verificar o token
Depois que seu aplicativo receber um token de identidade de uma instância do Compute Engine, ele poderá verificá-lo usando o processo a seguir.
Receba o token da instância de máquina virtual, faça a decodificação dele usando um decodificador RS256 JWT e leia o conteúdo do cabeçalho para conseguir o valor
kid
.Compare o token com o certificado público do Google para verificar se ele está assinado. Todo certificado público tem um valor
kid
que corresponde akid
no cabeçalho do token.Se o token for válido, compare o conteúdo do payload com os valores esperados. Se o payload do token incluir detalhes sobre a instância e o projeto, o aplicativo poderá verificar os valores
instance_id
,project_id
ezone
. Eles são uma tupla globalmente exclusiva que confirma se o aplicativo se comunica com a instância correta no projeto esperado.
É possível decodificar e verificar o token usando a ferramenta que você quiser. No entanto, um método comum é usar as bibliotecas do seu idioma. Por exemplo, é possível usar o método verify_token
da biblioteca do Google OAuth 2.0 para Python. O verify_token
combina o valor kid
ao certificado apropriado, verifica a assinatura, confere a declaração do público e retorna o conteúdo do payload do token.
Depois de verificar o token e seu conteúdo, o aplicativo poderá se comunicar com essa instância em uma conexão segura e depois encerrar a conexão quando terminar. Para as conexões posteriores, solicite um novo token da instância e volte a verificar a identidade dela.
Conteúdo do token
O token de identidade da instância contém três partes principais:
Header
O cabeçalho inclui o valor kid
para identificar quais certificados OAuth2 públicos são necessários para verificar a assinatura. Ele também inclui o valor alg
para confirmar que a assinatura foi gerada usando o algoritmo RS256 (em inglês).
{
"alg": "RS256",
"kid": "511a3e85d2452aee960ed557e2666a8c5cedd8ae",
}
Payload
O payload contém a declaração do público aud
. Se a instância especificou format=full
ao solicitar o token, o payload também incluirá declarações sobre a instância de máquina virtual e o projeto dela.
Ao solicitar um token de formato completo, a especificação licenses=TRUE
também incluirá declarações sobre as licenças associadas à instância.
{
"iss": "[TOKEN_ISSUER]",
"iat": [ISSUED_TIME],
"exp": [EXPIRED_TIME],
"aud": "[AUDIENCE]",
"sub": "[SUBJECT]",
"azp": "[AUTHORIZED_PARTY]",
"google": {
"compute_engine": {
"project_id": "[PROJECT_ID]",
"project_number": [PROJECT_NUMBER],
"zone": "[ZONE]",
"instance_id": "[INSTANCE_ID]",
"instance_name": "[INSTANCE_NAME]",
"instance_creation_timestamp": [CREATION_TIMESTAMP],
"instance_confidentiality": [INSTANCE_CONFIDENTIALITY],
"license_id": [
"[LICENSE_1]",
...
"[LICENSE_N]"
]
}
}
}
Em que:
[TOKEN_ISSUER]
: um URL que identifica o emissor do token. Para o Compute Engine, esse valor éhttps://accounts.google.com
;[ISSUED_TIME]
: um carimbo de data/hora Unix que indica quando o token foi emitido. Esse valor é atualizado sempre que a instância solicita um token do servidor de metadados;[EXPIRED_TIME]
: um carimbo de data/hora Unix que indica quando o token expira;[AUDIENCE]
: o URI exclusivo aceito pela instância e pelo sistema que verifica a identidade dela. Por exemplo, o público pode ser um URL da conexão entre os dois sistemas;[SUBJECT]
: o assunto do token, que é o ID exclusivo da conta de serviço associada à instância.[AUTHORIZED_PARTY]
: o grupo para o qual o ID do token foi emitido, que é um ID exclusivo da conta de serviço associada à instância.[PROJECT_ID]
: o ID do projeto em que você criou a instância;[PROJECT_NUMBER]
: o número exclusivo do projeto em que a instância foi criada;[ZONE]
: a zona em que a instância está localizada.[INSTANCE_ID]
: o ID exclusivo da instância a que esse token pertence. Esse ID é exclusivo no projeto e na zona.[INSTANCE_NAME]
: o nome da instância a que esse token pertence. Se o projeto usar o DNS zonal, ele poderá ser reutilizado nas zonas, portanto, use uma combinação de valoresproject_id
,zone
einstance_id
para identificar um ID de instância exclusivo. Projetos com DNS global ativado têm um nome de instância exclusivo em todo o projeto.[CREATION_TIMESTAMP]
: um carimbo de data/hora Unix que indica quando a instância foi criada;[INSTANCE_CONFIDENTIALITY]
:1
se a instância for uma VM confidencial.[LICENSE_1]
até[LICENSE_N]
: os códigos de licença para imagens associadas a essa instância.
Veja o exemplo de payload a seguir:
{
"iss": "https://accounts.google.com",
"iat": 1496953245,
"exp": 1496956845,
"aud": "https://www.example.com",
"sub": "107517467455664443765",
"azp": "107517467455664443765",
"google": {
"compute_engine": {
"project_id": "my-project",
"project_number": 739419398126,
"zone": "us-west1-a",
"instance_id": "152986662232938449",
"instance_name": "example",
"instance_creation_timestamp": 1496952205,
"instance_confidentiality": 1,
"license_id": [
"1000204"
]
}
}
}
Assinatura
O Google gera a assinatura por Base64url, codificando o cabeçalho e o payload, além de concatenar os dois valores. É possível comparar esse valor com os certificados OAuth2 públicos para verificar o token.
A seguir
- Revisar o Framework de arquitetura do Google Cloud.