{"record":{"id":"22e40296f8edd783","repo":"dapr/dapr","slug":"failed-to-extract-spiffe-id-w","errorCode":null,"errorMessage":"failed to extract SPIFFE ID: %w","messagePattern":"failed to extract SPIFFE ID: %w","errorType":"exception","errorClass":"VerificationError","httpStatus":null,"severity":"critical","filePath":"pkg/runtime/wfengine/state/state.go","lineNumber":1203,"sourceCode":"\tif expectedNamespace == \"\" {\n\t\treturn errors.New(\"expectedNamespace must not be empty\")\n\t}\n\tif len(certChainDER) == 0 {\n\t\treturn errors.New(\"certificate chain is empty\")\n\t}\n\n\tcerts, err := x509.ParseCertificates(certChainDER)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse certificate chain: %w\", err)\n\t}\n\tif len(certs) == 0 {\n\t\treturn errors.New(\"no certificates in chain\")\n\t}\n\n\tleaf := certs[0]\n\tspiffeID, err := x509svid.IDFromCert(leaf)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to extract SPIFFE ID: %w\", err)\n\t}\n\n\t// Validate the full SPIFFE path structure: /ns/<namespace>/<app-id>\n\t// Split produces: [\"\", \"ns\", \"<namespace>\", \"<app-id>\"]\n\tsegments := strings.Split(spiffeID.Path(), \"/\")\n\tif len(segments) != 4 || segments[0] != \"\" || segments[1] != \"ns\" || segments[2] == \"\" || segments[3] == \"\" {\n\t\treturn fmt.Errorf(\"SPIFFE ID %q does not match expected path format /ns/<namespace>/<app-id>\", spiffeID)\n\t}\n\tcertNamespace := segments[2]\n\tcertAppID := segments[3]\n\n\tif certNamespace != expectedNamespace {\n\t\treturn fmt.Errorf(\"certificate SPIFFE ID namespace %q does not match expected namespace %q\", certNamespace, expectedNamespace)\n\t}\n\tif certAppID != expectedAppID {\n\t\treturn fmt.Errorf(\"certificate SPIFFE ID app %q does not match expected app %q\", certAppID, expectedAppID)\n\t}\n","sourceCodeStart":1185,"sourceCodeEnd":1221,"githubUrl":"https://github.com/dapr/dapr/blob/74ad41702745709bb15fe2114ff693b8c59bc3cc/pkg/runtime/wfengine/state/state.go#L1185-L1221","documentation":"verifyCertAppIdentity parsed the certificate chain but go-spiffe's x509svid.IDFromCert could not extract a SPIFFE ID from the leaf. Typically the leaf has no URI SAN (or a malformed one), meaning it is not a SPIFFE SVID at all — for example a plain TLS cert was used for workflow signing. Wrapped as 'signing certificate N: failed to extract SPIFFE ID' in the VerificationError.","triggerScenarios":"The leaf certificate in the stored chain lacks a valid spiffe:// URI SAN — issuing workflow signing certs from a CA that does not embed SPIFFE IDs, or using an ordinary TLS certificate as the signing identity.","commonSituations":"Custom/internal CA without SPIFFE support wired into the signing path instead of the workload identity system; cert rotation switching from SVIDs to plain certs; test setups using self-signed TLS certs.","solutions":["Issue signing certificates as proper SPIFFE SVIDs (URI SAN spiffe://<trust-domain>/...) via the workload identity/sentry subsystem","Re-create the workflow so it is signed by the SVID-based identity","Verify the leaf really is the SVID and not an intermediate/CA placed first by mistake"],"exampleFix":"// before: plain TLS cert (no URI SAN) used as signing identity\nleaf := tlsCert.Leaf // CN=myapp, no SPIFFE URI SAN\n\n// after: obtain an SVID from the workload identity subsystem\n// leaf must carry URI SAN: spiffe://example.org/ns/production/orders\nsvid := workloadAPI.FetchX509SVID()","handlingStrategy":"try-catch","validationCode":"// ensure the signing identity is a real SVID before use\nif _, err := x509svid.IDFromCert(leaf); err != nil {\n\treturn fmt.Errorf(\"signing cert is not a SPIFFE SVID (missing URI SAN): %w\", err)\n}","typeGuard":"func isSPIFFEExtractionFailure(err error) bool {\n\tvar ver *wferrors.VerificationError\n\treturn errors.As(err, &ver) && strings.Contains(ver.Error(), \"failed to extract SPIFFE ID\")\n}","tryCatchPattern":"if err := loadAndVerify(); err != nil {\n\tvar ver *wferrors.VerificationError\n\tif errors.As(err, &ver) && strings.Contains(ver.Error(), \"failed to extract SPIFFE ID\") {\n\t\t// a non-SVID cert was used for signing: re-issue from the workload identity subsystem and recreate\n\t}\n\treturn err\n}","preventionTips":["Only use workload-identity-issued SVIDs for workflow signing, never plain TLS certs","Add a CI check that signing certs carry a spiffe:// URI SAN"],"tags":["workflow","signing","spiffe","certificates"],"backgroundTag":null,"analyzedSha":"74ad41702745709bb15fe2114ff693b8c59bc3cc","analyzedAt":"2026-08-16T04:22:26.543Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}