Antes de uma aplicação enviar informações confidenciais para uma instância de máquina virtual (VM), a aplicação pode validar a identidade da instância através de tokens de identidade da instância assinados pela Google. Cada instância tem um Símbolo da Web JSON (JWT) exclusivo que inclui detalhes sobre a instância, bem como a assinatura RS256 da Google. As suas aplicações podem validar a assinatura com base nos certificados OAuth2 públicos da Google para confirmar a identidade da instância com a qual estabeleceram uma ligação.
O Compute Engine gera tokens de instância assinados apenas quando uma instância os pede a partir dos metadados da instância. As instâncias podem aceder apenas ao seu próprio token único e não aos tokens de outras instâncias.
Recomendamos que valide as identidades das suas instâncias nos seguintes cenários:
- Quando inicia uma instância pela primeira vez, as suas aplicações podem ter de garantir que a instância à qual se ligaram tem uma identidade válida antes de transmitirem informações confidenciais à instância.
- Quando as suas políticas exigem que armazene credenciais fora do ambiente do Compute Engine e envia regularmente essas credenciais para as suas instâncias para utilização temporária. As suas aplicações podem confirmar as identidades das instâncias sempre que precisarem de transmitir credenciais.
Os métodos de autenticação de instâncias da Google têm as seguintes vantagens:
- O Compute Engine cria um token exclusivo sempre que uma instância o pede, e cada token expira no prazo de uma hora. Pode configurar as suas aplicações para aceitarem o token de identidade de uma instância apenas uma vez, o que reduz o risco de o token poder ser reutilizado por um sistema não autorizado.
- Os tokens de metadados assinados usam a norma industrial aberta RFC 7519 e a camada de identidade OpenID Connect 1.0, pelo que as ferramentas e as bibliotecas existentes funcionam perfeitamente com os tokens de identidade.
Antes de começar
- Compreenda como obter valores de metadados da instância.
- Compreenda os básicos dos símbolos da Web JSON para saber como os usar nas suas aplicações.
- Compreenda como criar e ativar contas de serviço nas suas instâncias. As suas instâncias têm de ter uma conta de serviço associada para poderem obter os respetivos tokens de identidade. A conta de serviço não requer autorizações de IAM para obter estes tokens de identidade.
-
Se ainda não o tiver feito, configure a autenticação.
A autenticação valida a sua identidade para aceder a Trusted Cloud by S3NS serviços e APIs. Para executar código ou exemplos a partir de um ambiente de desenvolvimento local, pode autenticar-se no Compute Engine selecionando uma das seguintes opções:
Para usar os Python exemplos nesta página num ambiente de desenvolvimento local, instale e inicialize a CLI gcloud e, em seguida, configure as Credenciais predefinidas da aplicação com as suas credenciais de utilizador.
Instale a CLI Google Cloud e, em seguida, inicie sessão na CLI gcloud com a sua identidade federada.
Create local authentication credentials for your user account:
gcloud auth application-default login
If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.
Para mais informações, consulte Set up authentication for a local development environment.
Validar a identidade de uma instância
Em alguns cenários, as suas aplicações têm de validar a identidade de uma instância em execução no Compute Engine antes de transmitir dados confidenciais para essa instância. Num exemplo típico, existe um sistema em execução fora do Compute Engine denominado "Host1" e uma instância do Compute Engine denominada "VM1". A VM1 pode estabelecer ligação ao Host1 e validar a identidade dessa instância com o seguinte processo:
A VM1 estabelece uma ligação segura ao Host1 através de um protocolo de ligação segura à sua escolha, como HTTPS.
A VM1 pede o respetivo token de identidade exclusivo ao servidor de metadados e especifica o público-alvo do token. Neste exemplo, o valor do público-alvo é o URI para Host1. O pedido ao servidor de metadados inclui o URI do público para que o Host1 possa verificar o valor mais tarde durante o passo de validação do token.
O Google gera um novo token de identidade da instância exclusivo no formato JWT e fornece-o à VM1. A carga útil do token inclui vários detalhes sobre a instância e também inclui o URI do público-alvo. Leia o artigo Conteúdos do token para uma descrição completa dos conteúdos do token.
A VM1 envia o token de identidade para o Host1 através da ligação segura existente.
O anfitrião 1 descodifica o token de identidade para obter o cabeçalho do token e os valores do payload.
O anfitrião 1 verifica se o token está assinado pela Google através da verificação do valor do público-alvo e da validação da assinatura do certificado em relação ao certificado público da Google.
Se o token for válido, o Host1 prossegue com a transmissão e fecha a ligação quando terminar. O anfitrião 1 e quaisquer outros sistemas devem pedir um novo token para quaisquer ligações subsequentes à VM1.
Obter o token de identidade da instância
Quando a instância de máquina virtual recebe um pedido para fornecer o respetivo token de identidade, a instância pede esse token ao servidor de metadados através do processo normal para obter metadados da instância. Por exemplo, pode usar um dos seguintes métodos:
cURL
Crie um pedido curl
e inclua um valor no parâmetro audience
.
Opcionalmente, pode incluir o parâmetro format
para especificar se quer ou não incluir detalhes do projeto e da instância no payload. Se usar o formato full
, pode incluir o parâmetro licenses
para especificar se quer ou não incluir códigos de licença na carga útil.
curl -H "Metadata-Flavor: Google" \ 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=AUDIENCE&format=FORMAT&licenses=LICENSES'
Substitua o seguinte:
AUDIENCE
: o URI exclusivo acordado entre a instância e o sistema que valida a identidade da instância. Por exemplo, o público pode ser um URL para a associação entre os dois sistemas.FORMAT
: o parâmetro opcional que especifica se os detalhes do projeto e da instância estão incluídos no payload. Especifiquefull
para incluir estas informações na carga útil oustandard
para omitir as informações da carga útil. O valor predefinido éstandard
. Para mais informações, consulte o artigo Formato do token de identidade.LICENSES
: um parâmetro opcional que especifica se os códigos de licença das imagens associadas a esta instância estão incluídos no payload. EspecifiqueTRUE
para incluir estas informações ouFALSE
para omitir estas informações da carga útil. O valor predefinido éFALSE
. Não tem efeito, a menos queformat
sejafull
O servidor de metadados responde a este pedido com um token Web JSON assinado através do algoritmo RS256. O token inclui uma assinatura da Google e informações adicionais no payload. Pode enviar este token para outros sistemas e aplicações para que possam validar o token e confirmar a identidade da sua instância.
Python
Pode enviar um pedido simples da sua instância para o servidor de metadados
usando métodos na biblioteca requests
do Python. O exemplo seguinte
pede e, em seguida, imprime um token de identidade da instância. O token é exclusivo
da instância que faz este pedido.
O servidor de metadados responde a este pedido com um token Web JSON assinado através do algoritmo RS256. O token inclui uma assinatura da Google e informações adicionais no payload. Pode enviar este token para outros sistemas e aplicações para que possam validar o token e confirmar a identidade da sua instância.
A validar o token
Depois de a sua aplicação receber um token de identidade da instância de uma instância do Compute Engine, pode validar o token através do seguinte processo.
Receba o token da instância da máquina virtual, descodifique o token com um descodificador JWT RS256 e leia o conteúdo do cabeçalho para obter o valor
kid
.Verifique se o token está assinado comparando-o com o certificado público da Google. Cada certificado público tem um valor
kid
que corresponde ao valorkid
no cabeçalho do token.Se o token for válido, compare o conteúdo da carga útil com os valores esperados. Se a carga útil do token incluir detalhes sobre a instância e o projeto, a sua aplicação pode verificar os valores
instance_id
,project_id
ezone
. Esses valores são uma tupla globalmente única que confirma que a sua aplicação está a comunicar com a instância correta no projeto pretendido.
Pode descodificar e validar o token com qualquer ferramenta que quiser, mas um método comum é usar as bibliotecas para o seu idioma de preferência. Por exemplo, pode usar o método verify_token
da biblioteca Google OAuth 2.0 para Python. O método verify_token
faz corresponder o valor kid
ao certificado adequado, verifica a assinatura, verifica a reivindicação de público-alvo e devolve os conteúdos da carga útil do token.
Depois de a sua aplicação validar o token e o respetivo conteúdo, pode continuar a comunicar com essa instância através de uma ligação segura e, em seguida, fechar a ligação quando terminar. Para ligações subsequentes, peça uma nova chave à instância e valide novamente a identidade da instância.
Conteúdo do token
O token de identidade da instância contém três partes principais:
Cabeçalho
O cabeçalho inclui o valor kid
para identificar que
certificados OAuth2 públicos
tem de usar para validar a assinatura. O cabeçalho também inclui o valor alg
para confirmar que a assinatura é gerada através do
algoritmo RS256.
{
"alg": "RS256",
"kid": "511a3e85d2452aee960ed557e2666a8c5cedd8ae",
}
Payload
O payload contém a reivindicação de público-alvo aud
. Se a instância tiver especificado format=full
quando solicitou o token, o payload também inclui reivindicações sobre a instância da máquina virtual e o respetivo projeto.
Quando pedir um token de formato completo, a especificação de licenses=TRUE
também inclui reivindicaçõ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]"
]
}
}
}
Onde:
[TOKEN_ISSUER]
: um URL que identifica quem emitiu o token. Para o Compute Engine, este valor éhttps://accounts.google.com
.[ISSUED_TIME]
: uma data/hora Unix que indica quando o token foi emitido. Este valor é atualizado sempre que a instância pede um token ao servidor de metadados.[EXPIRED_TIME]
: uma data/hora no formato Unix que indica quando o token expira.[AUDIENCE]
: o URI exclusivo acordado entre a instância e o sistema que valida a identidade da instância. Por exemplo, o público-alvo pode ser um URL para a ligação entre os dois sistemas.[SUBJECT]
: o assunto do token, que é o ID exclusivo da conta de serviço que associou à sua instância.[AUTHORIZED_PARTY]
: a parte à qual o token de ID foi emitido, que é o ID exclusivo da conta de serviço que associou à sua instância.[PROJECT_ID]
: o ID do projeto onde criou a instância.[PROJECT_NUMBER]
: o número exclusivo do projeto onde criou a instância.[ZONE]
: a zona onde a instância está localizada.[INSTANCE_ID]
: o ID exclusivo da instância à qual este token pertence. Este ID é exclusivo no projeto e na zona.[INSTANCE_NAME]
: o nome da instância à qual este token pertence. Se o seu projeto usar DNS zonal, este nome pode ser reutilizado em várias zonas. Por isso, use uma combinação dos valoresproject_id
,zone
einstance_id
para identificar um ID da instância único. Os projetos com DNS global ativado têm um nome de instância único no projeto.[CREATION_TIMESTAMP]
: uma indicação de tempo Unix que indica quando criou a instância.[INSTANCE_CONFIDENTIALITY]
:1
se a instância for uma VM confidencial.[LICENSE_1]
a[LICENSE_N]
: os códigos de licença para imagens associadas a esta instância.
O seu payload pode ser semelhante ao seguinte exemplo:
{
"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
A Google gera a assinatura através da codificação base64url do cabeçalho e do payload, e concatenando os dois valores. Pode verificar este valor com os certificados OAuth2 públicos para validar o token.
O que se segue?
- Reveja a Trusted Cloud by S3NS estrutura bem arquitetada.
- Autenticar cargas de trabalho noutras cargas de trabalho através de mTLS.