Introduction

For a long time, I used service accounts and understood the security implications of working with them in GCP, but I never really took a deep dive into how they work. Like many developers, I relied on the abstraction provided by Google’s SDKs, which made it easy to interact with GCP services without worrying too much about the underlying mechanisms. The metadata service is a critical part of how applications running inside virtual machines fetch instance-specific data and credentials. It plays an essential role in the operation and management of compute instances. Most applications built using Google’s SDKs interact with this service behind the scenes, fetching authentication tokens and other instance-specific data. This enables seamless integration with GCP services without requiring manual credential management, allowing developers to focus on building their applications while benefiting from the security and scalability of GCP’s infrastructure.

In this article, we’ll explore the metadata service in GCP, with a particular focus on how it interacts with compute instances using the gcloud CLI with the --verbosity flag set to debug.

What Is the Metadata Service?

The metadata service is an internal HTTP server exposed to every compute instance in GCP at the fixed IP address 169.254.169.254 or the hostname metadata.google.internal. It provides information about the instance, such as its project ID, service account credentials, instance tags, and custom metadata.

One of the most prominent functions of the metadata service is managing service account credentials. Applications running inside an instance can retrieve short-lived access tokens that allow them to authenticate with other GCP services, all without exposing long-lived credentials.

How the Metadata Service Works in Compute Instances

Whenever a compute instance starts, it is automatically configured with access to the metadata service. This service is only accessible from within the instance itself. The metadata is organized into a RESTful structure and can be queried programmatically using tools like curl.

For instance, querying the metadata for the active service account and its associated scopes can be done with:

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

The header Metadata-Flavor: Google ensures the request is valid and prevents SSRF (Server-Side Request Forgery) attacks.

Debugging Metadata Service Interactions with gcloud CLI

The gcloud CLI simplifies interaction with GCP resources. However, to truly understand what happens behind the scenes, using the --verbosity flag shows detailed interactions and HTTP requests made during execution. Let’s analyze the following command and its debug output:

gcloud storage ls --project=alexanderhose --verbosity=debug

The --verbosity=debug parameter increases the level of detail in the CLI output, showing HTTP requests made to GCP APIs, including the metadata service. Here's an excerpt of the debug logs:

DEBUG: Running [gcloud.storage.ls] with arguments: [--project: "alexanderhose", --verbosity: "debug"]
DEBUG: Making request: GET http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/[email protected]/?recursive=true
DEBUG: Starting new HTTP connection (1): metadata.google.internal:80
DEBUG: http://metadata.google.internal:80 "GET /computeMetadata/v1/instance/service-accounts/[email protected]/?recursive=true HTTP/1.1" 200 194
DEBUG: Making request: GET http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/[email protected]/token
DEBUG: http://metadata.google.internal:80 "GET /computeMetadata/v1/instance/service-accounts/[email protected]/token HTTP/1.1" 200 869
DEBUG: Making request: GET http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/[email protected]/?recursive=true
DEBUG: Starting new HTTP connection (1): metadata.google.internal:80
DEBUG: http://metadata.google.internal:80 "GET /computeMetadata/v1/instance/service-accounts/[email protected]/?recursive=true HTTP/1.1" 200 194
DEBUG: Making request: GET http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/[email protected]/token
DEBUG: http://metadata.google.internal:80 "GET /computeMetadata/v1/instance/service-accounts/[email protected]/token HTTP/1.1" 200 869

This log reveals that the CLI retrieves information about the service account associated with the instance. Let’s break this down:

  1. Initial Metadata Query: The CLI queries the metadata service for details about the active service account.
  2. Token Request: A subsequent request fetches an access token. This token is then used to authenticate with GCP services such as Cloud Storage.

Using curl to Explore the Metadata Service

The metadata service can also be queried directly using curl. This is particularly useful for debugging or testing outside of the gcloud CLI.

Querying Service Account Details

curl -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/[email protected]/?recursive=true

Example response

{
   "aliases": ["default"],
   "email": "[email protected]",
   "scopes": [
      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring.write",
      "https://www.googleapis.com/auth/service.management.readonly",
      "https://www.googleapis.com/auth/servicecontrol",
      "https://www.googleapis.com/auth/trace.append"
   ]
}

The request retrieves metadata about the specific service account assigned to the instance ([email protected] in this case). The information returned includes aliases, the email of the service account, and its authorized OAuth scopes.

Fetching an Access Token

curl -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/[email protected]/token

Example response

{
   "access_token": "ya29.c.c0ASRK0GYexampleoini",
   "expires_in": 3173,
   "token_type": "Bearer"
}

The request retrieves a short-lived OAuth 2.0 access token for the specified service account ([email protected]). The token is used to authenticate the API calls to the storage API.

Practical Applications

The metadata service ensures secure and seamless authentication for applications running inside GCP compute instances. Key benefits include:

Debugging Insights

Using the --verbosity=debug flag with gcloud commands provides a detailed view of metadata interactions. This is useful for:

  • Identifying issues with service account permissions.
  • Understanding the sequence of HTTP requests made to the metadata service.
  • Optimizing application behavior by studying token lifetimes and metadata query patterns.

Conclusion

The GCP metadata service is the cornerstone of secure and scalable cloud application design. By leveraging tools like gcloud CLI and curl, you can debug, optimize, and gain deeper insights into how your applications interact with GCP’s metadata.

For a deeper understanding of the security implications surrounding the use of the metadata service, I’ve also written an article that explores the potential risks. Make sure to check it out for further insights into maintaining a robust security posture on GCP.

How to hack GCP compute instances
Introduction Google Cloud offers a secure and efficient way to manage permissions and authentication through service accounts. These accounts are typically associated with GCP resources like Compute Engine instances, allowing them to securely access other Google Cloud services. But how can we abuse the service account credentials and use them
Share this post