kubernetes/kops · error

attested document createdOn is required

Error message

attested document createdOn is required

What it means

Guard on the attested document freshness fields: createdOn is empty, so the document's age cannot be established and replay of arbitrarily old attestations would be possible.

Source

Thrown at upup/pkg/fi/cloudup/azure/attest.go:299

	}
	klog.V(4).Infof("Attested document content: vmId=%q subscriptionId=%q createdOn=%q expiresOn=%q", data.VMId, data.SubscriptionId, data.TimeStamp.CreatedOn, data.TimeStamp.ExpiresOn)

	if data.VMId == "" {
		return nil, fmt.Errorf("attested document vmId is required")
	}
	if data.SubscriptionId == "" {
		return nil, fmt.Errorf("attested document subscriptionId is required")
	}

	// Verify the nonce matches the request body hash (replay protection).
	expectedNonce := nonceForBody(body)
	if data.Nonce != expectedNonce {
		return nil, fmt.Errorf("attested document nonce mismatch: got=%q expected=%q", data.Nonce, expectedNonce)
	}

	now := time.Now().UTC()
	if data.TimeStamp.CreatedOn == "" {
		return nil, fmt.Errorf("attested document createdOn is required")
	}
	createdOn, err := time.Parse(attestedDocumentTimeFormat, data.TimeStamp.CreatedOn)
	if err != nil {
		return nil, fmt.Errorf("parsing attested document creation: %w", err)
	}
	if createdOn.After(now.Add(attestedDocumentMaxClockSkew)) {
		return nil, fmt.Errorf("attested document createdOn %s is too far in the future", data.TimeStamp.CreatedOn)
	}
	oldestAllowedCreatedOn := now.Add(-(attestedDocumentMaxAge + attestedDocumentMaxClockSkew))
	if createdOn.Before(oldestAllowedCreatedOn) {
		return nil, fmt.Errorf("attested document createdOn %s is older than allowed freshness window of %s plus %s clock skew", data.TimeStamp.CreatedOn, attestedDocumentMaxAge, attestedDocumentMaxClockSkew)
	}
	klog.V(4).Infof("Attested document createdOn is fresh (createdOn=%s now=%s)", createdOn.Format(time.RFC3339), now.Format(time.RFC3339))

	// Verify the attested document has not expired and has a coherent lifetime.
	if data.TimeStamp.ExpiresOn != "" {
		expiresOn, err := time.Parse(attestedDocumentTimeFormat, data.TimeStamp.ExpiresOn)
		if err != nil {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Reject the attestation token
  2. Regenerate the token on the node
  3. Update kOps if the document timestamp schema changed
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at upup/pkg/fi/cloudup/azure/attest.go:299 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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