Skip to main content

GCP Instance Identity Token

The GCP Instance Identity Token method attests agents running on Google Cloud Compute Engine VMs. The agent queries the instance metadata service for its signed identity token; the Trust Domain Server verifies the token's authenticity using GCP's public signing keys, then optionally queries the Compute Engine API for additional VM metadata.

Attributes available for SVID issuance

The following attributes are produced. All have the origin gcp_iit.

AttributeDescriptionRequires useInstanceMetadata
gcp_iit.project_idGCP project IDNo
gcp_iit.instance_idUnique instance IDNo
gcp_iit.instance_nameInstance nameNo
gcp_iit.project_numberGCP project numberNo
gcp_iit.zoneZone where the instance is locatedNo
gcp_iit.instance_creation_timestampUnix timestamp of instance creationNo
gcp_iit.label.<key>Instance label values, where <key> is in attributeLabelKeysYes
gcp_iit.metadata.<key>Instance metadata values, where <key> is in attributeMetadataKeysYes

Example SPIFFE ID template:

/gcp/{{gcp_iit.project_id}}/{{gcp_iit.zone}}/{{gcp_iit.instance_name}}

How to Deploy

Step 1 — Set Up GCP Credentials (If Using Instance Metadata)

If you want to include label or metadata attributes (attributeLabelKeys, attributeMetadataKeys), the Trust Domain Server needs an Application Default Credential (ADC) with access to the Compute Engine API.

The service account or workload identity used by the Trust Domain Server must have the compute.instances.get IAM permission (or the roles/compute.viewer role) for the relevant projects.

The server also needs outbound network access to:

  • https://www.googleapis.com/oauth2/v1/certs — to fetch token signing certificates
  • GCP Compute Engine API — to resolve instance metadata

Step 2 — Update cluster configuration

section: AgentAttestation
schema: v1
spec:
policies:
- name: gcp_policy
requiredAttestors:
- type: gcp_iit
config:
allowedProjectIDs:
- project-12345
useInstanceMetadata: true
attributeLabelKeys:
- environment
- team
attributeMetadataKeys:
- production
maxMetadataValueSize: 128

Apply it using spirlctl:

spirlctl config set cluster --id <cluster-id> attestation-policy.yaml

Or using Terraform:

resource "spirl_cluster_config" "agent_attestation" {
cluster_id = spirl_cluster.my_cluster.id
sections = {
AgentAttestation = <<-YAML
section: AgentAttestation
schema: v1
spec:
policies:
- name: gcp_policy
requiredAttestors:
- type: gcp_iit
config:
allowedProjectIDs:
- project-12345
useInstanceMetadata: true
YAML
}
}

Once a configuration document passes validation and is stored, the Defakto control plane syncs it to your Trust Domain Servers automatically. No server or agent restart is required.

Server Configuration Reference

FieldRequiredDefaultDescription
allowedProjectIDsYesList of GCP project IDs whose instances are allowed to attest.
useInstanceMetadataNofalseEnable fetching VM labels and metadata via the Compute Engine API. Required for attributeLabelKeys and attributeMetadataKeys.
serviceAccountKeyJsonNoADCGCP service account credentials JSON. Used only when useInstanceMetadata is enabled. When omitted, Application Default Credentials are used.
attributeLabelKeysNoInstance label keys to emit as attributes. Requires useInstanceMetadata: true.
attributeMetadataKeysNoInstance metadata keys to emit as attributes. Requires useInstanceMetadata: true.
maxMetadataValueSizeNo128Maximum size (bytes) for label and metadata attribute values. Values exceeding this limit are truncated.

Step 3 — Configure the Agent

agent:
auth:
clusterId: c-xxxxxx
attestors:
- type: gcp_iit
config:
identityTokenHost: metadata.google.internal # optional; override metadata service host
serviceAccount: default # optional; select a specific service account

Agent Configuration Reference

FieldDefaultDescription
identityTokenHostmetadata.google.internalMetadata service host for fetching the identity token.
serviceAccountdefaultService account for which to fetch the identity token.

Step 4 — Verify

Server logs — look for these in order:

  1. "Login started with multi-attestation support" — confirms the agent offered providedMethods: ["gcp_iit"]
  2. "Authorization received and verified" — includes agentAttestationAttributes with the instance identity:
    {
    "msg": "Authorization received and verified",
    "agentAttestationAttributes": [
    "gcp_iit:gcp_iit.project_id=\"project-12345\"",
    "gcp_iit:gcp_iit.instance_name=\"my-vm\"",
    "gcp_iit:gcp_iit.zone=\"us-central1-a\""
    ]
    }
  3. "Connected to agent" — session is fully established

Agent logs — enable debug logging to see "Sending Login" with attestors: ["gcp_iit"]. At the default log level, "Connected to server" confirms the session is live.

Metrics — confirm proofs are succeeding:

spirl_attestation_signer.proof{attestor_type="gcp_iit",outcome="success"}
spirl_attestation_agent.proof{attestor_type="gcp_iit",outcome="success"}

Alert on outcome="failed" to detect token signature or project allowlist failures.

Common errors:

ErrorLikely cause
no cluster policy authorizes the provided attestorsAgent's gcp_iit method doesn't match any policy — verify allowedProjectIDs includes the VM's GCP project
Attestor rejected proof, policy failedVM's project ID not in allowedProjectIDs, or server can't reach googleapis.com to fetch signing certs
Label/metadata attributes missing from agentAttestationAttributesuseInstanceMetadata is not enabled, or the Trust Domain Server lacks compute.instances.get permission

Security Considerations

  • The Trust Domain Server verifies the identity token's signature using GCP's public signing keys fetched from googleapis.com. Network access to this endpoint is required.
  • Labels and metadata values are fetched from the GCP Compute Engine API using unattested IMDS data as a hint and then validated. Restrict which label and metadata keys are emitted using attributeLabelKeys and attributeMetadataKeys.
  • maxMetadataValueSize prevents abnormally large metadata values from being included in attributes. The default of 128 bytes is sufficient for most environment tags and labels.