hashicorp/packer · error

verify keyless certificate identity: %w

Error message

verify keyless certificate identity: %w

What it means

This error wraps a failed identity.Verify(summary) call: the Fulcio certificate's summarized identities (SANs, issuer) did not match the expected keyless identity policy built from the configured keyless_identity and keyless_oidc_issuer. The library throws it during keyless attestation verification to reject certificates that were issued to a different identity or OIDC provider than the one configured, preventing signature forgery by an unrelated valid certificate.

Source

Thrown at internal/attestation/sign_keyless.go:76

	// 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
}

func newKeylessSigner(ctx context.Context, cfg BackendConfig) (Signer, error) {

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Compare the certificate's actual SAN and issuer (from the Fulcio cert or Rekor entry) and set keyless_identity / keyless_oidc_issuer to exactly those values.
  2. Re-sign the artifact from the intended workflow/identity if the artifact came from an unintended source.
  3. If the identity includes workflow ref/sha, ensure the expectation matches the sigstore SAN format (e.g. https://github.com/org/repo/.github/workflows/wf.yml@refs/heads/main) or relax to the repo-level URI.
  4. Verify the trusted root corresponds to the OIDC provider that issued the signing token.

Example fix

// before
keyless_identity = "https://github.com/org/other-repo/..."
keyless_oidc_issuer = "https://token.actions.githubusercontent.com"
// after
keyless_identity = "https://github.com/org/repo/.github/workflows/release.yml@refs/tags/v1.0.0"
keyless_oidc_issuer = "https://token.actions.githubusercontent.com"
Defensive patterns

Strategy: validation

Validate before calling

// Before verifying, confirm the expected identity matches the signing workflow:
// expected: "https://github.com/org/repo/.github/workflows/release.yml@refs/tags/v1.0.0"
// issuer:   "https://token.actions.githubusercontent.com"
if !strings.HasPrefix(expectedIdentity, "https://github.com/org/repo/.github/workflows/") {
    return fmt.Errorf("expected identity does not match the signing workflow")
}

Try / catch

err := verifier.Verify(ctx, payloadType, payload, sig)
if err != nil && strings.Contains(err.Error(), "verify keyless certificate identity") {
    // inspect cert SAN/issuer vs configured identity; fail closed, do not retry
}

Prevention

When it happens

Trigger: keylessVerifier.Verify -> verifyKeylessCertificate -> identity.Verify(summary) returns mismatch when the certificate's SAN does not equal cfg.KeylessIdentity or its OIDC issuer does not equal cfg.KeylessOIDCIssuer (internal/attestation/sign_keyless.go:75-77).

Common situations: Verifying an artifact signed by a different workflow/repo than configured (e.g. identity set to repo A but signed from repo B); using the wrong OIDC issuer (GitLab vs GitHub); expected identity includes a ref/branch while the cert SAN omits it; case or trailing-slash differences in the issuer URL.

Understand the failure class

Related errors


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