hashicorp/nomad · warning

identities without an expiration are insecure

Error message

identities without an expiration are insecure

What it means

WorkloadIdentity.Warnings flags named identities that have no TTL, meaning the resulting JWT never expires. Non-expiring identity tokens are insecure; Nomad recommends setting a TTL so tokens are periodically rotated.

Source

Thrown at nomad/structs/workload_id.go:515

	return mErr.ErrorOrNil()
}

func (wi *WorkloadIdentity) Warnings() error {
	if wi == nil {
		return fmt.Errorf("must not be nil")
	}

	var mErr multierror.Error

	if n := len(wi.Audience); n == 0 {
		mErr.Errors = append(mErr.Errors, fmt.Errorf("identities without an audience are insecure"))
	} else if n > 1 {
		mErr.Errors = append(mErr.Errors, fmt.Errorf("while multiple audiences is allowed, it is more secure to use 1 audience per identity"))
	}

	if wi.Name != "" && wi.Name != WorkloadIdentityDefaultName {
		if wi.TTL == 0 {
			mErr.Errors = append(mErr.Errors, fmt.Errorf("identities without an expiration are insecure"))
		}
	}

	// Warn users about using env vars without restarts
	if wi.Env && wi.ChangeMode != WIChangeModeRestart {
		mErr.Errors = append(mErr.Errors, fmt.Errorf("using env=%t without change_mode=%q may result in task not getting updated identity",
			wi.Env, WIChangeModeRestart))
	}

	return mErr.ErrorOrNil()
}

// WorkloadIdentityRequest encapsulates the 3 parameters used to generated a
// signed workload identity: the alloc, task, and specific identity's name.
type WorkloadIdentityRequest struct {
	AllocID string
	WIHandle
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set a ttl on the named identity block (e.g. ttl = "1h").
  2. Set wi.TTL in Go to a positive duration before validation.
  3. Choose a TTL aligned with the cloud provider's credential lifetime and rotation policy.

Example fix

// before
identity {
  name = "aws"
  audience = ["aws"]
}
// after
identity {
  name = "aws"
  audience = ["aws"]
  ttl = "1h"
}
Defensive patterns

Strategy: validation

Validate before calling

func validateTTLSet(wi *structs.WorkloadIdentity) error {
  if wi.Name != "" && wi.Name != structs.WorkloadIdentityDefaultName && wi.TTL == 0 {
    return fmt.Errorf("identity %q should set a ttl so tokens expire", wi.Name)
  }
  return nil
}

Prevention

When it happens

Trigger: Calling Warnings() on an identity where wi.Name is non-empty and not "default" while wi.TTL == 0, e.g. identity { name = "aws" audience = ["aws"] } with no ttl set.

Common situations: Adding named identities for cloud credentials without configuring expiration; migrating default identities to named ones and dropping the TTL; assuming tokens are short-lived by default.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/a0e703c5f7be563f. Report an issue: GitHub.