kubernetes/kops · error

empty attested document signature

Error message

empty attested document signature

What it means

The attested document endpoint returned HTTP 200 and valid JSON, but the signature field was empty. The authenticator requires a non-empty PKCS7 signature to construct the "x-azure-id <resourceID> <signature>" bootstrap token, so it rejects the response as unusable.

Source

Thrown at upup/pkg/fi/cloudup/azure/azuremetadata/authenticator.go:67

	// Query IMDS for the VM's resource ID.
	metadata, err := QueryComputeInstanceMetadata(ctx)
	if err != nil {
		return "", fmt.Errorf("querying instance metadata: %w", err)
	}
	if metadata.ResourceID == "" {
		return "", fmt.Errorf("missing resource ID")
	}
	klog.V(4).Infof("Azure authenticator obtained resource ID %q", metadata.ResourceID)

	// Query IMDS for a PKCS7-signed attested document containing the nonce.
	nonce := NonceForBody(body)
	doc, err := queryIMDSAttestedDocument(ctx, nonce)
	if err != nil {
		return "", fmt.Errorf("querying attested document: %w", err)
	}
	if doc.Signature == "" {
		return "", fmt.Errorf("empty attested document signature")
	}
	klog.V(2).Infof("Azure authenticator obtained attested document for %q", metadata.ResourceID)

	// Token format: "x-azure-id <resourceID> <base64-pkcs7-signature>"
	return AzureAuthenticationTokenPrefix + metadata.ResourceID + " " + doc.Signature, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the raw IMDS attested response with curl to see whether a signature field is returned normally
  2. Verify api-version currency and re-test; pin/upgrade to a supported version
  3. Rule out spoofing: check routes/iptables for anything answering on 169.254.169.254
  4. If the VM is degraded (run 'az vm rerun' / redeploy) to restore the IMDS signing service
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: fetch the attested document and assert a non-empty signature
resp, err := http.Get("http://169.254.169.254/metadata/attested/document?api-version=2025-04-07&nonce=test")
// (set Metadata:true header in production code)
var doc struct{ Signature string `json:"signature"` }
json.NewDecoder(resp.Body).Decode(&doc)
if doc.Signature == "" { return errors.New("IMDS returned empty attestation signature") }

Type guard

func hasValidSignature(d *struct{ Signature string }) bool {
    return d != nil && strings.TrimSpace(d.Signature) != ""
}

Try / catch

// Treat empty-signature as unrecoverable config/env issue: fail fast with diagnostics
if err != nil {
    return fmt.Errorf("bootstrap aborted (attestation): %w", err)
}

Prevention

When it happens

Trigger: queryIMDSAttestedDocument returns an attestedDocument struct whose signature field is an empty string — the JSON lacked the "signature" key or it was empty/null.

Common situations: Intercepting software returning 200 with crafted JSON; Azure IMDS behavior/shape change for the api-version in use; VM in a degraded state where signing service returns empty payloads; accidental hit of a spoofed 169.254.169.254 responder.

Related errors


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