{"record":{"id":"43bfbea3067bbf2a","repo":"hashicorp/packer","slug":"load-keyless-trusted-root-w","errorCode":null,"errorMessage":"load keyless trusted root: %w","messagePattern":"load keyless trusted root: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/attestation/sign_keyless.go","lineNumber":164,"sourceCode":"\t}, nil\n}\n\nfunc (s *keylessSigner) SignBundle(ctx context.Context, payloadType string, payload []byte, cfg BackendConfig) (Envelope, []byte, error) {\n\tcontent := &sigstoregosign.DSSEData{Data: payload, PayloadType: payloadType}\n\toptions := sigstoregosign.BundleOptions{\n\t\tCertificateProvider: staticCertificateProvider{certDER: append([]byte(nil), s.cert.Raw...)},\n\t\tContext:             ctx,\n\t}\n\n\tif cfg.UploadTlog {\n\t\trekorURL := strings.TrimSpace(cfg.RekorURL)\n\t\tif rekorURL == \"\" {\n\t\t\trekorURL = defaultRekorURL\n\t\t}\n\n\t\ttrustedMaterial, err := loadKeylessTrustedMaterial(cfg)\n\t\tif err != nil {\n\t\t\treturn Envelope{}, nil, fmt.Errorf(\"load keyless trusted root: %w\", err)\n\t\t}\n\n\t\toptions.TransparencyLogs = []sigstoregosign.Transparency{newKeylessRekor(rekorURL)}\n\t\toptions.TrustedRoot = trustedMaterial\n\t}\n\n\tprotobufBundle, err := newKeylessBundle(content, s.keypair, options)\n\tif err != nil {\n\t\treturn Envelope{}, nil, fmt.Errorf(\"build Sigstore bundle: %w\", err)\n\t}\n\n\tbundleWrapper, err := sigstorebundle.NewBundle(protobufBundle)\n\tif err != nil {\n\t\treturn Envelope{}, nil, fmt.Errorf(\"decode Sigstore bundle: %w\", err)\n\t}\n\n\tbundleEnvelope, err := bundleWrapper.Envelope()\n\tif err != nil {","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/attestation/sign_keyless.go#L146-L182","documentation":"When cfg.UploadTlog is true, SignBundle needs Sigstore trusted root material (Fulcio CA certs, CT logs, tlog keys) to build the Rekor bundle. loadKeylessTrustedMaterial either fetches the public Sigstore root from the network (sigstoreroot.FetchTrustedRoot) or loads it from cfg.TrustedRootPath; any failure there is wrapped as 'load keyless trusted root'. This is typically a network/offline problem or a missing/invalid trusted-root JSON file.","triggerScenarios":"SignBundle called with cfg.UploadTlog=true and either (a) cfg.TrustedRootPath empty and FetchTrustedRoot fails (network unreachable, sigstore.org down, proxy blocks https://tuf-rekor-cdn.sigstore.dev or fulcio/rekor TUF metadata), or (b) TrustedRootPath set and the file does not exist or is not valid trusted-root JSON (internal/attestation/sign_keyless.go:162-164).","commonSituations":"CI job without internet egress trying to upload to Rekor; corporate proxy/SSL interception breaking TUF fetch; mistyped or stale trusted_root_path pointing at an old/renamed trusted root bundle; air-gapped environment lacking a vendored trusted root.","solutions":["If offline, set cfg.TrustedRootPath (trusted_root_path) to a locally cached trusted-root JSON (obtain via sigstore-go or cosign's trusted-root output) instead of relying on FetchTrustedRoot","If online, verify network egress to sigstore.dev TUF/CDN endpoints and any HTTPS proxy CA configuration","Validate the file at cfg.TrustedRootPath exists, is readable, and is a valid Sigstore trusted root (JSON with trustedRoot field)","If transparency-log upload is not required, set cfg.UploadTlog=false to skip trusted-root loading entirely"],"exampleFix":"// before\ncfg := BackendConfig{UploadTlog: true} // no TrustedRootPath: needs network\n// after\ncfg := BackendConfig{UploadTlog: true, TrustedRootPath: \"/etc/sigstore/trusted_root.json\"}","handlingStrategy":"fallback","validationCode":"path := strings.TrimSpace(cfg.TrustedRootPath)\nif path == \"\" {\n\t// ensure network egress to sigstore TUF endpoints or pre-fetch a local copy\n\tif err := tryFetchTrustedRoot(context.Background()); err != nil {\n\t\treturn fmt.Errorf(\"cannot fetch Sigstore trusted root; set trusted_root_path: %w\", err)\n\t}\n} else if _, err := os.Stat(path); err != nil {\n\treturn fmt.Errorf(\"trusted root file missing: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"envelope, bundle, err := signer.SignBundle(ctx, ptype, payload, cfg)\nif err != nil && strings.Contains(err.Error(), \"load keyless trusted root\") {\n\tcfg.TrustedRootPath = \"/etc/sigstore/trusted_root.json\" // local fallback\n\tenvelope, bundle, err = signer.SignBundle(ctx, ptype, payload, cfg)\n}","preventionTips":["Vendored trusted-root file for CI/air-gapped environments via trusted_root_path","Validate the trusted root file parses after Sigstore root rotations","Set UploadTlog=false when no transparency-log entry is needed"],"tags":["network","sigstore","rekor","trusted-root","offline"],"backgroundTag":"trusted-root-fetch-failed","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}