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
- 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.
- Re-sign the artifact from the intended workflow/identity if the artifact came from an unintended source.
- 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.
- 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
- Copy the identity/issuer values from a known-good Rekor entry or `cosign verify` output for the same artifact.
- Pin the full workflow ref in keyless_identity, or use the repo-level SAN prefix consistently.
- Use the issuer URL that matches the CI system that signed (GitHub vs GitLab).
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
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- build keyless identity policy: %w
- create keyless verifier: %w
- sign payload with keyless signer: %w
- build Sigstore bundle: %w
- static certificate provider is missing a certificate
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/bd73789d9fafdcda.
Report an issue: GitHub.