{"record":{"id":"63b937dbbd99566c","repo":"hashicorp/packer","slug":"builder-and-source-policy-checks-require-predicate","errorCode":null,"errorMessage":"builder and source policy checks require predicate type %q, got %q","messagePattern":"builder and source policy checks require predicate type %q, got %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/attestation/verify.go","lineNumber":242,"sourceCode":"\t}\n\n\tif statement.Type != internalprovenance.StatementType {\n\t\treturn nil, fmt.Errorf(\"unexpected attestation statement type %q\", statement.Type)\n\t}\n\n\tif policy.PredicateType != \"\" && statement.PredicateType != policy.PredicateType {\n\t\treturn nil, fmt.Errorf(\"attestation predicate type %q does not match expected %q\", statement.PredicateType, policy.PredicateType)\n\t}\n\n\tif policy.ArtifactPath != \"\" {\n\t\tif err := verifyArtifactSubject(statement.Subject, policy.ArtifactPath); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif policy.BuilderID != \"\" || policy.SourceURI != \"\" {\n\t\tif statement.PredicateType != internalprovenance.SLSAProvenanceV1PredicateType {\n\t\t\treturn nil, fmt.Errorf(\"builder and source policy checks require predicate type %q, got %q\", internalprovenance.SLSAProvenanceV1PredicateType, statement.PredicateType)\n\t\t}\n\n\t\tvar typedStatement struct {\n\t\t\tType          string                                     `json:\"_type\"`\n\t\t\tSubject       []internalprovenance.Subject               `json:\"subject\"`\n\t\t\tPredicateType string                                     `json:\"predicateType\"`\n\t\t\tPredicate     internalprovenance.SLSAProvenancePredicate `json:\"predicate\"`\n\t\t}\n\t\tif err := json.Unmarshal(payload, &typedStatement); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"decode SLSA predicate for policy verification: %w\", err)\n\t\t}\n\n\t\tif policy.BuilderID != \"\" && typedStatement.Predicate.RunDetails.Builder.ID != policy.BuilderID {\n\t\t\treturn nil, fmt.Errorf(\"attestation builder id %q does not match expected %q\", typedStatement.Predicate.RunDetails.Builder.ID, policy.BuilderID)\n\t\t}\n\n\t\tif policy.SourceURI != \"\" {\n\t\t\tmatched := false","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/attestation/verify.go#L224-L260","documentation":"Builder-ID and Source-URI policy checks are only implemented for SLSA provenance v1, whose predicate carries buildDefinition.resolvedDependencies and runDetails.builder.id. This error means the policy asked for builder or source checks but the attestation's predicateType is not https://slsa.dev/provenance/v1.","triggerScenarios":"VerifyAttestationFile with a policy that sets BuilderID or SourceURI while the attestation predicateType is empty, a non-SLSA predicate, or SLSA provenance v0.2.","commonSituations":"Enforcing builder/source policy against attestations produced by older CI tooling emitting v0.2 provenance; policy applied to generic in-toto attestations (e.g. SBOM) that have no provenance predicate; typo'd predicateType in the producing pipeline.","solutions":["Regenerate the attestation with a builder that emits https://slsa.dev/provenance/v1 provenance.","Remove the BuilderID/SourceURI fields from the policy if you only need predicate/subject checks for non-v1 attestations.","If your attestation is v0.2, normalize/convert it to v1 before verification.","Verify the producing pipeline's predicateType URI is exactly https://slsa.dev/provenance/v1 (no trailing slash or version typos)."],"exampleFix":"// policy: builder check on a v0.2 attestation fails\n// before\npolicy.SourceURI = \"git+https://github.com/org/repo@refs/heads/main\" // attestation is provenance/v0.2\n// after: upgrade producer or use a v1 provenance attestation\n{\"_type\":\"https://in-toto.io/Statement/v1\",\"predicateType\":\"https://slsa.dev/provenance/v1\",...}","handlingStrategy":"validation","validationCode":"if (policy.BuilderID != \"\" || policy.SourceURI != \"\") {\n\tvar s struct{ PredicateType string `json:\"predicateType\"` }\n\t_ = json.Unmarshal(payload, &s)\n\tif s.PredicateType != \"https://slsa.dev/provenance/v1\" {\n\t\treturn fmt.Errorf(\"builder/source checks need SLSA v1, got %q\", s.PredicateType)\n\t}\n}","typeGuard":"func isSLSAProvenanceV1(payload []byte) bool {\n\tvar s struct{ PredicateType string `json:\"predicateType\"` }\n\treturn json.Unmarshal(payload, &s) == nil && s.PredicateType == \"https://slsa.dev/provenance/v1\"\n}","tryCatchPattern":"_, err := VerifyAttestationFile(path, policy)\nif err != nil && strings.Contains(err.Error(), \"builder and source policy checks require\") {\n\t// either upgrade producer to SLSA v1 or drop BuilderID/SourceURI from policy\n}","preventionTips":["Only set BuilderID/SourceURI in policy for attestations you know are SLSA v1","Upgrade CI provenance generation to slsa.dev/provenance/v1","Validate attestation predicate version before applying builder/source policy"],"tags":["attestation","slsa","policy"],"backgroundTag":"slsa-provenance-version-unsupported","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"}