diff --git a/getting_started/attestations.md b/getting_started/attestations.md index bc32029..5156461 100644 --- a/getting_started/attestations.md +++ b/getting_started/attestations.md @@ -306,6 +306,50 @@ Currently, we support the following types of evidence: Nothing in the SBOM is checked against the artifact. It is recorded as reported, so the attestation says what the SBOM claims, not whether the claim is true. + **What you get depends on the tool, not just the format.** Kosli records what the document + declares, and tools fill the same fields differently. Three differences catch people out. + + *The subject's digest is often absent from CycloneDX.* Kosli reads the subject's SHA-256 + `hashes` entry into `subject.sha256`, in both formats. Syft's SPDX output fills it. Snyk's + and Syft's CycloneDX output does not: both leave `hashes` empty and write the digest into + `version`, where it reads as a version string rather than a checksum. Kosli does not infer + a checksum from a version, so the field is empty for those two. That is the tool's choice + rather than a limit of CycloneDX, so check what yours writes instead of assuming either + way. + + *A digest that is present is not automatically the artifact's.* The subject identifies what + the generator scanned. Point one at a tag and it records whatever that tag resolved to on + that machine. For a multi-architecture image that is a single architecture, and it can be a + local image id rather than a registry digest. Kosli does not check the subject against the + artifact, so a digest that is present can still belong to something else. Compare the two + only where your pipeline pointed the generator at the exact artifact it attests. Otherwise + check it in the pipeline, where the build can fail, rather than in a policy. + + *Package counts are not comparable between formats.* `package_count` counts what each + format calls a package. A CycloneDX component with `type: file` is skipped, while the SPDX + package describing that same file is counted. Syft reports one package for + `kosli_Linux_arm64.rpm` in CycloneDX and two for the same file in SPDX. + + Of the two policy mechanisms, only [Rego](/policy-reference/rego_policy#input-data) can read + these fields. Environment policy expressions expose the artifact's name and fingerprint, + not attestation content. Evaluation copies an attestation's own fields onto its status + entry, so the summary sits under `attestation_data`: + + ```rego + sbom_attestation_name := data.params.sbom_attestation_name + + sbom_describes(artifact) if { + sbom := artifact.attestations_statuses[sbom_attestation_name] + sbom.attestation_data.document.subject.sha256 == artifact.artifact_fingerprint + } + ``` + + A trail-scoped SBOM sits at `trail.compliance_status.attestations_statuses[name]` instead. + + If you narrow the input with `kosli evaluate trail --attestations`, name the SBOM there too, + dot-qualified as `.` for an artifact-scoped one. Anything left out is absent + from the input, and a rule reading it does not match rather than failing. + The CLI refuses an SBOM file larger than 9 MiB, which leaves room for the attestation itself within the 10 MB the server accepts. We are working on raising this.