{"record":{"id":"e15fb70d74d6c3be","repo":"hashicorp/packer","slug":"decode-attestation-statement-w","errorCode":null,"errorMessage":"decode attestation statement: %w","messagePattern":"decode attestation statement: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/attestation/verify.go","lineNumber":223,"sourceCode":"\t}\n\n\treturn false\n}\n\nfunc isRecognizedKMSReference(value string) bool {\n\tfor _, prefix := range []string{\"awskms://\", \"gcpkms://\", \"azurekms://\", \"hashivault://\"} {\n\t\tif strings.HasPrefix(value, prefix) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc verifyPolicy(payload []byte, policy VerificationPolicy) (*internalprovenance.Statement, error) {\n\tvar statement internalprovenance.Statement\n\tif err := json.Unmarshal(payload, &statement); err != nil {\n\t\treturn nil, fmt.Errorf(\"decode attestation statement: %w\", err)\n\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 {","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/attestation/verify.go#L205-L241","documentation":"verifyPolicy wraps the json.Unmarshal failure of the envelope payload into an internalprovenance.Statement as `decode attestation statement: %w`. This runs after signature verification succeeds, so the payload bytes are authentic but not a valid in-toto statement JSON — the structure does not match _type/subject/predicateType/predicate fields or contains type-mismatched values.","triggerScenarios":"An envelope whose decoded payload is not an in-toto Statement (custom payload smuggled past payloadType check is impossible here, but malformed statement JSON is not); statement produced by a different/older schema version with incompatible field types; payload re-encoded with different field names.","commonSituations":"Upstream tool changed the statement schema; hand-crafted attestations in tests with wrong shapes; truncation or re-serialization of the base64 payload during post-processing; mixing provenance formats (e.g. SLSA v0.1 layout) that don't unmarshal into the Statement struct.","solutions":["Decode the base64 payload and inspect it with `jq .` to confirm it is an in-toto statement with correct field types","Re-generate the attestation with a matching version of the signing tooling","Check internalprovenance.Statement field tags against the actual payload keys","If a policy expects SLSA provenance, confirm predicateType is SLSAProvenanceV1PredicateType so the typed decode path is exercised correctly"],"exampleFix":"// before: payload missing _type field\n// {\"subject\":[...],\"predicateType\":\"...\"}\n\n// after: emit a full in-toto statement\n// {\"_type\":\"https://in-toto.io/Statement/v1\",\"subject\":[...],\"predicateType\":\"...\",\"predicate\":{...}}","handlingStrategy":"validation","validationCode":"payload, err := attestation.DecodeEnvelopePayload(envelope)\nif err != nil { return err }\nvar probe struct{ Type string `json:\"_type\"`; PredicateType string `json:\"predicateType\"` }\nif err := json.Unmarshal(payload, &probe); err != nil || probe.Type == \"\" {\n    return fmt.Errorf\"payload is not an in-toto statement\"%w\", err)\n}","typeGuard":"func looksLikeStatement(payload []byte) bool {\n    var s internalprovenance.Statement\n    return json.Unmarshal(payload, &s) == nil && s.Type == internalprovenance.StatementType\n}","tryCatchPattern":"if _, err := attestation.VerifyAttestationFile(ctx, path, cfg, policy); err != nil {\n    if strings.Contains(err.Error(), \"decode attestation statement\") {\n        return fmt.Errorf\"signature is valid but payload is not a recognized statement: %w\", err)\n    }\n    return err\n}","preventionTips":["Only verify statements produced by the same schema version of this toolchain","Round-trip a generated statement through json.Unmarshal in tests before signing","Pin the attestation-producing tool version across signing and verification","Inspect decoded payloads when migrating between SLSA versions"],"tags":["attestation","json","intoto","parsing"],"backgroundTag":"schema-validation-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"}