Verifying the Identity of Instances

Before an application sends sensitive information to a virtual machine
instance, the application can verify the identity of the virtual machine using
instance identity tokens signed by Google. Each instance has a unique
JSON Web Token (JWT) that includes details about the instance as well as
Google's RS256 signature.
Your applications can verify the signature against Google's
public Oauth2 certificates
to confirm the identity of the instance with which they have established a
connection.

Compute Engine generates signed instance tokens only when an
instance requests them from instance metadata. Instances are
able to access only their own unique token and not the tokens for any other
instances.

You might want to verify the identities of your instances in the following
scenarios:

When you start an instance for the first time, your applications might need to
ensure that the instance they connected to has a valid identity before they
transmit sensitive information to the instance.

When your policies require you to store credentials outside of the
Compute Engine environment and you regularly send
those credentials to your instances for temporary use. Your applications
can confirm the identities of instances each time they need to transmit
credentials.

Google's instance authentication methods have the following benefits:

Compute Engine creates a unique token each time an instance
requests it, and each token expires within one hour. You can configure your
applications to accept an instance's identity token only once, which reduces
the risk that the token can be reused by an unauthorized system.

Google's private keys and
public Oauth2 certificates
rotate daily to reduce the potential attack surface against these signatures.

Signed metadata tokens use the
RFC 7519
open industry standard and the
OpenID Connect 1.0,
identity layer, so existing tooling and libraries will work seamlessly
with the identity tokens.

Understand how to
create and enable service accounts
on your instances. Your instances must have a service account associated
with them so that they can retrieve their identity tokens. The service account
does not require any IAM permissions to retrieve these identity tokens.

Verifying the identity of an instance

In some scenarios your applications must verify the identity of an instance
running on Compute Engine before transmitting sensitive data to that
instance. In one typical example, there is one system running outside of
Compute Engine called "Host1" and a Compute Engine instance
called "VM1". VM1 can connect to Host1 and validate the identity of that
instance with the following process:

VM1 establishes a secure connection to Host1 over a secure connection
protocol of your choice, such as HTTPS.

VM1 requests its unique identity token from the
metadata server and specifies the audience of the token. In this example,
the audience value is the URI for Host1. The request to the metadata server
includes the audience URI so that Host1 can check the value later during
the token verification step.

Google generates a new unique instance identity token in JWT format and
provides it to VM1. The payload of the token includes several details
about the instance and also includes the audience URI. Read
Token Contents for a complete description of the token
contents.

VM1 sends the identity token to Host1 over the existing secure connection.

Host1 decodes the identity token to obtain the token header and
payload values.

If the token is valid, Host1 proceeds with the transmission and closes the
connection when it is finished. Host1 and any other systems should request
a new token for any subsequent connections to VM1.

Obtaining the instance identity token

When your virtual machine instance receives a request to provide its identity
token, the instance requests that token from the metadata server using
the normal process for
getting instance metadata.
For example, you might use one of the following methods:

cURL

Create a curl request and include a value in the audience parameter.
Optionally, you can include the format parameter to specify whether or not
you want to include project and instance details in the payload. If using
the full format, you can include the licenses parameter to
specify whether or not you want to include license codes in the payload.

[AUDIENCE] is the unique URI agreed upon by both the instance and
the system verifying the instance's identity. For example, the audience
could be a URL for the connection between the two systems.

[FORMAT] is the optional parameter that specifies whether or not the
project and instance details are included in the payload. Specify full
to include this information in the payload or standard to omit the
information from the payload. The default value is standard. Read
Identity Token Format to learn complete details of
the token format.

[LICENSES] is an optional parameter that specifies whether or not
license codes
for images associated with this instance are included in the payload.
Specify TRUE to include this information or FALSE to omit
the information from the payload. The default value is FALSE. Has no
effect unless format is full

The metadata server responds to this request with a JSON Web Token
signed using the
RS256 algorithm.
The token includes a Google signature and additional information in the
payload. You can send this token to other systems and applications so
that they can verify the token and confirm that the
identity of your instance.

Python

You can submit a simple request from your instance to the metadata server
using methods in the Python requests library. The following example
requests and then prints an instance identity token. The token is unique
to the instance that makes this request.

The metadata server responds to this request with a JSON Web Token
signed using the
RS256 algorithm.
The token includes a Google signature and additional information in the
payload. You can send this token to other systems and applications so
that they can verify the token and confirm that the
identity of your instance.

Verifying the token

After your application receives an instance identity token from a
Compute Engine instance, it can verify the token
using the following process.

Receive the token from the virtual machine instance, decode the token
using an RS256 JWT decoder, and read the header contents to obtain the
kid value.

Verify that the token is signed by checking the token against the
public Google certificate.
Each public certificate has a kid value that corresponds to the kid
value in the token header.

If the token is valid, compare the payload contents against the expected
values. If the token payload includes details about the instance and the
project, your application can check the instance_id, project_id, and
zone values. Those values are a globally unique tuple that confirms
your application is communicating with the correct instance
in the desired project.

You can decode and verify the token using any tool that you like, but a
common method is to use the libraries for your language of choice. For example,
you can use the verify_token method from the
Google OAuth 2.0 library
for Python. The verify_token method matches the kid value to the appropriate
certificate, verifies the signature, checks the audience claim, and returns the
payload contents from the token.

After your application verifies the token and its contents, it can proceed
to communicate with that instance over a secure connection and then close
the connection when it is finished. For subsequent connections, request
a new token from the instance and re-verify the identity of the instance.

Token contents

Header

The header includes the kid value to identify which
public Oauth2 certificates
you must use to verify the signature. The header also includes the alg
value to confirm that the signature is generated using the
RS256 algorithm.

Payload

The payload contains the aud audience claim. If the instance
specified format=full when it requested the token, the payload also
includes claims about the virtual machine instance and its project.
When requesting a full format token, specifying licenses=TRUE will also
include claims about the licenses associated with the instance.