hashicorp/packer · error

build keyless identity policy: %w

Error message

build keyless identity policy: %w

What it means

This error wraps a failure from sigstore-go's verify.NewShortCertificateIdentity, which constructs the keyless identity policy used to match a Fulcio certificate against the expected signer. The library throws it when the policy cannot be built, almost always because the expected OIDC issuer and identity values are empty or invalid (NewShortCertificateIdentity requires at least one matchable field and returns an error when all inputs are empty). It is returned from verifyKeylessCertificate while validating the signer's certificate during keyless attestation verification.

Source

Thrown at internal/attestation/sign_keyless.go:73

		return fmt.Errorf("verify Fulcio certificate chain: %w", err)
	}

	// When using the public Sigstore root (no custom trusted root configured),
	// require a valid SCT so certificates issued outside a public CT log are rejected.
	if strings.TrimSpace(trustedRootPath) == "" {
		if err := sigstoreverify.VerifySignedCertificateTimestamp(chains, 1, trustedMaterial); err != nil {
			return fmt.Errorf("verify Fulcio certificate SCT: %w", err)
		}
	}

	summary, err := fulciocertificate.SummarizeCertificate(certificate)
	if err != nil {
		return fmt.Errorf("summarize Fulcio certificate: %w", err)
	}

	identity, err := sigstoreverify.NewShortCertificateIdentity(expectedOIDCIssuer, "", expectedIdentity, "")
	if err != nil {
		return fmt.Errorf("build keyless identity policy: %w", err)
	}
	if err := identity.Verify(summary); err != nil {
		return fmt.Errorf("verify keyless certificate identity: %w", err)
	}

	return nil
}

func init() {
	RegisterSigner(SigningModeKeyless, newKeylessSigner)
}

type keylessSigner struct {
	keypair  sigstoregosign.Keypair
	certPEM  []byte
	cert     *x509.Certificate
	verifier Verifier
	keyID    string

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Set both keyless_identity and keyless_oidc_issuer in the backend config to the expected signer identity (e.g. email or workflow URI) and the OIDC issuer URL (e.g. https://token.actions.githubusercontent.com).
  2. Trim and validate the values before calling verify; ensure at least one of issuer/identity is non-empty.
  3. Check sigstore-go version compatibility for NewShortCertificateIdentity argument semantics (issuer, SAN, identity, SAN values).

Example fix

// before
identity, err := sigstoreverify.NewShortCertificateIdentity("", "", "", "")
// after
if expectedOIDCIssuer == "" || expectedIdentity == "" {
    return fmt.Errorf("keyless verification requires keyless_oidc_issuer and keyless_identity")
}
identity, err := sigstoreverify.NewShortCertificateIdentity(expectedOIDCIssuer, "", expectedIdentity, "")
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(cfg.KeylessIdentity) == "" || strings.TrimSpace(cfg.KeylessOIDCIssuer) == "" {
    return fmt.Errorf("keyless verification requires keyless_identity and keyless_oidc_issuer")
}

Type guard

func hasKeylessIdentityPolicy(identity, issuer string) bool {
    return strings.TrimSpace(identity) != "" && strings.TrimSpace(issuer) != ""
}

Prevention

When it happens

Trigger: Calling keylessVerifier.Verify (which invokes verifyKeylessCertificate in internal/attestation/sign_keyless.go:71-74) with BackendConfig where KeylessOIDCIssuer or KeylessIdentity resolve to empty strings at this point, or NewShortCertificateIdentity rejecting the combination (e.g. both expectedOIDCIssuer and expectedIdentity empty).

Common situations: A template/backend config omits keyless_identity or keyless_oidc_issuer and the code path reached verifyKeylessCertificate without the earlier newKeylessVerifier guard (e.g. a Verifier supplied explicitly with blank identity fields); values set only with surrounding whitespace; a refactor passed "" for both parameters.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/356cc640e1917832. Report an issue: GitHub.