kubernetes/kops · critical

failed to get GCE RSA attestation key from TPM: %w

Error message

failed to get GCE RSA attestation key from TPM: %w

What it means

CreateToken opens the node's local TPM 2.0 device and fetches the GCE RSA attestation key (EK/AIK-backed) via go-attestation's client.GceAttestationKeyRSA. If the TPM cannot provide that key (device open succeeded but key creation/loading failed), the error is wrapped with this message and CreateToken returns no token. It means node authentication via TPM attestation cannot proceed.

Source

Thrown at upup/pkg/fi/cloudup/gce/tpm/gcetpmsigner/tpmauthenticator.go:79

		zone:      zone,
		instance:  instance,
	}, nil
}

func (a *tpmAuthenticator) CreateToken(body []byte) (string, error) {
	requestHash := sha256.Sum256(body)

	tpmStart := time.Now()

	tpmDevice, err := openTPM()
	if err != nil {
		return "", fmt.Errorf("failed to open TPM: %w", err)
	}
	defer tpmDevice.Close()

	key, err := client.GceAttestationKeyRSA(tpmDevice)
	if err != nil {
		return "", fmt.Errorf("failed to get GCE RSA attestation key from TPM: %w", err)
	}
	defer key.Close()

	klog.V(2).Infof("attestation key is %v", debugToPEM(key.PublicKey()))

	klog.Infof("TPM initialization took %v", time.Since(tpmStart))

	data := gcetpm.AuthTokenData{
		GCPProjectID: a.projectID,
		Zone:         a.zone,
		Instance:     a.instance,
		Timestamp:    time.Now().Unix(),
		Audience:     gcetpm.AudienceNodeAuthentication,
		RequestHash:  requestHash[:],
	}

	payload, err := json.Marshal(&data)
	if err != nil {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Enable Shielded VM with vTPM on the instance (or recreate the instance with shielded-secure-boot/vTPM options on)
  2. Ensure the process can access /dev/tpmrm0 (run privileged, add device mapping in container, check udev/permissions)
  3. Verify the machine actually has a TPM 2.0 device: ls /dev/tpm*
  4. Pin/upgrade github.com/google/go-attestation to a version compatible with your OS/GCE guest environment
  5. Test key availability with go-attestation tools (e.g. tpm-tools or attest client) to isolate the failing layer

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

// before creating tokens
if _, err := os.Stat("/dev/tpmrm0"); err != nil {
    return fmt.Errorf("TPM device unavailable: %w", err)
}

Try / catch

token, err := authenticator.CreateToken(ctx, request)
if err != nil {
    if strings.Contains(err.Error(), "failed to get GCE RSA attestation key") {
        // fall back to non-TPM auth or surface actionable setup error
    }
    return err
}

Prevention

When it happens

Trigger: client.GceAttestationKeyRSA(tpmDevice) returns an error: TPM lacks the GCE attestation key hierarchy, the key cannot be created/loaded, or the underlying tpm2/attestation call fails (I/O error on /dev/tpmrm0, unsupported TPM, permission denied on the device).

Common situations: Running on a GCE VM without a vTPM enabled (shielded VM / 'enableIntegrityMonitoring' off); /dev/tpmrm0 not accessible to the process (container without --device or device cgroup rules); non-GCE environment or emulated testing where the GCE-specific attestation key is absent; go-attestation version incompatibility with the guest environment.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/e8334ff3098289b5. Report an issue: GitHub.