Server plugin: NodeAttestor "gcp_iit"

May 24, 2026 ยท View on GitHub

Must be used in conjunction with the agent-side gcp_iit plugin

The gcp_iit plugin automatically attests instances using the GCP Instance Identity Token. It also allows an operator to use GCP Instance IDs when defining SPIFFE ID attestation policies. Agents attested by the gcp_iit attestor will be issued a SPIFFE ID like spiffe://TRUST_DOMAIN/spire/agent/gcp_iit/PROJECT_ID/INSTANCE_ID This plugin requires an allow list of ProjectID from which nodes can be attested. This also means that you shouldn't run multiple trust domains from the same GCP project.

Configuration

ConfigurationDescriptionDefault
projectid_allow_listList of ProjectIDs from which nodes can be attested.
use_instance_metadataIf true, instance metadata is fetched from the Google Compute Engine API and used to augment the node selectors produced by the plugin.false
service_account_filePath to the service account file used to authenticate with the Google Compute Engine API
allowed_label_keysInstance label keys considered for selectors
allowed_metadata_keysInstance metadata keys considered for selectors
max_metadata_value_sizeSets the maximum metadata value size considered by the plugin for selectors128
agent_path_templateA URL path portion format of Agent's SPIFFE ID. Describe in text/template format."/{{ .PluginName }}/{{ .ProjectID }}/{{ .InstanceID }}"

A sample configuration:

    NodeAttestor "gcp_iit" {
        plugin_data {
            projectid_allow_list = ["project-123"]
        }
    }

Selectors

This plugin generates the following selectors based on information contained in the Instance Identity Token:

SelectorExampleDescription
gcp_iit:project-idgcp_iit:project-id:big-kahuna-123456ID of the project containing the instance
gcp_iit:zonegcp_iit:zone:us-west1-bZone containing the instance
gcp_iit:instance-namegcp_iit:instance-name:blog-serverName of the instance
gcp_iit:sagcp_iit:sa:123456789-compute@developer.gserviceaccount.comService account email

If use_instance_metadata is true, then the Google Compute Engine API is queried for instance metadata which is used to populate these additional selectors:

SelectorExampleDescription
gcp_iit:taggcp_iit:tag:blog-serverInstance tag (one selector per)
gcp_iit:labelgcp_iit:label:key:valueInstance label
gcp_iit:metadatagcp_iit:metadata:key:valueInstance metadata (see caveat below)

Not all instance label and metadata values are useful for node selection. To prevent the creation of large amounts of useless selectors, labels and metadata are not used by default. To opt-in to use a specific label or metadata value, specify the key in the allowed_label_keys or allowed_metadata_keys configurable.

Instance metadata can hold large values up to 256KiB. To prevent pushing large amounts of data into the datastore, a maximum metadata value size limit is enforced. If an allowed (i.e. key specified in allowed_metadata_keys) metadata value is encountered that exceeds the limit then attestation will fail.

Metadata and label values are optional. If the value isn't present, the corresponding selector will still have a trailing colon (i.e. gcp_iit:label:<key>:, gcp_iit:metadata:<key>:)

Authenticating with the Google Compute Engine API

The plugin uses the Application Default Credentials to authenticate with the Google Compute Engine API, as documented by Setting Up Authentication For Server to Server. When SPIRE Server is running inside GCP, it will use the default service account credentials available to the instance it is running under. When running outside GCP, or if non-default credentials are needed, the path to the service account file containing the credentials may be specified using the GOOGLE_APPLICATION_CREDENTIALS environment variable or the service_account_file configurable (see Configuration).

The service account must have IAM permissions and Authorization Scopes granting access to the following APIs:

Agent Path Template

The agent path template is a way of customizing the format of generated SPIFFE IDs for agents. The template formatter is using Golang text/template conventions, it can reference values provided by the plugin or in a Compute Engine identity token. Details about the template engine are available in the template engine documentation. Note that agent SPIFFE IDs must be unique within a trust domain, so if two agents use the same service account, the path template must contain additional fully distinguishing identifiers.

Some useful values are:

ValueDescription
.PluginNameThe name of the plugin
.ProjectIDThe ID for the project where the instance was created
.InstanceIDThe unique ID for the instance to which this token belongs.
.ProjectNumberThe unique number for the project where you created the instance
.ZoneThe zone where the instance is located
.InstanceCreationTimestampA Unix timestamp indicating when you created the instance.
.ServiceAccountThe service account email ("@" is replaced with "_")

Security Considerations

The Instance Identity Token, which this attestor leverages to prove node identity, is available to any process running on the node by default. As a result, it is possible for non-agent code running on a node to attest to the SPIRE Server, allowing it to obtain any workload identity that the node is authorized to run.

While many operators choose to configure their systems to block access to the Instance Identity Token, the SPIRE project cannot guarantee this posture. To mitigate the associated risk, the gcp_iit node attestor implements Trust On First Use (or TOFU) semantics. For any given node, attestation may occur only once. Subsequent attestation attempts will be rejected.

It is still possible for non-agent code to complete node attestation before SPIRE Agent can, however this condition is easily and quickly detectable as SPIRE Agent will fail to start, and both SPIRE Agent and SPIRE Server will log the occurrence. Such cases should be investigated as possible security incidents.