PageSourceSearch

https://ratify.dev/assets/js/36fd341e.9f009bda.js

js ratify.dev collected 2026-09-24 19:28:42 UTC 9,433 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkratify=globalThis.webpackChunkratify||[]).push([[3253],{28453(e,n,i){i.d(n,{R:()=>l,x:()=>o});var t=i(96540);const s={},a=t.createContext(s);function l(e){const n=t.useContext(a);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),t.createElement(a.Provider,{value:n},e.children)}},82973(e,n,i){i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"quickstarts/working-with-spdx","title":"Working with SPDX","description":"SPDX is a popular specification for representing software bill of material (SBoM) information. Once an SBoM has been","source":"@site/versioned_docs/version-1.1/quickstarts/working-with-spdx.md","sourceDirName":"quickstarts","slug":"/quickstarts/working-with-spdx","permalink":"/docs/1.1/quickstarts/working-with-spdx","draft":false,"unlisted":false,"editUrl":"https://github.com/ratify-project/ratify-web/blob/main/versioned_docs/version-1.1/quickstarts/working-with-spdx.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"tutorialSidebar","previous":{"title":"Ratify with Venafi CodeSign Protect","permalink":"/docs/1.1/quickstarts/ratify-with-venafi"},"next":{"title":"Reference","permalink":"/docs/1.1/category/reference"}}');var s=i(74848),a=i(28453);const l={},o="Working with SPDX",r={},c=[{value:"Setup",id:"setup",level:2},{value:"Build the Image",id:"build-the-image",level:2},{value:"Generate the SBoM",id:"generate-the-sbom",level:2},{value:"Push the image and SBoM",id:"push-the-image-and-sbom",level:2},{value:"Validating the SBoM",id:"validating-the-sbom",level:2},{value:"Cleaning Up",id:"cleaning-up",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"working-with-spdx",children:"Working with SPDX"})}),"\n",(0,s.jsxs)(n.p,{children:["SPDX is a popular specification for representing software bill of material (SBoM) information. Once an SBoM has been\ngenerated there are a number of ways to validate the contents. This guide will walk through the steps to generate an\nSBoM from a container image and validate some information from the SBoM using the example ",(0,s.jsx)(n.code,{children:"licensechecker"})," plugin. By\nthe end of this guide you will have:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Built a docker image"}),"\n",(0,s.jsx)(n.li,{children:"Generated an SBoM for that image in SPDX tag-value format"}),"\n",(0,s.jsx)(n.li,{children:"Pushed the SBoM to a registry"}),"\n",(0,s.jsx)(n.li,{children:"Configured Ratify to validate the licenses used in the docker image"}),"\n",(0,s.jsx)(n.li,{children:"Run the validation via the CLI"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For more information on additional metadata that is captured in SPDX visit the ",(0,s.jsx)(n.a,{href:"https://spdx.dev/specifications/",children:"SPDX specification docs"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"setup",children:"Setup"}),"\n",(0,s.jsx)(n.p,{children:"In order to complete this guide you will need some tools."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://www.docker.com/get-started",children:"docker"}),": This tool will be used to build the container image"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/anchore/syft",children:"syft"}),": This tool will be used to generate an SBoM in SPDX tag-value format"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/oras-project/oras",children:"oras"}),": This tool will be used to push the generated SBoM to the registry"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/ratify-project/ratify",children:"ratify"}),": This tool will be used to validate the SBoM"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"You will also need a registry to push your container image and SBoM to. For this guide deploy a local registry with\noras artifacts support:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"docker run --name sbom_demo -d -p 5000:5000 ghcr.io/oras-project/registry:v0.0.3-alpha\n"})}),"\n",(0,s.jsx)(n.h2,{id:"build-the-image",children:"Build the Image"}),"\n",(0,s.jsx)(n.p,{children:"First we need to build the container image we will be using:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"docker build -t localhost:5000/only-spdx:v1 https://github.com/wabbit-networks/net-monitor.git\\#main\n"})}),"\n",(0,s.jsx)(n.h2,{id:"generate-the-sbom",children:"Generate the SBoM"}),"\n",(0,s.jsx)(n.p,{children:"Generate an SPDX SBoM using syft:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"syft -o spdx --file sbom.spdx localhost:5000/only-spdx:v1\n"})}),"\n",(0,s.jsx)(n.h2,{id:"push-the-image-and-sbom",children:"Push the image and SBoM"}),"\n",(0,s.jsx)(n.p,{children:"After building the image and generating the SBoM pu
1sh them to the registry:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"docker push localhost:5000/only-spdx:v1\n\noras attach localhost:5000/only-spdx:v1 \\\n  --artifact-type application/vnd.ratify.spdx.v0 \\\n  --plain-http \\\n  sbom.spdx:application/text\n"})}),"\n",(0,s.jsx)(n.h2,{id:"validating-the-sbom",children:"Validating the SBoM"}),"\n",(0,s.jsx)(n.p,{children:"If you have not done so already, build and install ratify:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"make build\nmake install\n"})}),"\n",(0,s.jsx)(n.p,{children:"Next we will create the config file we will use for validation:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'cat <<\'EOF\' >> spdxconfig.json\n{\n    "store": {\n        "version": "1.0.0",\n        "plugins": [\n            {\n                "name": "oras",\n                "useHttp": true,\n                "localCachePath": "./local_oras_cache"\n            }\n        ]\n    },\n    "policy": {\n        "version": "1.0.0",\n        "plugin": {\n            "name": "configPolicy",\n            "artifactVerificationPolicies": {\n                "application/vnd.ratify.spdx.v0": "all"\n            }\n        }\n    },\n    "verifier": {\n        "version": "1.0.0",\n        "plugins": [\n            {\n                "name": "licensechecker",\n                "artifactTypes": "application/vnd.ratify.spdx.v0",\n                "allowedLicenses": [\n                    "GPL-2.0-only",\n                    "MIT",\n                    "OpenSSL",\n                    "BSD-2-Clause AND BSD-3-Clause",\n                    "Zlib",\n                    "MPL-2.0 AND MIT",\n                    "ISC"\n                ]\n            }\n\n        ]\n\n    }\n}\nEOF\n'})}),"\n",(0,s.jsxs)(n.p,{children:["This config file will only enable the ",(0,s.jsx)(n.code,{children:"licensechecker"})," verifier and configure it to check that only the licenses in the\n",(0,s.jsx)(n.code,{children:"allowedLicenses"})," list are used. Note here that the ",(0,s.jsx)(n.code,{children:"artifactType"})," of the SBoM is arbitrary and can be whatever you\nwant to specify it as so long as you are consistently use it when pushing and validating."]}),"\n",(0,s.jsx)(n.p,{children:"We are now ready to validate our image:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'ratify verify -c spdxconfig.json -s localhost:5000/only-spdx:v1\n\n{\n  "isSuccess": true,\n  "verifierReports": [\n    {\n      "subject": "localhost:5000/only-spdx:v1",\n      "isSuccess": true,\n      "name": "licensechecker",\n      "results": [\n        "License Check: SUCCESS",\n        "All packages have allowed licenses"\n      ]\n    }\n  ]\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Now remove one of the license lines from the config file, for example ",(0,s.jsx)(n.code,{children:"MIT"}),", and run the validation again:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'ratify verify -c spdxconfig.json -s localhost:5000/only-spdx:v1\n\n{\n  "isSuccess": false,\n  "verifierReports": [\n    {\n      "subject": "localhost:5000/only-spdx:v1",\n      "name": "licensechecker",\n      "results": [\n        "License Check: FAILED",\n        "package \'alpine-keys\' has unpermitted license \'MIT\'",\n        "package \'musl-utils\' has unpermitted license \'MIT\'",\n        "package \'musl\' has unpermitted license \'MIT\'"\n      ]\n    }\n  ]\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"We have successfully used Ratify to validate the contents of an SPDX SBoM!"}),"\n",(0,s.jsx)(n.h2,{id:"cleaning-up",children:"Cleaning Up"}),"\n",(0,s.jsx)(n.p,{children:"Remove the registry container, the guide sbom, and the guide config:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"docker container stop sbom_demo\ndocker container rm sbom_demo\n\nrm sbom.spdx\nrm spdxconfig.json\n"})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.