hashicorp/packer · error

build keyless identity policy: %w

Error message

build keyless identity policy: %w

What it means

sigstoreverify.NewShortCertificateIdentity rejected the keyless identity parameters, so the certificate-identity policy cannot be built. It is thrown because bundle verification requires a well-formed issuer/identity pair to match against the Fulcio certificate SAN. The inner error describes the specific validation failure.

Source

Thrown at internal/attestation/verify.go:338

	verifier, err := newSigstoreBundleVerifier(trustedMaterial, verifierOptions...)
	if err != nil {
		return fmt.Errorf("create Sigstore bundle verifier: %w", err)
	}

	artifactPolicy := sigstoreverify.WithoutArtifactUnsafe()
	if policy.ArtifactPath != "" {
		artifact, err := os.Open(policy.ArtifactPath)
		if err != nil {
			return fmt.Errorf("open artifact %q for bundle verification: %w", policy.ArtifactPath, err)
		}
		defer func() { _ = artifact.Close() }()
		artifactPolicy = sigstoreverify.WithArtifact(artifact)
	}

	identity, err := sigstoreverify.NewShortCertificateIdentity(cfg.KeylessOIDCIssuer, "", cfg.KeylessIdentity, "")
	if err != nil {
		return fmt.Errorf("build keyless identity policy: %w", err)
	}

	policyBuilder := sigstoreverify.NewPolicy(artifactPolicy, sigstoreverify.WithCertificateIdentity(identity))
	if _, err := verifier.Verify(bundle, policyBuilder); err != nil {
		return fmt.Errorf("verify Sigstore bundle %q: %w", policy.SigstoreBundlePath, err)
	}

	return nil
}

func ensureBundleMatchesEnvelope(bundle *sigstorebundle.Bundle, envelope Envelope) error {
	bundleEnvelope, err := bundle.Envelope()
	if err != nil {
		return fmt.Errorf("extract DSSE envelope from Sigstore bundle: %w", err)
	}

	rawEnvelope := bundleEnvelope.RawEnvelope()
	if rawEnvelope == nil {

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Set both keyless_identity and keyless_oidc_issuer exactly as encoded in the Fulcio certificate SAN/OID (issuer must match the OIDC issuer, identity the SAN)
  2. Copy the identity/issuer values verbatim from the attestation or certificate (sigstorectl / cosign info can show them)
  3. Trim whitespace and remove quotes/escaping mistakes from config values

Example fix

// before
cfg.KeylessOIDCIssuer = "github"
cfg.KeylessIdentity = "my-org"
// after
cfg.KeylessOIDCIssuer = "https://token.actions.githubusercontent.com"
cfg.KeylessIdentity = "https://github.com/my-org/my-repo/.github/workflows/release.yml@refs/tags/v1.0.0"
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(cfg.KeylessIdentity) == "" || strings.TrimSpace(cfg.KeylessOIDCIssuer) == "" {
    return fmt.Errorf("keyless_identity and keyless_oidc_issuer are required")
}
if _, err := url.ParseRequestURI(cfg.KeylessOIDCIssuer); err != nil {
    return fmt.Errorf("keyless_oidc_issuer %q is not a valid URL", cfg.KeylessOIDCIssuer)
}

Try / catch

if err := verify(...); err != nil {
    if strings.Contains(err.Error(), "build keyless identity policy") {
        // surface config guidance: check identity/issuer values against the cert SAN
    }
}

Prevention

When it happens

Trigger: cfg.KeylessOIDCIssuer or cfg.KeylessIdentity is empty (partially checked earlier, but invalid forms slip through), or contains values NewShortCertificateIdentity cannot parse/accept (e.g. malformed issuer URL, empty required field for the short-form constructor).

Common situations: keyless_identity or keyless_oidc_issuer mistyped or swapped in config; using an email where the cert SAN holds 'usersanta:' style subject; trailing whitespace; changing OIDC provider so the issuer string no longer matches (e.g. accounts.google.com vs token.actions.githubusercontent.com).

Related errors


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