{"id":816,"date":"2026-02-21T16:47:55","date_gmt":"2026-02-21T15:47:55","guid":{"rendered":"https:\/\/secure-pipelines.com\/ci-cd-security\/lab-sbom-pipeline-generate-attest-verify-syft-cosign-2\/"},"modified":"2026-03-25T09:56:11","modified_gmt":"2026-03-25T08:56:11","slug":"lab-sbom-pipeline-generate-attest-verify-syft-cosign","status":"publish","type":"post","link":"https:\/\/secure-pipelines.com\/ar\/ci-cd-security\/lab-sbom-pipeline-generate-attest-verify-syft-cosign\/","title":{"rendered":"\u0645\u062e\u062a\u0628\u0631: \u0628\u0646\u0627\u0621 \u062e\u0637 \u0623\u0646\u0627\u0628\u064a\u0628 SBOM \u2014 \u0627\u0644\u062a\u0648\u0644\u064a\u062f \u0648\u0627\u0644\u062a\u0635\u062f\u064a\u0642 \u0648\u0627\u0644\u062a\u062d\u0642\u0642 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 Syft \u0648Cosign"},"content":{"rendered":"<h2>\u0646\u0638\u0631\u0629 \u0639\u0627\u0645\u0629<\/h2>\n<p>\u0623\u0635\u0628\u062d\u062a \u0642\u0648\u0627\u0626\u0645 \u0645\u0643\u0648\u0646\u0627\u062a \u0627\u0644\u0628\u0631\u0645\u062c\u064a\u0627\u062a (SBOMs) \u0628\u0633\u0631\u0639\u0629 \u0639\u0646\u0635\u0631\u064b\u0627 \u0625\u0644\u0632\u0627\u0645\u064a\u064b\u0627 \u0644\u0634\u0641\u0627\u0641\u064a\u0629 \u0633\u0644\u0633\u0644\u0629 \u062a\u0648\u0631\u064a\u062f \u0627\u0644\u0628\u0631\u0645\u062c\u064a\u0627\u062a. \u062a\u062a\u0637\u0644\u0628 \u0627\u0644\u0623\u0648\u0627\u0645\u0631 \u0627\u0644\u062a\u0646\u0641\u064a\u0630\u064a\u0629 \u0648\u0627\u0644\u0623\u0637\u0631 \u0627\u0644\u062a\u0646\u0638\u064a\u0645\u064a\u0629 \u0645\u062b\u0644 NIST SSDF \u0648\u0627\u0644\u0645\u0639\u0627\u064a\u064a\u0631 \u0627\u0644\u0635\u0646\u0627\u0639\u064a\u0629 \u0627\u0644\u0622\u0646 \u0645\u0646 \u0627\u0644\u0645\u0624\u0633\u0633\u0627\u062a \u0625\u0646\u062a\u0627\u062c \u0648\u062a\u0648\u0632\u064a\u0639 \u0648\u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 SBOMs \u0644\u0643\u0644 \u0625\u0635\u062f\u0627\u0631 \u0628\u0631\u0645\u062c\u064a. \u062a\u0633\u0631\u062f SBOM \u0643\u0644 \u0645\u0643\u0648\u0646 \u0648\u0645\u0643\u062a\u0628\u0629 \u0648\u062a\u0628\u0639\u064a\u0629 \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u062c\u0643 \u2014 \u0645\u0645\u0627 \u064a\u0645\u0646\u062d \u0627\u0644\u0645\u0633\u062a\u0647\u0644\u0643\u064a\u0646 \u0627\u0644\u0642\u062f\u0631\u0629 \u0639\u0644\u0649 \u062a\u0642\u064a\u064a\u0645 \u0627\u0644\u0645\u062e\u0627\u0637\u0631 \u0648\u062a\u062a\u0628\u0639 \u0627\u0644\u062b\u063a\u0631\u0627\u062a \u0648\u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0627\u0644\u0645\u0635\u062f\u0631.<\/p>\n<p>\u0641\u064a \u0647\u0630\u0627 \u0627\u0644\u0645\u062e\u062a\u0628\u0631 \u0627\u0644\u0639\u0645\u0644\u064a\u060c \u0633\u062a\u0628\u0646\u064a <strong>\u062e\u0637 \u0623\u0646\u0627\u0628\u064a\u0628 SBOM \u0643\u0627\u0645\u0644<\/strong> \u0645\u0646 \u0627\u0644\u0635\u0641\u0631. \u0628\u0646\u0647\u0627\u064a\u0629 \u0647\u0630\u0627 \u0627\u0644\u0645\u062e\u062a\u0628\u0631\u060c \u0633\u062a\u0643\u0648\u0646 \u0642\u0627\u062f\u0631\u064b\u0627 \u0639\u0644\u0649:<\/p>\n<ul>\n<li>\u062a\u0648\u0644\u064a\u062f SBOMs \u0628\u062a\u0646\u0633\u064a\u0642\u064a SPDX \u0648CycloneDX \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 <strong>Syft<\/strong><\/li>\n<li>\u0641\u062d\u0635 SBOMs \u0628\u062d\u062b\u064b\u0627 \u0639\u0646 \u0627\u0644\u062b\u063a\u0631\u0627\u062a \u0627\u0644\u0645\u0639\u0631\u0648\u0641\u0629 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 <strong>Grype<\/strong><\/li>\n<li>\u0625\u0631\u0641\u0627\u0642 SBOMs \u0643\u062a\u0635\u062f\u064a\u0642\u0627\u062a \u0645\u0648\u0642\u0639\u0629 \u0644\u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 <strong>Cosign<\/strong><\/li>\n<li>\u0623\u062a\u0645\u062a\u0629 \u0633\u064a\u0631 \u0627\u0644\u0639\u0645\u0644 \u0628\u0627\u0644\u0643\u0627\u0645\u0644 \u0641\u064a <strong>GitHub Actions<\/strong> \u0648<strong>GitLab CI<\/strong><\/li>\n<li>\u0641\u0631\u0636 \u0645\u062a\u0637\u0644\u0628\u0627\u062a \u062a\u0635\u062f\u064a\u0642 SBOM \u0639\u0646\u062f \u0627\u0644\u0646\u0634\u0631 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 <strong>Kyverno<\/strong><\/li>\n<li>\u0645\u0642\u0627\u0631\u0646\u0629 SBOMs \u0628\u064a\u0646 \u0627\u0644\u0625\u0635\u062f\u0627\u0631\u0627\u062a \u0644\u0627\u0643\u062a\u0634\u0627\u0641 \u062a\u063a\u064a\u064a\u0631\u0627\u062a \u0627\u0644\u062a\u0628\u0639\u064a\u0627\u062a<\/li>\n<\/ul>\n<p>\u064a\u062d\u0627\u0643\u064a \u0647\u0630\u0627 \u0627\u0644\u0645\u062e\u062a\u0628\u0631 \u0633\u064a\u0631 \u0627\u0644\u0639\u0645\u0644 \u0627\u0644\u0625\u0646\u062a\u0627\u062c\u064a \u0627\u0644\u062d\u0642\u064a\u0642\u064a \u0627\u0644\u0630\u064a \u062a\u0633\u062a\u062e\u062f\u0645\u0647 \u0627\u0644\u0641\u0631\u0642 \u0627\u0644\u062a\u064a \u062a\u062a\u0628\u0646\u0649 SLSA \u0648in-toto \u0648\u0623\u0645\u0627\u0646 \u0633\u0644\u0633\u0644\u0629 \u0627\u0644\u062a\u0648\u0631\u064a\u062f \u0627\u0644\u0645\u0628\u0646\u064a \u0639\u0644\u0649 Sigstore.<\/p>\n<h2>\u0627\u0644\u0645\u062a\u0637\u0644\u0628\u0627\u062a \u0627\u0644\u0623\u0633\u0627\u0633\u064a\u0629<\/h2>\n<p>\u0642\u0628\u0644 \u0627\u0644\u0628\u062f\u0621\u060c \u062a\u0623\u0643\u062f \u0645\u0646 \u062a\u062b\u0628\u064a\u062a \u0648\u062a\u0643\u0648\u064a\u0646 \u0627\u0644\u0623\u062f\u0648\u0627\u062a \u0627\u0644\u062a\u0627\u0644\u064a\u0629:<\/p>\n<table>\n<thead>\n<tr>\n<th>\u0627\u0644\u0623\u062f\u0627\u0629<\/th>\n<th>\u0627\u0644\u063a\u0631\u0636<\/th>\n<th>\u0627\u0644\u062a\u062b\u0628\u064a\u062a<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>Syft<\/strong><\/td>\n<td>\u062a\u0648\u0644\u064a\u062f SBOM<\/td>\n<td><code>curl -sSfL https:\/\/raw.githubusercontent.com\/anchore\/syft\/main\/install.sh | sh -s -- -b \/usr\/local\/bin<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>Grype<\/strong><\/td>\n<td>\u0641\u062d\u0635 \u0627\u0644\u062b\u063a\u0631\u0627\u062a<\/td>\n<td><code>curl -sSfL https:\/\/raw.githubusercontent.com\/anchore\/grype\/main\/install.sh | sh -s -- -b \/usr\/local\/bin<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>Cosign<\/strong><\/td>\n<td>\u0627\u0644\u062a\u0648\u0642\u064a\u0639 \u0648\u0627\u0644\u062a\u0635\u062f\u064a\u0642<\/td>\n<td><code>go install github.com\/sigstore\/cosign\/v2\/cmd\/cosign@latest<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>Docker<\/strong><\/td>\n<td>\u0628\u0646\u0627\u0621 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a<\/td>\n<td><a href=\"https:\/\/docs.docker.com\/get-docker\/\" target=\"_blank\" rel=\"noopener\">docs.docker.com<\/a><\/td>\n<\/tr>\n<tr>\n<td><strong>GitHub CLI (gh)<\/strong><\/td>\n<td>\u0627\u0644\u0648\u0635\u0648\u0644 \u0625\u0644\u0649 \u0627\u0644\u0645\u0633\u062a\u0648\u062f\u0639 \u0648GHCR<\/td>\n<td><code>brew install gh<\/code> \u0623\u0648 <a href=\"https:\/\/cli.github.com\/\" target=\"_blank\" rel=\"noopener\">cli.github.com<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u062a\u062d\u062a\u0627\u062c \u0623\u064a\u0636\u064b\u0627 \u0625\u0644\u0649 <strong>\u062d\u0633\u0627\u0628 GitHub<\/strong> \u0645\u0639 \u0625\u0645\u0643\u0627\u0646\u064a\u0629 \u0627\u0644\u0648\u0635\u0648\u0644 \u0625\u0644\u0649 GitHub Container Registry (GHCR)\u060c \u0648\u062a\u0637\u0628\u064a\u0642 \u0623\u0633\u0627\u0633\u064a \u064a\u062d\u062a\u0648\u064a \u0639\u0644\u0649 <code>Dockerfile<\/code>.<\/p>\n<h2>\u0625\u0639\u062f\u0627\u062f \u0627\u0644\u0628\u064a\u0626\u0629<\/h2>\n<p>\u0633\u0646\u0646\u0634\u0626 \u062a\u0637\u0628\u064a\u0642 Node.js \u0628\u0633\u064a\u0637\u060c \u0648\u0646\u062d\u0648\u0644\u0647 \u0625\u0644\u0649 \u062d\u0627\u0648\u064a\u0629\u060c \u0648\u0646\u062f\u0641\u0639\u0647 \u0625\u0644\u0649 GHCR. \u062a\u0635\u0628\u062d \u0647\u0630\u0647 \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0647\u062f\u0641 \u0644\u062c\u0645\u064a\u0639 \u062a\u0645\u0627\u0631\u064a\u0646 SBOM \u0627\u0644\u0644\u0627\u062d\u0642\u0629.<\/p>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 1: \u0625\u0646\u0634\u0627\u0621 \u0645\u0633\u062a\u0648\u062f\u0639 \u0627\u0644\u0627\u062e\u062a\u0628\u0627\u0631<\/h3>\n<pre><code class=\"language-bash\">mkdir sbom-pipeline-lab &amp;&amp; cd sbom-pipeline-lab\ngit init\n<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 2: \u0625\u0646\u0634\u0627\u0621 \u062a\u0637\u0628\u064a\u0642 Node.js \u0628\u0633\u064a\u0637<\/h3>\n<pre><code class=\"language-bash\">cat &gt; package.json &lt;&lt;'EOF'\n{\n  \"name\": \"sbom-lab-app\",\n  \"version\": \"1.0.0\",\n  \"description\": \"SBOM pipeline lab application\",\n  \"main\": \"server.js\",\n  \"dependencies\": {\n    \"express\": \"^4.18.2\",\n    \"lodash\": \"^4.17.21\",\n    \"axios\": \"^1.6.0\"\n  }\n}\nEOF\n<\/code><\/pre>\n<pre><code class=\"language-bash\">cat &gt; server.js &lt;&lt;'EOF'\nconst express = require('express');\nconst app = express();\n\napp.get('\/', (req, res) =&gt; {\n  res.json({ status: 'ok', message: 'SBOM Pipeline Lab' });\n});\n\napp.listen(3000, () =&gt; console.log('Listening on port 3000'));\nEOF\n<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 3: \u0625\u0646\u0634\u0627\u0621 Dockerfile<\/h3>\n<pre><code class=\"language-dockerfile\">FROM node:20-alpine\nWORKDIR \/app\nCOPY package*.json .\/\nRUN npm install --production\nCOPY . .\nEXPOSE 3000\nCMD [\"node\", \"server.js\"]\n<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 4: \u0628\u0646\u0627\u0621 \u0635\u0648\u0631\u0629 \u0627\u0644\u062d\u0627\u0648\u064a\u0629 \u0648\u062f\u0641\u0639\u0647\u0627<\/h3>\n<pre><code class=\"language-bash\"># \u0627\u0644\u0645\u0635\u0627\u062f\u0642\u0629 \u0639\u0644\u0649 GHCR\necho $GITHUB_TOKEN | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin\n\n# \u0628\u0646\u0627\u0621 \u0627\u0644\u0635\u0648\u0631\u0629\ndocker build -t ghcr.io\/YOUR_GITHUB_USERNAME\/sbom-lab-app:v1.0.0 .\n\n# \u0627\u0644\u062f\u0641\u0639 \u0625\u0644\u0649 GHCR\ndocker push ghcr.io\/YOUR_GITHUB_USERNAME\/sbom-lab-app:v1.0.0\n<\/code><\/pre>\n<p>\u0627\u0633\u062a\u0628\u062f\u0644 <code>YOUR_GITHUB_USERNAME<\/code> \u0628\u0627\u0633\u0645 \u0645\u0633\u062a\u062e\u062f\u0645 GitHub \u0627\u0644\u0641\u0639\u0644\u064a \u0627\u0644\u062e\u0627\u0635 \u0628\u0643 \u0641\u064a \u062c\u0645\u064a\u0639 \u0623\u0646\u062d\u0627\u0621 \u0647\u0630\u0627 \u0627\u0644\u0645\u062e\u062a\u0628\u0631. \u0628\u0639\u062f \u0627\u0643\u062a\u0645\u0627\u0644 \u0627\u0644\u062f\u0641\u0639\u060c \u0633\u062c\u0644 \u0645\u0644\u062e\u0635 \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0643\u0627\u0645\u0644 \u2014 \u0633\u062a\u062d\u062a\u0627\u062c \u0625\u0644\u064a\u0647 \u0644\u0639\u0645\u0644\u064a\u0627\u062a \u0627\u0644\u062a\u0648\u0642\u064a\u0639.<\/p>\n<pre><code class=\"language-bash\"># \u0627\u0644\u062a\u0642\u0627\u0637 \u0645\u0644\u062e\u0635 \u0627\u0644\u0635\u0648\u0631\u0629\nexport IMAGE=$(docker inspect --format='{{index .RepoDigests 0}}' ghcr.io\/YOUR_GITHUB_USERNAME\/sbom-lab-app:v1.0.0)\necho $IMAGE\n# Output: ghcr.io\/YOUR_GITHUB_USERNAME\/sbom-lab-app@sha256:abc123...\n<\/code><\/pre>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 1: \u062a\u0648\u0644\u064a\u062f SBOM \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 Syft<\/h2>\n<p>Syft \u0647\u064a \u0623\u062f\u0627\u0629 \u0645\u0641\u062a\u0648\u062d\u0629 \u0627\u0644\u0645\u0635\u062f\u0631 \u0645\u0646 Anchore \u062a\u0648\u0644\u062f SBOMs \u0639\u0646 \u0637\u0631\u064a\u0642 \u062a\u062d\u0644\u064a\u0644 \u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a \u0648\u0623\u0646\u0638\u0645\u0629 \u0627\u0644\u0645\u0644\u0641\u0627\u062a \u0648\u0627\u0644\u0623\u0631\u0634\u064a\u0641\u0627\u062a. \u062a\u062f\u0639\u0645 \u062a\u0646\u0633\u064a\u0642\u0627\u062a \u0625\u062e\u0631\u0627\u062c \u0645\u062a\u0639\u062f\u062f\u0629 \u0628\u0645\u0627 \u0641\u064a \u0630\u0644\u0643 SPDX \u0648CycloneDX \u2014 \u0627\u0644\u0645\u0639\u064a\u0627\u0631\u0627\u0646 \u0627\u0644\u0645\u0647\u064a\u0645\u0646\u0627\u0646 \u0644\u0640 SBOM.<\/p>\n<h3>\u062a\u0648\u0644\u064a\u062f SBOM \u0628\u062a\u0646\u0633\u064a\u0642 SPDX<\/h3>\n<pre><code class=\"language-bash\">syft $IMAGE -o spdx-json=sbom.spdx.json\n<\/code><\/pre>\n<p>\u0641\u062d\u0635 \u0627\u0644\u0645\u062e\u0631\u062c\u0627\u062a:<\/p>\n<pre><code class=\"language-bash\">cat sbom.spdx.json | jq '.packages | length'\n# Output: 287 (count varies based on image content)\n\n# \u0639\u0631\u0636 \u0627\u0644\u062d\u0632\u0645 \u0627\u0644\u0645\u0643\u062a\u0634\u0641\u0629\ncat sbom.spdx.json | jq '.packages[] | {name: .name, version: .versionInfo, license: .licenseDeclared}' | head -40\n<\/code><\/pre>\n<h3>\u062a\u0648\u0644\u064a\u062f SBOM \u0628\u062a\u0646\u0633\u064a\u0642 CycloneDX<\/h3>\n<pre><code class=\"language-bash\">syft $IMAGE -o cyclonedx-json=sbom.cyclonedx.json\n<\/code><\/pre>\n<p>\u0641\u062d\u0635 \u0645\u062e\u0631\u062c\u0627\u062a CycloneDX:<\/p>\n<pre><code class=\"language-bash\">cat sbom.cyclonedx.json | jq '.components | length'\n\n# \u0639\u0631\u0636 \u0627\u0644\u0645\u0643\u0648\u0646\u0627\u062a \u0645\u0639 \u0627\u0644\u062a\u0631\u0627\u062e\u064a\u0635\ncat sbom.cyclonedx.json | jq '.components[] | {name: .name, version: .version, type: .type}' | head -40\n<\/code><\/pre>\n<h3>SPDX \u0645\u0642\u0627\u0628\u0644 CycloneDX: \u0627\u0644\u0641\u0631\u0648\u0642 \u0627\u0644\u0631\u0626\u064a\u0633\u064a\u0629<\/h3>\n<table>\n<thead>\n<tr>\n<th>\u0627\u0644\u0645\u064a\u0632\u0629<\/th>\n<th>SPDX<\/th>\n<th>CycloneDX<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>\u0627\u0644\u0623\u0635\u0644<\/strong><\/td>\n<td>Linux Foundation<\/td>\n<td>OWASP<\/td>\n<\/tr>\n<tr>\n<td><strong>\u0627\u0644\u062a\u0631\u0643\u064a\u0632 \u0627\u0644\u0623\u0633\u0627\u0633\u064a<\/strong><\/td>\n<td>\u0627\u0644\u0627\u0645\u062a\u062b\u0627\u0644 \u0644\u0644\u062a\u0631\u0627\u062e\u064a\u0635 \u0648\u0627\u0644\u0645\u0644\u0643\u064a\u0629 \u0627\u0644\u0641\u0643\u0631\u064a\u0629<\/td>\n<td>\u0627\u0644\u0623\u0645\u0627\u0646 \u0648\u062a\u062d\u0644\u064a\u0644 \u0627\u0644\u0645\u062e\u0627\u0637\u0631<\/td>\n<\/tr>\n<tr>\n<td><strong>\u0645\u0639\u064a\u0627\u0631 ISO<\/strong><\/td>\n<td>ISO\/IEC 5962:2021<\/td>\n<td>ECMA-424<\/td>\n<\/tr>\n<tr>\n<td><strong>\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u062b\u063a\u0631\u0627\u062a<\/strong><\/td>\n<td>\u062f\u0639\u0645 \u0623\u0635\u0644\u064a \u0645\u062d\u062f\u0648\u062f<\/td>\n<td>\u062d\u0642\u0644 <code>vulnerabilities<\/code> \u0645\u0646 \u0627\u0644\u062f\u0631\u062c\u0629 \u0627\u0644\u0623\u0648\u0644\u0649<\/td>\n<\/tr>\n<tr>\n<td><strong>\u0627\u0644\u062a\u0646\u0633\u064a\u0642\u0627\u062a<\/strong><\/td>\n<td>JSON, RDF, XML, YAML, tag-value<\/td>\n<td>JSON, XML, Protobuf<\/td>\n<\/tr>\n<tr>\n<td><strong>\u0627\u0644\u0623\u0641\u0636\u0644 \u0644\u0640<\/strong><\/td>\n<td>\u0627\u0644\u0627\u0645\u062a\u062b\u0627\u0644 \u0627\u0644\u062a\u0646\u0638\u064a\u0645\u064a\u060c \u062a\u062f\u0642\u064a\u0642 \u0627\u0644\u062a\u0631\u0627\u062e\u064a\u0635<\/td>\n<td>DevSecOps\u060c \u062a\u062a\u0628\u0639 \u0627\u0644\u062b\u063a\u0631\u0627\u062a<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u0641\u064a \u0647\u0630\u0627 \u0627\u0644\u0645\u062e\u062a\u0628\u0631\u060c \u0646\u0633\u062a\u062e\u062f\u0645 \u0628\u0634\u0643\u0644 \u0623\u0633\u0627\u0633\u064a SPDX JSON \u0644\u0623\u0646\u0647 \u0627\u0644\u062a\u0646\u0633\u064a\u0642 \u0627\u0644\u0645\u0637\u0644\u0648\u0628 \u0645\u0646 \u0642\u0628\u0644 \u0627\u0644\u0639\u062f\u064a\u062f \u0645\u0646 \u0645\u0639\u0627\u064a\u064a\u0631 \u0627\u0644\u0645\u0634\u062a\u0631\u064a\u0627\u062a \u0627\u0644\u062d\u0643\u0648\u0645\u064a\u0629 \u0648\u064a\u062a\u0648\u0627\u0641\u0642 \u0628\u0634\u0643\u0644 \u062c\u064a\u062f \u0645\u0639 \u062a\u0635\u062f\u064a\u0642\u0627\u062a Cosign. \u0648\u0645\u0639 \u0630\u0644\u0643\u060c \u0641\u0625\u0646 \u0643\u0644\u0627 \u0627\u0644\u062a\u0646\u0633\u064a\u0642\u064a\u0646 \u0645\u062f\u0639\u0648\u0645\u0627\u0646 \u0645\u0646 Grype \u0648Cosign.<\/p>\n<h3>\u062a\u0648\u0644\u064a\u062f \u0645\u0644\u062e\u0635 \u0642\u0627\u0628\u0644 \u0644\u0644\u0642\u0631\u0627\u0621\u0629<\/h3>\n<pre><code class=\"language-bash\">syft $IMAGE -o syft-table\n<\/code><\/pre>\n<p>\u064a\u0637\u0628\u0639 \u0647\u0630\u0627 \u062c\u062f\u0648\u0644\u064b\u0627 \u0628\u062c\u0645\u064a\u0639 \u0627\u0644\u062d\u0632\u0645 \u0645\u0639 \u0627\u0644\u0627\u0633\u0645 \u0648\u0627\u0644\u0625\u0635\u062f\u0627\u0631 \u0648\u0627\u0644\u0646\u0648\u0639 \u2014 \u0645\u0641\u064a\u062f \u0644\u0644\u0645\u0631\u0627\u062c\u0639\u0629 \u0627\u0644\u0633\u0631\u064a\u0639\u0629 \u0623\u062b\u0646\u0627\u0621 \u0627\u0644\u062a\u0637\u0648\u064a\u0631.<\/p>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 2: \u0641\u062d\u0635 SBOM \u0628\u062d\u062b\u064b\u0627 \u0639\u0646 \u0627\u0644\u062b\u063a\u0631\u0627\u062a \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 Grype<\/h2>\n<p>Grype \u0647\u0648 \u0645\u0627\u0633\u062d \u0627\u0644\u062b\u063a\u0631\u0627\u062a \u0645\u0646 Anchore. \u064a\u0645\u0643\u0646\u0647 \u0641\u062d\u0635 \u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a \u0645\u0628\u0627\u0634\u0631\u0629\u060c \u0644\u0643\u0646\u0647 \u064a\u0645\u0643\u0646\u0647 \u0623\u064a\u0636\u064b\u0627 \u0641\u062d\u0635 \u0645\u0644\u0641 SBOM \u2014 \u0648\u0647\u0648 \u0623\u0633\u0631\u0639 \u0628\u0634\u0643\u0644 \u0645\u0644\u062d\u0648\u0638 \u0644\u0623\u0646\u0647 \u064a\u062a\u062e\u0637\u0649 \u062e\u0637\u0648\u0629 \u062a\u062d\u0644\u064a\u0644 \u0627\u0644\u0635\u0648\u0631\u0629.<\/p>\n<h3>\u0641\u062d\u0635 SBOM<\/h3>\n<pre><code class=\"language-bash\">grype sbom:.\/sbom.spdx.json\n<\/code><\/pre>\n<p>\u0646\u0645\u0648\u0630\u062c \u0627\u0644\u0645\u062e\u0631\u062c\u0627\u062a:<\/p>\n<pre><code class=\"language-text\">NAME          INSTALLED  FIXED-IN   TYPE  VULNERABILITY   SEVERITY\nlodash        4.17.21               npm   CVE-2025-XXXXX  Medium\nnode          20.10.0    20.11.1    apk   CVE-2024-22019  High\nlibcrypto3    3.1.4-r1   3.1.4-r3   apk   CVE-2024-0727   Medium\n<\/code><\/pre>\n<h3>\u0627\u0644\u062a\u0635\u0641\u064a\u0629 \u062d\u0633\u0628 \u0627\u0644\u062e\u0637\u0648\u0631\u0629<\/h3>\n<pre><code class=\"language-bash\"># \u0639\u0631\u0636 \u0627\u0644\u062b\u063a\u0631\u0627\u062a \u0627\u0644\u062d\u0631\u062c\u0629 \u0648\u0627\u0644\u0639\u0627\u0644\u064a\u0629 \u0641\u0642\u0637\ngrype sbom:.\/sbom.spdx.json --fail-on critical\n\n# \u0625\u062e\u0631\u0627\u062c \u0627\u0644\u0646\u062a\u0627\u0626\u062c \u0628\u062a\u0646\u0633\u064a\u0642 JSON \u0644\u0644\u0645\u0639\u0627\u0644\u062c\u0629 \u0641\u064a CI\ngrype sbom:.\/sbom.spdx.json -o json &gt; vulnerabilities.json\n\n# \u0639\u062f \u0627\u0644\u062b\u063a\u0631\u0627\u062a \u062d\u0633\u0628 \u0627\u0644\u062e\u0637\u0648\u0631\u0629\ncat vulnerabilities.json | jq '[.matches[].vulnerability.severity] | group_by(.) | map({severity: .[0], count: length})'\n<\/code><\/pre>\n<h3>\u0641\u062d\u0635 \u0627\u0644\u0635\u0648\u0631\u0629 \u0645\u0642\u0627\u0628\u0644 \u0641\u062d\u0635 SBOM<\/h3>\n<p>\u0647\u0646\u0627\u0643 \u0641\u0631\u0642 \u0645\u0647\u0645 \u0628\u064a\u0646 \u0641\u062d\u0635 \u0627\u0644\u0635\u0648\u0631\u0629 \u0645\u0628\u0627\u0634\u0631\u0629 \u0648\u0641\u062d\u0635 SBOM:<\/p>\n<pre><code class=\"language-bash\"># \u0641\u062d\u0635 \u0645\u0628\u0627\u0634\u0631 \u0644\u0644\u0635\u0648\u0631\u0629 \u2014 \u064a\u0633\u062d\u0628 Grype \u0637\u0628\u0642\u0627\u062a \u0627\u0644\u0635\u0648\u0631\u0629 \u0648\u064a\u062d\u0644\u0644\u0647\u0627\ngrype $IMAGE\n\n# \u0641\u062d\u0635 SBOM \u2014 \u064a\u0642\u0631\u0623 Grype \u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062d\u0632\u0645 \u0627\u0644\u0645\u0648\u0644\u062f\u0629 \u0645\u0633\u0628\u0642\u064b\u0627\ngrype sbom:.\/sbom.spdx.json\n<\/code><\/pre>\n<table>\n<thead>\n<tr>\n<th>\u0627\u0644\u0646\u0647\u062c<\/th>\n<th>\u0627\u0644\u0633\u0631\u0639\u0629<\/th>\n<th>\u0627\u0644\u062f\u0642\u0629<\/th>\n<th>\u062d\u0627\u0644\u0629 \u0627\u0644\u0627\u0633\u062a\u062e\u062f\u0627\u0645<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u0641\u062d\u0635 \u0645\u0628\u0627\u0634\u0631 \u0644\u0644\u0635\u0648\u0631\u0629<\/td>\n<td>\u0623\u0628\u0637\u0623 (\u064a\u0633\u062d\u0628 \u0627\u0644\u0637\u0628\u0642\u0627\u062a)<\/td>\n<td>\u064a\u0643\u062a\u0634\u0641 \u062c\u0645\u064a\u0639 \u0627\u0644\u062d\u0632\u0645<\/td>\n<td>\u0627\u0644\u062a\u062d\u0644\u064a\u0644 \u0627\u0644\u0623\u0648\u0644\u064a\u060c \u0627\u0644\u062a\u0637\u0648\u064a\u0631 \u0627\u0644\u0645\u062d\u0644\u064a<\/td>\n<\/tr>\n<tr>\n<td>\u0641\u062d\u0635 SBOM<\/td>\n<td>\u0633\u0631\u064a\u0639 (\u064a\u0642\u0631\u0623 \u0645\u0644\u0641 JSON)<\/td>\n<td>\u0645\u062d\u062f\u0648\u062f \u0628\u0645\u062d\u062a\u0648\u064a\u0627\u062a SBOM<\/td>\n<td>\u062e\u0637\u0648\u0637 \u0623\u0646\u0627\u0628\u064a\u0628 CI\u060c \u0627\u0644\u0641\u062d\u0648\u0635\u0627\u062a \u0627\u0644\u0645\u062a\u0643\u0631\u0631\u0629\u060c \u0627\u0644\u062a\u062f\u0642\u064a\u0642<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u0641\u062d\u0635 SBOM \u064a\u0643\u0648\u0646 \u0634\u0627\u0645\u0644\u064b\u0627 \u0628\u0642\u062f\u0631 \u0634\u0645\u0648\u0644\u064a\u0629 SBOM \u0646\u0641\u0633\u0647\u0627. \u0625\u0630\u0627 \u0623\u063a\u0641\u0644 Syft \u062d\u0632\u0645\u0629 \u0645\u0627 (\u0645\u062b\u0644 \u0645\u0644\u0641 \u062b\u0646\u0627\u0626\u064a \u0645\u064f\u062c\u0645\u064e\u0651\u0639 \u0628\u0634\u0643\u0644 \u062b\u0627\u0628\u062a)\u060c \u0641\u0644\u0646 \u064a\u062c\u062f Grype \u062b\u063a\u0631\u0627\u062a \u0644\u0647\u0627. \u0644\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u0623\u0642\u0635\u0649 \u062a\u063a\u0637\u064a\u0629\u060c \u0642\u0645 \u0628\u062a\u0648\u0644\u064a\u062f SBOM \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u062e\u064a\u0627\u0631 <code>--catalogers all<\/code> \u0641\u064a Syft.<\/p>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 3: \u0625\u0631\u0641\u0627\u0642 SBOM \u0643\u062a\u0635\u062f\u064a\u0642 Cosign<\/h2>\n<p>\u0627\u0644\u062a\u0635\u062f\u064a\u0642 \u0647\u0648 \u0628\u064a\u0627\u0646 \u0645\u0648\u0642\u0639 \u062d\u0648\u0644 \u0623\u062f\u0627\u0629 \u0628\u0631\u0645\u062c\u064a\u0629. \u0645\u0646 \u062e\u0644\u0627\u0644 \u0625\u0631\u0641\u0627\u0642 SBOM \u0643\u062a\u0635\u062f\u064a\u0642\u060c \u0641\u0625\u0646\u0643 \u062a\u0631\u0628\u0637 SBOM \u0628\u0634\u0643\u0644 \u062a\u0634\u0641\u064a\u0631\u064a \u0628\u0645\u0644\u062e\u0635 \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0645\u062d\u062f\u062f \u2014 \u064a\u0645\u0643\u0646 \u0644\u0623\u064a \u0634\u062e\u0635 \u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0623\u0646 SBOM \u0642\u062f \u062a\u0645 \u0625\u0646\u062a\u0627\u062c\u0647\u0627 \u0644\u062a\u0644\u0643 \u0627\u0644\u0635\u0648\u0631\u0629 \u0628\u0627\u0644\u062a\u062d\u062f\u064a\u062f \u0648\u0644\u0645 \u064a\u062a\u0645 \u0627\u0644\u062a\u0644\u0627\u0639\u0628 \u0628\u0647\u0627.<\/p>\n<h3>\u0625\u0631\u0641\u0627\u0642 \u062a\u0635\u062f\u064a\u0642 SBOM<\/h3>\n<p>\u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u062a\u062f\u0641\u0642 Cosign \u0628\u062f\u0648\u0646 \u0645\u0641\u0627\u062a\u064a\u062d (Sigstore Fulcio):<\/p>\n<pre><code class=\"language-bash\">cosign attest --predicate sbom.spdx.json \\\n  --type spdxjson \\\n  --yes \\\n  $IMAGE\n<\/code><\/pre>\n<p>\u064a\u0642\u0648\u0645 \u0647\u0630\u0627 \u0627\u0644\u0623\u0645\u0631 \u0628\u0645\u0627 \u064a\u0644\u064a:<\/p>\n<ol>\n<li>\u064a\u0641\u062a\u062d \u0645\u062a\u0635\u0641\u062d\u064b\u0627 \u0644\u0644\u0645\u0635\u0627\u062f\u0642\u0629 \u0639\u0628\u0631 OIDC (\u062a\u0648\u0642\u064a\u0639 \u0628\u062f\u0648\u0646 \u0645\u0641\u0627\u062a\u064a\u062d \u0639\u0628\u0631 Fulcio)<\/li>\n<li>\u064a\u0646\u0634\u0626 \u062a\u0635\u062f\u064a\u0642 in-toto \u0645\u0639 SBOM \u0627\u0644\u062e\u0627\u0635 \u0628\u0643 \u0643\u0645\u0633\u0646\u062f<\/li>\n<li>\u064a\u0648\u0642\u0639 \u0627\u0644\u062a\u0635\u062f\u064a\u0642 \u0648\u064a\u0633\u062c\u0644\u0647 \u0641\u064a \u0633\u062c\u0644 \u0627\u0644\u0634\u0641\u0627\u0641\u064a\u0629 Rekor<\/li>\n<li>\u064a\u062f\u0641\u0639 \u0627\u0644\u062a\u0635\u062f\u064a\u0642 \u0625\u0644\u0649 \u0627\u0644\u0633\u062c\u0644 \u0628\u062c\u0627\u0646\u0628 \u0627\u0644\u0635\u0648\u0631\u0629<\/li>\n<\/ol>\n<h3>\u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0627\u0644\u062a\u0635\u062f\u064a\u0642<\/h3>\n<pre><code class=\"language-bash\">cosign verify-attestation \\\n  --type spdxjson \\\n  --certificate-identity=YOUR_EMAIL@example.com \\\n  --certificate-oidc-issuer=https:\/\/accounts.google.com \\\n  $IMAGE | jq '.payload | @base64d | fromjson | .predicate'\n<\/code><\/pre>\n<p>\u0627\u0633\u062a\u0628\u062f\u0644 \u0647\u0648\u064a\u0629 \u0627\u0644\u0634\u0647\u0627\u062f\u0629 \u0648\u0645\u064f\u0635\u062f\u0631 OIDC \u0628\u0627\u0644\u0642\u064a\u0645 \u0627\u0644\u0645\u0637\u0627\u0628\u0642\u0629 \u0644\u0647\u0648\u064a\u0629 Sigstore \u0627\u0644\u062e\u0627\u0635\u0629 \u0628\u0643. \u0641\u064a \u0628\u064a\u0626\u0627\u062a CI (GitHub Actions)\u060c \u0633\u062a\u0643\u0648\u0646 \u0647\u0630\u0647:<\/p>\n<pre><code class=\"language-bash\">--certificate-identity=https:\/\/github.com\/YOUR_ORG\/YOUR_REPO\/.github\/workflows\/build.yml@refs\/heads\/main\n--certificate-oidc-issuer=https:\/\/token.actions.githubusercontent.com\n<\/code><\/pre>\n<h3>\u0641\u062d\u0635 \u0627\u0644\u062a\u0635\u062f\u064a\u0642 \u0641\u064a \u0627\u0644\u0633\u062c\u0644<\/h3>\n<pre><code class=\"language-bash\"># \u0633\u0631\u062f \u0627\u0644\u0645\u0631\u0627\u062c\u0639 (\u0633\u062c\u0644\u0627\u062a OCI 1.1)\ncosign tree $IMAGE\n<\/code><\/pre>\n<p>\u064a\u062c\u0628 \u0623\u0646 \u062a\u0631\u0649 \u0627\u0644\u062a\u0635\u062f\u064a\u0642 \u0645\u062f\u0631\u062c\u064b\u0627 \u0643\u0645\u0631\u062c\u0639 \u0645\u0631\u0641\u0642 \u0628\u0628\u064a\u0627\u0646 \u0627\u0644\u0635\u0648\u0631\u0629. \u064a\u062a\u0645 \u062a\u062e\u0632\u064a\u0646 \u0627\u0644\u062a\u0635\u062f\u064a\u0642 \u0643\u0623\u062f\u0627\u0629 OCI \u0641\u064a \u0646\u0641\u0633 \u0627\u0644\u0645\u0633\u062a\u0648\u062f\u0639\u060c \u0645\u064f\u0639\u0644\u064e\u0651\u0645 \u0628\u0627\u062a\u0641\u0627\u0642\u064a\u0629 <code>sha256-&lt;digest&gt;.att<\/code>.<\/p>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 4: \u0628\u0646\u0627\u0621 \u062e\u0637 \u0627\u0644\u0623\u0646\u0627\u0628\u064a\u0628 \u0627\u0644\u0643\u0627\u0645\u0644 \u0641\u064a GitHub Actions<\/h2>\n<p>\u0627\u0644\u0622\u0646 \u0646\u0642\u0648\u0645 \u0628\u0623\u062a\u0645\u062a\u0629 \u0643\u0644 \u0634\u064a\u0621 \u0641\u064a \u0633\u064a\u0631 \u0639\u0645\u0644 CI\/CD \u0648\u0627\u062d\u062f. \u064a\u0628\u0646\u064a \u0647\u0630\u0627 \u0627\u0644\u062e\u0637 \u0627\u0644\u0635\u0648\u0631\u0629\u060c \u0648\u064a\u0648\u0644\u062f SBOM\u060c \u0648\u064a\u0641\u062d\u0635 \u0627\u0644\u062b\u063a\u0631\u0627\u062a\u060c \u0648\u064a\u0631\u0641\u0642 SBOM \u0643\u062a\u0635\u062f\u064a\u0642 \u0645\u0648\u0642\u0639.<\/p>\n<p>\u0623\u0646\u0634\u0626 <code>.github\/workflows\/sbom-pipeline.yml<\/code>:<\/p>\n<pre><code class=\"language-yaml\">name: SBOM Pipeline\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\nenv:\n  REGISTRY: ghcr.io\n  IMAGE_NAME: ${{ github.repository }}\n\npermissions:\n  contents: read\n  packages: write\n  id-token: write  # Required for Cosign keyless signing\n  attestations: write\n\njobs:\n  build-and-attest:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions\/checkout@v4\n\n      - name: Set up Docker Buildx\n        uses: docker\/setup-buildx-action@v3\n\n      - name: Log in to GHCR\n        uses: docker\/login-action@v3\n        with:\n          registry: ${{ env.REGISTRY }}\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Build and push image\n        id: build\n        uses: docker\/build-push-action@v5\n        with:\n          context: .\n          push: true\n          tags: ${{ env.REGISTRY }}\/${{ env.IMAGE_NAME }}:${{ github.sha }}\n\n      - name: Get image digest\n        id: digest\n        run: |\n          echo \"image=${{ env.REGISTRY }}\/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}\" &gt;&gt; $GITHUB_OUTPUT\n\n      - name: Install Syft\n        uses: anchore\/sbom-action\/download-syft@v0\n\n      - name: Generate SPDX SBOM\n        run: |\n          syft ${{ steps.digest.outputs.image }} -o spdx-json=sbom.spdx.json\n          echo \"### SBOM Summary\" &gt;&gt; $GITHUB_STEP_SUMMARY\n          echo \"Package count: $(cat sbom.spdx.json | jq '.packages | length')\" &gt;&gt; $GITHUB_STEP_SUMMARY\n\n      - name: Install Grype\n        uses: anchore\/scan-action\/download-grype@v4\n\n      - name: Scan SBOM for vulnerabilities\n        run: |\n          grype sbom:.\/sbom.spdx.json -o json &gt; vulnerabilities.json\n          grype sbom:.\/sbom.spdx.json -o table &gt;&gt; $GITHUB_STEP_SUMMARY\n\n          # Fail if critical vulnerabilities are found\n          CRITICAL_COUNT=$(cat vulnerabilities.json | jq '[.matches[] | select(.vulnerability.severity==\"Critical\")] | length')\n          echo \"Critical vulnerabilities: $CRITICAL_COUNT\"\n          if [ \"$CRITICAL_COUNT\" -gt 0 ]; then\n            echo \"::error::Found $CRITICAL_COUNT critical vulnerabilities. Failing pipeline.\"\n            exit 1\n          fi\n\n      - name: Install Cosign\n        uses: sigstore\/cosign-installer@v3\n\n      - name: Attest SBOM\n        run: |\n          cosign attest --predicate sbom.spdx.json \\\n            --type spdxjson \\\n            --yes \\\n            ${{ steps.digest.outputs.image }}\n\n      - name: Verify attestation\n        run: |\n          cosign verify-attestation \\\n            --type spdxjson \\\n            --certificate-identity-regexp=\"https:\/\/github.com\/${{ github.repository }}\/\" \\\n            --certificate-oidc-issuer=https:\/\/token.actions.githubusercontent.com \\\n            ${{ steps.digest.outputs.image }}\n\n      - name: Upload SBOM as artifact\n        uses: actions\/upload-artifact@v4\n        with:\n          name: sbom-spdx\n          path: sbom.spdx.json\n          retention-days: 90\n\n      - name: Upload vulnerability report\n        uses: actions\/upload-artifact@v4\n        if: always()\n        with:\n          name: vulnerability-report\n          path: vulnerabilities.json\n          retention-days: 90\n<\/code><\/pre>\n<p>\u064a\u0633\u062a\u062e\u062f\u0645 \u0633\u064a\u0631 \u0627\u0644\u0639\u0645\u0644 \u0647\u0630\u0627 <strong>\u0627\u0644\u062a\u0648\u0642\u064a\u0639 \u0628\u062f\u0648\u0646 \u0645\u0641\u0627\u062a\u064a\u062d<\/strong> \u0639\u0628\u0631 \u0647\u0648\u064a\u0629 OIDC \u0627\u0644\u062e\u0627\u0635\u0629 \u0628\u0640 GitHub Actions. \u0644\u0627 \u064a\u062a\u0645 \u062a\u062e\u0632\u064a\u0646 \u0645\u0641\u0627\u062a\u064a\u062d \u062e\u0627\u0635\u0629 \u0641\u064a \u0627\u0644\u0623\u0633\u0631\u0627\u0631 \u2014 \u064a\u062d\u0635\u0644 Cosign \u0639\u0644\u0649 \u0634\u0647\u0627\u062f\u0629 \u0642\u0635\u064a\u0631\u0629 \u0627\u0644\u0639\u0645\u0631 \u0645\u0646 Fulcio CA \u0627\u0644\u062a\u0627\u0628\u0639\u0629 \u0644\u0640 Sigstore\u060c \u0648\u064a\u062a\u0645 \u062a\u0633\u062c\u064a\u0644 \u062d\u062f\u062b \u0627\u0644\u062a\u0648\u0642\u064a\u0639 \u0641\u064a \u0633\u062c\u0644 \u0627\u0644\u0634\u0641\u0627\u0641\u064a\u0629 Rekor.<\/p>\n<p>\u064a\u0641\u0634\u0644 \u062e\u0637 \u0627\u0644\u0623\u0646\u0627\u0628\u064a\u0628 <strong>\u0625\u0630\u0627 \u062a\u0645 \u0627\u0643\u062a\u0634\u0627\u0641 \u0623\u064a \u062b\u063a\u0631\u0627\u062a \u062d\u0631\u062c\u0629<\/strong>. \u0642\u0645 \u0628\u062a\u0639\u062f\u064a\u0644 \u0627\u0644\u062d\u062f \u0639\u0646 \u0637\u0631\u064a\u0642 \u062a\u063a\u064a\u064a\u0631 \u0645\u0631\u0634\u062d \u0627\u0644\u062e\u0637\u0648\u0631\u0629 \u0641\u064a \u062e\u0637\u0648\u0629 \u0641\u062d\u0635 Grype.<\/p>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 5: \u0628\u0646\u0627\u0621 \u062e\u0637 \u0627\u0644\u0623\u0646\u0627\u0628\u064a\u0628 \u0641\u064a GitLab CI<\/h2>\n<p>\u062e\u0637 \u0627\u0644\u0623\u0646\u0627\u0628\u064a\u0628 \u0627\u0644\u0645\u0643\u0627\u0641\u0626 \u0641\u064a GitLab CI \u064a\u0633\u062a\u062e\u062f\u0645 \u0646\u0641\u0633 \u0627\u0644\u0623\u062f\u0648\u0627\u062a \u0644\u0643\u0646\u0647 \u064a\u062a\u0643\u064a\u0641 \u0645\u0639 \u0646\u0645\u0648\u0630\u062c GitLab \u0627\u0644\u0642\u0627\u0626\u0645 \u0639\u0644\u0649 \u0627\u0644\u0645\u0631\u0627\u062d\u0644 \u0648\u0633\u062c\u0644 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a \u0627\u0644\u0645\u062f\u0645\u062c \u0641\u064a\u0647.<\/p>\n<p>\u0623\u0646\u0634\u0626 <code>.gitlab-ci.yml<\/code>:<\/p>\n<pre><code class=\"language-yaml\">stages:\n  - build\n  - sbom\n  - scan\n  - attest\n\nvariables:\n  IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA\n  IMAGE_DIGEST: \"\"\n\nbuild:\n  stage: build\n  image: docker:24\n  services:\n    - docker:24-dind\n  variables:\n    DOCKER_TLS_CERTDIR: \"\/certs\"\n  script:\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n    - docker build -t $IMAGE .\n    - docker push $IMAGE\n    - |\n      DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' $IMAGE)\n      echo \"IMAGE_DIGEST=$DIGEST\" &gt;&gt; build.env\n  artifacts:\n    reports:\n      dotenv: build.env\n\ngenerate-sbom:\n  stage: sbom\n  image: alpine:3.19\n  needs: [build]\n  before_script:\n    - apk add --no-cache curl jq\n    - curl -sSfL https:\/\/raw.githubusercontent.com\/anchore\/syft\/main\/install.sh | sh -s -- -b \/usr\/local\/bin\n  script:\n    - syft $IMAGE_DIGEST -o spdx-json=sbom.spdx.json\n    - echo \"Package count:\" $(cat sbom.spdx.json | jq '.packages | length')\n  artifacts:\n    paths:\n      - sbom.spdx.json\n    expire_in: 90 days\n\nscan-vulnerabilities:\n  stage: scan\n  image: alpine:3.19\n  needs: [generate-sbom]\n  before_script:\n    - apk add --no-cache curl jq\n    - curl -sSfL https:\/\/raw.githubusercontent.com\/anchore\/grype\/main\/install.sh | sh -s -- -b \/usr\/local\/bin\n  script:\n    - grype sbom:.\/sbom.spdx.json -o json &gt; vulnerabilities.json\n    - grype sbom:.\/sbom.spdx.json -o table\n    - |\n      CRITICAL_COUNT=$(cat vulnerabilities.json | jq '[.matches[] | select(.vulnerability.severity==\"Critical\")] | length')\n      echo \"Critical vulnerabilities found: $CRITICAL_COUNT\"\n      if [ \"$CRITICAL_COUNT\" -gt 0 ]; then\n        echo \"ERROR: Critical vulnerabilities detected. Failing pipeline.\"\n        exit 1\n      fi\n  artifacts:\n    paths:\n      - vulnerabilities.json\n    expire_in: 90 days\n    when: always\n\nattest-sbom:\n  stage: attest\n  image: alpine:3.19\n  needs: [build, generate-sbom, scan-vulnerabilities]\n  id_tokens:\n    SIGSTORE_ID_TOKEN:\n      aud: sigstore\n  before_script:\n    - apk add --no-cache curl\n    - curl -sSfL https:\/\/github.com\/sigstore\/cosign\/releases\/latest\/download\/cosign-linux-amd64 -o \/usr\/local\/bin\/cosign\n    - chmod +x \/usr\/local\/bin\/cosign\n  script:\n    - cosign attest --predicate sbom.spdx.json\n        --type spdxjson\n        --yes\n        $IMAGE_DIGEST\n    - cosign verify-attestation\n        --type spdxjson\n        --certificate-identity-regexp=\"https:\/\/gitlab.com\/$CI_PROJECT_PATH\/\/\"\n        --certificate-oidc-issuer=https:\/\/gitlab.com\n        $IMAGE_DIGEST\n<\/code><\/pre>\n<p>\u0627\u0644\u0641\u0631\u0648\u0642 \u0627\u0644\u0631\u0626\u064a\u0633\u064a\u0629 \u0639\u0646 \u0625\u0635\u062f\u0627\u0631 GitHub Actions:<\/p>\n<ul>\n<li>\u064a\u0633\u062a\u062e\u062f\u0645 GitLab <strong>\u0627\u0644\u0645\u0631\u0627\u062d\u0644<\/strong> \u0628\u062f\u0644\u0627\u064b \u0645\u0646 \u0648\u0638\u064a\u0641\u0629 \u0648\u0627\u062d\u062f\u0629 \u0628\u062e\u0637\u0648\u0627\u062a<\/li>\n<li>\u064a\u062a\u0645 \u062a\u0645\u0631\u064a\u0631 \u0645\u0644\u062e\u0635 \u0627\u0644\u0635\u0648\u0631\u0629 \u0628\u064a\u0646 \u0627\u0644\u0645\u0631\u0627\u062d\u0644 \u0639\u0628\u0631 \u0623\u062f\u0648\u0627\u062a <code>dotenv<\/code><\/li>\n<li>\u064a\u062a\u0645 \u0643\u0634\u0641 \u0631\u0645\u0632 OIDC \u0627\u0644\u062e\u0627\u0635 \u0628\u0640 GitLab \u0639\u0628\u0631 <code>id_tokens<\/code> \u0648\u0645\u062a\u063a\u064a\u0631 <code>SIGSTORE_ID_TOKEN<\/code><\/li>\n<li>\u0645\u064f\u0635\u062f\u0631 OIDC \u0644\u0644\u062a\u062d\u0642\u0642 \u0647\u0648 <code>https:\/\/gitlab.com<\/code><\/li>\n<\/ul>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 6: \u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 SBOM \u0639\u0646\u062f \u0627\u0644\u0646\u0634\u0631<\/h2>\n<p>\u062a\u0648\u0644\u064a\u062f SBOMs \u0648\u062a\u0635\u062f\u064a\u0642\u0647\u0627 \u0647\u0648 \u0646\u0635\u0641 \u0627\u0644\u0642\u0635\u0629 \u0641\u0642\u0637. \u0627\u0644\u0641\u0627\u0626\u062f\u0629 \u0627\u0644\u0623\u0645\u0646\u064a\u0629 \u0627\u0644\u062d\u0642\u064a\u0642\u064a\u0629 \u062a\u0623\u062a\u064a \u0645\u0646 <strong>\u0641\u0631\u0636 \u0627\u0644\u062a\u062d\u0642\u0642 \u0641\u064a \u0648\u0642\u062a \u0627\u0644\u0646\u0634\u0631<\/strong> \u2014 \u0631\u0641\u0636 \u0623\u064a \u0635\u0648\u0631\u0629 \u062a\u0641\u062a\u0642\u0631 \u0625\u0644\u0649 \u062a\u0635\u062f\u064a\u0642 SBOM \u0635\u0627\u0644\u062d.<\/p>\n<h3>\u0627\u0644\u062e\u064a\u0627\u0631 \u0623: \u0627\u0644\u062a\u062d\u0642\u0642 \u0641\u064a \u0633\u0643\u0631\u064a\u0628\u062a \u0627\u0644\u0646\u0634\u0631<\/h3>\n<pre><code class=\"language-bash\">#!\/bin\/bash\n# deploy.sh \u2014 \u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u062a\u0635\u062f\u064a\u0642 SBOM \u0642\u0628\u0644 \u0627\u0644\u0646\u0634\u0631\nset -euo pipefail\n\nIMAGE=\"$1\"\n\necho \"Verifying SBOM attestation for: $IMAGE\"\n\ncosign verify-attestation \\\n  --type spdxjson \\\n  --certificate-identity-regexp=\"https:\/\/github.com\/YOUR_ORG\/YOUR_REPO\/\" \\\n  --certificate-oidc-issuer=https:\/\/token.actions.githubusercontent.com \\\n  \"$IMAGE\" &gt; \/dev\/null 2&gt;&amp;1\n\nif [ $? -eq 0 ]; then\n  echo \"SBOM attestation verified successfully.\"\n  kubectl set image deployment\/myapp myapp=\"$IMAGE\"\nelse\n  echo \"ERROR: SBOM attestation verification failed. Deployment blocked.\"\n  exit 1\nfi\n<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u064a\u0627\u0631 \u0628: \u0627\u0644\u0641\u0631\u0636 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 Kyverno \u0641\u064a Kubernetes<\/h3>\n<p>Kyverno \u0647\u0648 \u0645\u062d\u0631\u0643 \u0633\u064a\u0627\u0633\u0627\u062a \u0623\u0635\u0644\u064a \u0644\u0640 Kubernetes \u064a\u0645\u0643\u0646\u0647 \u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u062a\u0648\u0642\u064a\u0639\u0627\u062a \u0627\u0644\u0635\u0648\u0631 \u0648\u0627\u0644\u062a\u0635\u062f\u064a\u0642\u0627\u062a \u0641\u064a \u0648\u0642\u062a \u0627\u0644\u0642\u0628\u0648\u0644. \u062a\u0642\u0648\u0645 \u0627\u0644\u0633\u064a\u0627\u0633\u0629 \u0627\u0644\u062a\u0627\u0644\u064a\u0629 <strong>\u0628\u0631\u0641\u0636 \u0623\u064a pod<\/strong> \u0644\u0627 \u062a\u062d\u062a\u0648\u064a \u0635\u0648\u0631\u062a\u0647 \u0639\u0644\u0649 \u062a\u0635\u062f\u064a\u0642 SBOM \u0635\u0627\u0644\u062d.<\/p>\n<pre><code class=\"language-yaml\">apiVersion: kyverno.io\/v1\nkind: ClusterPolicy\nmetadata:\n  name: require-sbom-attestation\nspec:\n  validationFailureAction: Enforce\n  webhookTimeoutSeconds: 30\n  rules:\n    - name: check-sbom-attestation\n      match:\n        any:\n          - resources:\n              kinds:\n                - Pod\n      verifyImages:\n        - imageReferences:\n            - \"ghcr.io\/YOUR_ORG\/*\"\n          attestations:\n            - type: spdxjson\n              attestors:\n                - entries:\n                    - keyless:\n                        subject: \"https:\/\/github.com\/YOUR_ORG\/YOUR_REPO\/.github\/workflows\/sbom-pipeline.yml@refs\/heads\/main\"\n                        issuer: \"https:\/\/token.actions.githubusercontent.com\"\n                        rekor:\n                          url: https:\/\/rekor.sigstore.dev\n              conditions:\n                - all:\n                    - key: \"{{ len(spdxVersion) }}\"\n                      operator: GreaterThan\n                      value: \"0\"\n<\/code><\/pre>\n<p>\u062a\u0637\u0628\u064a\u0642 \u0627\u0644\u0633\u064a\u0627\u0633\u0629:<\/p>\n<pre><code class=\"language-bash\">kubectl apply -f require-sbom-attestation.yaml\n<\/code><\/pre>\n<h3>\u0627\u062e\u062a\u0628\u0627\u0631 \u0627\u0644\u0642\u0628\u0648\u0644: \u0635\u0648\u0631\u0629 \u0645\u0639 \u062a\u0635\u062f\u064a\u0642<\/h3>\n<pre><code class=\"language-bash\"># \u064a\u062c\u0628 \u0623\u0646 \u064a\u062a\u0645 \u0642\u0628\u0648\u0644 \u0647\u0630\u0627\nkubectl run test-admitted \\\n  --image=ghcr.io\/YOUR_ORG\/sbom-lab-app@sha256:abc123... \\\n  --restart=Never\n\n# \u0627\u0644\u0645\u062e\u0631\u062c \u0627\u0644\u0645\u062a\u0648\u0642\u0639:\n# pod\/test-admitted created\n<\/code><\/pre>\n<h3>\u0627\u062e\u062a\u0628\u0627\u0631 \u0627\u0644\u0642\u0628\u0648\u0644: \u0635\u0648\u0631\u0629 \u0628\u062f\u0648\u0646 \u062a\u0635\u062f\u064a\u0642<\/h3>\n<pre><code class=\"language-bash\"># \u064a\u062c\u0628 \u0623\u0646 \u064a\u062a\u0645 \u0631\u0641\u0636 \u0647\u0630\u0627\nkubectl run test-rejected \\\n  --image=ghcr.io\/YOUR_ORG\/sbom-lab-app:unattested \\\n  --restart=Never\n\n# \u0627\u0644\u0645\u062e\u0631\u062c \u0627\u0644\u0645\u062a\u0648\u0642\u0639:\n# Error from server: admission webhook \"mutate.kyverno.svc-fail\" denied the request:\n# resource Pod\/default\/test-rejected was blocked due to the following policies:\n# require-sbom-attestation:\n#   check-sbom-attestation: 'image verification failed for ghcr.io\/YOUR_ORG\/sbom-lab-app:unattested:\n#     attestation spdxjson not found'\n<\/code><\/pre>\n<p>\u0647\u0630\u0647 \u0647\u064a \u062d\u0644\u0642\u0629 \u0627\u0644\u0641\u0631\u0636 \u0627\u0644\u062a\u064a \u062a\u062c\u0639\u0644 SBOMs \u0630\u0627\u062a \u0645\u0639\u0646\u0649 \u062a\u0634\u063a\u064a\u0644\u064a \u2014 \u0628\u062f\u0648\u0646 \u0627\u0644\u062a\u062d\u0642\u0642 \u0639\u0646\u062f \u0627\u0644\u0646\u0634\u0631\u060c \u064a\u0628\u0642\u0649 \u062a\u0648\u0644\u064a\u062f SBOM \u0645\u062c\u0631\u062f \u062a\u0648\u062b\u064a\u0642 \u0641\u0642\u0637.<\/p>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 7: \u0645\u0642\u0627\u0631\u0646\u0629 SBOM \u0628\u064a\u0646 \u0627\u0644\u0625\u0635\u062f\u0627\u0631\u0627\u062a<\/h2>\n<p>\u0639\u0646\u062f\u0645\u0627 \u062a\u0635\u062f\u0631 \u0625\u0635\u062f\u0627\u0631\u064b\u0627 \u062c\u062f\u064a\u062f\u064b\u0627\u060c \u062a\u062d\u062a\u0627\u062c \u0625\u0644\u0649 \u0641\u0647\u0645 \u0645\u0627 \u062a\u063a\u064a\u0631 \u0641\u064a \u0634\u062c\u0631\u0629 \u0627\u0644\u062a\u0628\u0639\u064a\u0627\u062a \u0627\u0644\u062e\u0627\u0635\u0629 \u0628\u0643. \u0645\u0642\u0627\u0631\u0646\u0629 SBOMs \u0628\u064a\u0646 \u0627\u0644\u0625\u0635\u062f\u0627\u0631\u0627\u062a \u062a\u0643\u0634\u0641 \u0639\u0646 \u0627\u0644\u062d\u0632\u0645 \u0627\u0644\u0645\u0636\u0627\u0641\u0629 \u0648\u0627\u0644\u0645\u062d\u0630\u0648\u0641\u0629 \u0648\u0627\u0644\u0645\u062d\u062f\u062b\u0629 \u2014 \u0648\u0647\u0648 \u0623\u0645\u0631 \u0628\u0627\u0644\u063a \u0627\u0644\u0623\u0647\u0645\u064a\u0629 \u0644\u062a\u0642\u064a\u064a\u0645 \u0627\u0644\u0645\u062e\u0627\u0637\u0631 \u0627\u0644\u062c\u062f\u064a\u062f\u0629.<\/p>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 1: \u062a\u0648\u0644\u064a\u062f SBOMs \u0644\u0625\u0635\u062f\u0627\u0631\u064a\u0646<\/h3>\n<pre><code class=\"language-bash\"># \u062a\u0648\u0644\u064a\u062f SBOM \u0644\u0644\u0625\u0635\u062f\u0627\u0631 v1.0.0\nsyft ghcr.io\/YOUR_GITHUB_USERNAME\/sbom-lab-app:v1.0.0 -o spdx-json=sbom-v1.spdx.json\n\n# \u062a\u0648\u0644\u064a\u062f SBOM \u0644\u0644\u0625\u0635\u062f\u0627\u0631 v1.1.0 (\u0628\u0639\u062f \u062a\u062d\u062f\u064a\u062b \u0627\u0644\u062a\u0628\u0639\u064a\u0627\u062a)\nsyft ghcr.io\/YOUR_GITHUB_USERNAME\/sbom-lab-app:v1.1.0 -o spdx-json=sbom-v2.spdx.json\n<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 2: \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u0642\u0648\u0627\u0626\u0645 \u0627\u0644\u062d\u0632\u0645<\/h3>\n<pre><code class=\"language-bash\"># \u0627\u0633\u062a\u062e\u0631\u0627\u062c \u0642\u0648\u0627\u0626\u0645 \u0627\u0644\u062d\u0632\u0645 \u0627\u0644\u0645\u0631\u062a\u0628\u0629\ncat sbom-v1.spdx.json | jq -r '.packages[] | \"\\(.name)@\\(.versionInfo)\"' | sort &gt; packages-v1.txt\ncat sbom-v2.spdx.json | jq -r '.packages[] | \"\\(.name)@\\(.versionInfo)\"' | sort &gt; packages-v2.txt\n<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 3: \u0645\u0642\u0627\u0631\u0646\u0629 \u0642\u0648\u0627\u0626\u0645 \u0627\u0644\u062d\u0632\u0645<\/h3>\n<pre><code class=\"language-bash\">diff --unified packages-v1.txt packages-v2.txt\n<\/code><\/pre>\n<p>\u0646\u0645\u0648\u0630\u062c \u0627\u0644\u0645\u062e\u0631\u062c\u0627\u062a:<\/p>\n<pre><code class=\"language-diff\">--- packages-v1.txt\n+++ packages-v2.txt\n@@ -12,7 +12,8 @@\n  express@4.18.2\n  lodash@4.17.21\n- axios@1.6.0\n+ axios@1.7.2\n+ helmet@7.1.0\n  mime-types@2.1.35\n<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 4: \u062a\u062d\u062f\u064a\u062f \u0627\u0644\u062b\u063a\u0631\u0627\u062a \u0627\u0644\u0645\u0643\u062a\u0634\u0641\u0629 \u062d\u062f\u064a\u062b\u064b\u0627<\/h3>\n<pre><code class=\"language-bash\"># \u0641\u062d\u0635 \u0627\u0644\u062d\u0632\u0645 \u0627\u0644\u062c\u062f\u064a\u062f\u0629\/\u0627\u0644\u0645\u062a\u063a\u064a\u0631\u0629 \u0641\u0642\u0637\ngrype sbom:.\/sbom-v2.spdx.json -o json &gt; vulns-v2.json\ngrype sbom:.\/sbom-v1.spdx.json -o json &gt; vulns-v1.json\n\n# \u0645\u0642\u0627\u0631\u0646\u0629 \u0623\u0639\u062f\u0627\u062f \u0627\u0644\u062b\u063a\u0631\u0627\u062a\necho \"v1.0.0 vulnerabilities: $(cat vulns-v1.json | jq '.matches | length')\"\necho \"v1.1.0 vulnerabilities: $(cat vulns-v2.json | jq '.matches | length')\"\n\n# \u0627\u0644\u0639\u062b\u0648\u0631 \u0639\u0644\u0649 \u0627\u0644\u062b\u063a\u0631\u0627\u062a \u0627\u0644\u062c\u062f\u064a\u062f\u0629 \u0641\u064a v1.1.0\ncomm -13 \\\n  &lt;(cat vulns-v1.json | jq -r '.matches[].vulnerability.id' | sort -u) \\\n  &lt;(cat vulns-v2.json | jq -r '.matches[].vulnerability.id' | sort -u)\n<\/code><\/pre>\n<p>\u064a\u0645\u0643\u0646 \u0623\u062a\u0645\u062a\u0629 \u0639\u0645\u0644\u064a\u0629 \u0627\u0644\u0645\u0642\u0627\u0631\u0646\u0629 \u0647\u0630\u0647 \u0641\u064a CI \u0644\u0644\u062a\u0639\u0644\u064a\u0642 \u0639\u0644\u0649 \u0637\u0644\u0628\u0627\u062a \u0627\u0644\u0633\u062d\u0628 \u0628\u062a\u063a\u064a\u064a\u0631\u0627\u062a \u0627\u0644\u062a\u0628\u0639\u064a\u0627\u062a\u060c \u0645\u0645\u0627 \u064a\u0645\u0646\u062d \u0627\u0644\u0645\u0631\u0627\u062c\u0639\u064a\u0646 \u0631\u0624\u064a\u0629 \u0644\u062a\u0623\u062b\u064a\u0631 \u0633\u0644\u0633\u0644\u0629 \u0627\u0644\u062a\u0648\u0631\u064a\u062f \u0642\u0628\u0644 \u0627\u0644\u062f\u0645\u062c.<\/p>\n<h2>\u0627\u0644\u062a\u0646\u0638\u064a\u0641<\/h2>\n<p>\u0627\u062d\u0630\u0641 \u0627\u0644\u0645\u0648\u0627\u0631\u062f \u0627\u0644\u062a\u064a \u062a\u0645 \u0625\u0646\u0634\u0627\u0624\u0647\u0627 \u0623\u062b\u0646\u0627\u0621 \u0647\u0630\u0627 \u0627\u0644\u0645\u062e\u062a\u0628\u0631:<\/p>\n<pre><code class=\"language-bash\"># \u062d\u0630\u0641 \u0627\u0644\u0645\u0644\u0641\u0627\u062a \u0627\u0644\u0645\u062d\u0644\u064a\u0629\nrm -f sbom.spdx.json sbom.cyclonedx.json vulnerabilities.json\nrm -f sbom-v1.spdx.json sbom-v2.spdx.json packages-v1.txt packages-v2.txt\nrm -f vulns-v1.json vulns-v2.json\n\n# \u062d\u0630\u0641 \u0635\u0648\u0631\u0629 \u0627\u0644\u0627\u062e\u062a\u0628\u0627\u0631 \u0645\u0646 GHCR (\u064a\u062a\u0637\u0644\u0628 gh CLI)\ngh api -X DELETE \/user\/packages\/container\/sbom-lab-app\/versions\/PACKAGE_VERSION_ID\n\n# \u062d\u0630\u0641 \u0633\u064a\u0627\u0633\u0629 Kyverno\nkubectl delete clusterpolicy require-sbom-attestation\n\n# \u062d\u0630\u0641 pods \u0627\u0644\u0627\u062e\u062a\u0628\u0627\u0631\nkubectl delete pod test-admitted test-rejected --ignore-not-found\n\n# \u062d\u0630\u0641 \u0627\u0644\u0645\u0633\u062a\u0648\u062f\u0639 \u0627\u0644\u0645\u062d\u0644\u064a\ncd .. &amp;&amp; rm -rf sbom-pipeline-lab\n<\/code><\/pre>\n<h2>\u0627\u0644\u0646\u0642\u0627\u0637 \u0627\u0644\u0631\u0626\u064a\u0633\u064a\u0629<\/h2>\n<ul>\n<li><strong>SBOMs \u0647\u064a \u0623\u0633\u0627\u0633 \u0623\u0645\u0627\u0646 \u0633\u0644\u0633\u0644\u0629 \u0627\u0644\u062a\u0648\u0631\u064a\u062f<\/strong> \u2014 \u0641\u0647\u064a \u062a\u0648\u0641\u0631 \u0627\u0644\u062c\u0631\u062f \u0627\u0644\u0630\u064a \u064a\u0645\u0643\u0651\u0646 \u0645\u0646 \u0641\u062d\u0635 \u0627\u0644\u062b\u063a\u0631\u0627\u062a \u0648\u0627\u0644\u0627\u0645\u062a\u062b\u0627\u0644 \u0644\u0644\u062a\u0631\u0627\u062e\u064a\u0635 \u0648\u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0627\u0644\u0645\u0635\u062f\u0631.<\/li>\n<li><strong>\u064a\u0648\u0644\u062f Syft SBOMs \u0628\u062c\u0645\u064a\u0639 \u0627\u0644\u062a\u0646\u0633\u064a\u0642\u0627\u062a \u0627\u0644\u0631\u0626\u064a\u0633\u064a\u0629<\/strong> \u2014 SPDX \u0644\u0644\u0627\u0645\u062a\u062b\u0627\u0644 \u0627\u0644\u062a\u0646\u0638\u064a\u0645\u064a\u060c CycloneDX \u0644\u0633\u064a\u0631 \u0639\u0645\u0644 \u0627\u0644\u0623\u0645\u0627\u0646\u060c \u0648\u0643\u0644\u0627\u0647\u0645\u0627 \u0645\u062f\u0639\u0648\u0645 \u0639\u0628\u0631 \u0627\u0644\u0646\u0638\u0627\u0645 \u0627\u0644\u0628\u064a\u0626\u064a.<\/li>\n<li><strong>\u0641\u062d\u0635 SBOM \u0623\u0633\u0631\u0639 \u0645\u0646 \u0641\u062d\u0635 \u0627\u0644\u0635\u0648\u0631\u0629<\/strong> \u2014 \u0627\u0633\u062a\u062e\u062f\u0645 Grype \u0645\u0639 \u0628\u0627\u062f\u0626\u0629 <code>sbom:<\/code> \u0641\u064a \u062e\u0637\u0648\u0637 \u0623\u0646\u0627\u0628\u064a\u0628 CI \u0644\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u062d\u0644\u0642\u0627\u062a \u062a\u063a\u0630\u064a\u0629 \u0631\u0627\u062c\u0639\u0629 \u0633\u0631\u064a\u0639\u0629 \u062f\u0648\u0646 \u0633\u062d\u0628 \u0637\u0628\u0642\u0627\u062a \u0627\u0644\u0635\u0648\u0631\u0629.<\/li>\n<li><strong>\u062a\u0635\u062f\u064a\u0642\u0627\u062a Cosign \u062a\u0631\u0628\u0637 SBOMs \u0628\u0627\u0644\u0635\u0648\u0631 \u062a\u0634\u0641\u064a\u0631\u064a\u064b\u0627<\/strong> \u2014 \u062a\u062b\u0628\u062a \u0627\u0644\u062a\u0635\u062f\u064a\u0642\u0627\u062a \u0627\u0644\u0645\u0648\u0642\u0639\u0629 \u0623\u0646 SBOM \u0645\u0639\u064a\u0646\u0629 \u062a\u0645 \u0625\u0646\u062a\u0627\u062c\u0647\u0627 \u0644\u0645\u0644\u062e\u0635 \u0635\u0648\u0631\u0629 \u0645\u062d\u062f\u062f\u060c \u0648\u0645\u062e\u0632\u0646\u0629 \u0641\u064a \u0627\u0644\u0633\u062c\u0644 \u0628\u062c\u0627\u0646\u0628 \u0627\u0644\u0635\u0648\u0631\u0629.<\/li>\n<li><strong>\u0627\u0644\u062a\u062d\u0642\u0642 \u0639\u0646\u062f \u0627\u0644\u0646\u0634\u0631 \u0647\u0648 \u0645\u0627 \u064a\u062c\u0639\u0644 SBOMs \u0642\u0627\u0628\u0644\u0629 \u0644\u0644\u0641\u0631\u0636<\/strong> \u2014 \u0628\u062f\u0648\u0646 \u0627\u0644\u062a\u062d\u0643\u0645 \u0641\u064a \u0627\u0644\u0642\u0628\u0648\u0644 (Kyverno \u0623\u0648 OPA Gatekeeper \u0623\u0648 \u0633\u0643\u0631\u064a\u0628\u062a\u0627\u062a \u0627\u0644\u0646\u0634\u0631)\u060c \u062a\u0628\u0642\u0649 SBOMs \u062a\u0648\u062b\u064a\u0642\u064b\u0627 \u0628\u0644\u0627 \u0642\u0648\u0629.<\/li>\n<li><strong>\u0645\u0642\u0627\u0631\u0646\u0629 SBOMs \u062a\u0643\u0634\u0641 \u062a\u063a\u064a\u064a\u0631\u0627\u062a \u0633\u0644\u0633\u0644\u0629 \u0627\u0644\u062a\u0648\u0631\u064a\u062f \u0628\u064a\u0646 \u0627\u0644\u0625\u0635\u062f\u0627\u0631\u0627\u062a<\/strong> \u2014 \u0623\u062a\u0645\u062a\u0629 \u0645\u0642\u0627\u0631\u0646\u0629 \u0627\u0644\u062a\u0628\u0639\u064a\u0627\u062a \u0641\u064a CI \u062a\u0645\u0646\u062d \u0627\u0644\u0641\u0631\u0642 \u0631\u0624\u064a\u0629 \u0644\u0644\u0645\u062e\u0627\u0637\u0631 \u0627\u0644\u062c\u062f\u064a\u062f\u0629 \u0642\u0628\u0644 \u0648\u0635\u0648\u0644 \u0627\u0644\u0643\u0648\u062f \u0625\u0644\u0649 \u0627\u0644\u0625\u0646\u062a\u0627\u062c.<\/li>\n<\/ul>\n<h2>\u0627\u0644\u062e\u0637\u0648\u0627\u062a \u0627\u0644\u062a\u0627\u0644\u064a\u0629<\/h2>\n<p>\u062a\u0627\u0628\u0639 \u0628\u0646\u0627\u0621 \u0645\u0645\u0627\u0631\u0633\u0629 \u0623\u0645\u0627\u0646 \u0633\u0644\u0633\u0644\u0629 \u0627\u0644\u062a\u0648\u0631\u064a\u062f \u0627\u0644\u062e\u0627\u0635\u0629 \u0628\u0643 \u0645\u0639 \u0647\u0630\u0647 \u0627\u0644\u0623\u062f\u0644\u0629 \u0630\u0627\u062a \u0627\u0644\u0635\u0644\u0629:<\/p>\n<ul>\n<li><a href=\"https:\/\/secure-pipelines.com\/ar\/ci-cd-security\/artifact-provenance-attestations-slsa-in-toto\/\">\u0645\u0635\u062f\u0631 \u0627\u0644\u0623\u062f\u0627\u0629 \u0648\u0627\u0644\u062a\u0635\u062f\u064a\u0642\u0627\u062a<\/a> \u2014 \u062a\u0639\u0644\u0645 \u0643\u064a\u0641 \u062a\u0645\u062a\u062f \u0623\u0637\u0631 SLSA \u0648in-toto \u0627\u0644\u062a\u0635\u062f\u064a\u0642 \u0625\u0644\u0649 \u0645\u0627 \u0628\u0639\u062f SBOMs \u0644\u062a\u0634\u0645\u0644 \u0645\u0635\u062f\u0631 \u0627\u0644\u0628\u0646\u0627\u0621 \u0648\u0633\u0644\u0627\u0645\u0629 \u0627\u0644\u0645\u0635\u062f\u0631 \u0648\u0633\u064a\u0627\u0633\u0627\u062a \u0627\u0644\u0646\u0634\u0631.<\/li>\n<li><a href=\"https:\/\/secure-pipelines.com\/ar\/ci-cd-security\/signing-verifying-container-images-sigstore-cosign\/\">\u062a\u0648\u0642\u064a\u0639 \u0648\u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 Sigstore \u0648Cosign<\/a> \u2014 \u062a\u0639\u0645\u0642 \u0641\u064a \u0627\u0644\u062a\u0648\u0642\u064a\u0639 \u0628\u062f\u0648\u0646 \u0645\u0641\u0627\u062a\u064a\u062d \u0648\u0634\u0647\u0627\u062f\u0627\u062a Fulcio \u0648\u0633\u062c\u0644\u0627\u062a \u0627\u0644\u0634\u0641\u0627\u0641\u064a\u0629 Rekor \u0648\u0633\u064a\u0627\u0633\u0627\u062a \u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u062a\u0648\u0642\u064a\u0639 \u0627\u0644\u0635\u0648\u0631.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>\u0646\u0638\u0631\u0629 \u0639\u0627\u0645\u0629 \u0623\u0635\u0628\u062d\u062a \u0642\u0648\u0627\u0626\u0645 \u0645\u0643\u0648\u0646\u0627\u062a \u0627\u0644\u0628\u0631\u0645\u062c\u064a\u0627\u062a (SBOMs) \u0628\u0633\u0631\u0639\u0629 \u0639\u0646\u0635\u0631\u064b\u0627 \u0625\u0644\u0632\u0627\u0645\u064a\u064b\u0627 \u0644\u0634\u0641\u0627\u0641\u064a\u0629 \u0633\u0644\u0633\u0644\u0629 \u062a\u0648\u0631\u064a\u062f \u0627\u0644\u0628\u0631\u0645\u062c\u064a\u0627\u062a. \u062a\u062a\u0637\u0644\u0628 \u0627\u0644\u0623\u0648\u0627\u0645\u0631 \u0627\u0644\u062a\u0646\u0641\u064a\u0630\u064a\u0629 \u0648\u0627\u0644\u0623\u0637\u0631 \u0627\u0644\u062a\u0646\u0638\u064a\u0645\u064a\u0629 \u0645\u062b\u0644 NIST SSDF \u0648\u0627\u0644\u0645\u0639\u0627\u064a\u064a\u0631 \u0627\u0644\u0635\u0646\u0627\u0639\u064a\u0629 \u0627\u0644\u0622\u0646 \u0645\u0646 \u0627\u0644\u0645\u0624\u0633\u0633\u0627\u062a \u0625\u0646\u062a\u0627\u062c \u0648\u062a\u0648\u0632\u064a\u0639 \u0648\u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 SBOMs \u0644\u0643\u0644 \u0625\u0635\u062f\u0627\u0631 \u0628\u0631\u0645\u062c\u064a. \u062a\u0633\u0631\u062f SBOM \u0643\u0644 \u0645\u0643\u0648\u0646 \u0648\u0645\u0643\u062a\u0628\u0629 \u0648\u062a\u0628\u0639\u064a\u0629 \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u062c\u0643 \u2014 \u0645\u0645\u0627 \u064a\u0645\u0646\u062d \u0627\u0644\u0645\u0633\u062a\u0647\u0644\u0643\u064a\u0646 \u0627\u0644\u0642\u062f\u0631\u0629 \u0639\u0644\u0649 \u062a\u0642\u064a\u064a\u0645 \u0627\u0644\u0645\u062e\u0627\u0637\u0631 \u0648\u062a\u062a\u0628\u0639 \u0627\u0644\u062b\u063a\u0631\u0627\u062a \u0648\u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 &#8230; <a title=\"\u0645\u062e\u062a\u0628\u0631: \u0628\u0646\u0627\u0621 \u062e\u0637 \u0623\u0646\u0627\u0628\u064a\u0628 SBOM \u2014 \u0627\u0644\u062a\u0648\u0644\u064a\u062f \u0648\u0627\u0644\u062a\u0635\u062f\u064a\u0642 \u0648\u0627\u0644\u062a\u062d\u0642\u0642 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 Syft \u0648Cosign\" class=\"read-more\" href=\"https:\/\/secure-pipelines.com\/ar\/ci-cd-security\/lab-sbom-pipeline-generate-attest-verify-syft-cosign\/\" aria-label=\"Read more about \u0645\u062e\u062a\u0628\u0631: \u0628\u0646\u0627\u0621 \u062e\u0637 \u0623\u0646\u0627\u0628\u064a\u0628 SBOM \u2014 \u0627\u0644\u062a\u0648\u0644\u064a\u062f \u0648\u0627\u0644\u062a\u0635\u062f\u064a\u0642 \u0648\u0627\u0644\u062a\u062d\u0642\u0642 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 Syft \u0648Cosign\">\u0627\u0642\u0631\u0623 \u0627\u0644\u0645\u0632\u064a\u062f<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26,27],"tags":[],"post_folder":[],"class_list":["post-816","post","type-post","status-publish","format-standard","hentry","category-ci-cd-security","category-software-supply-chain"],"_links":{"self":[{"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/posts\/816","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/comments?post=816"}],"version-history":[{"count":1,"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/posts\/816\/revisions"}],"predecessor-version":[{"id":821,"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/posts\/816\/revisions\/821"}],"wp:attachment":[{"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/media?parent=816"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/categories?post=816"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/tags?post=816"},{"taxonomy":"post_folder","embeddable":true,"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/post_folder?post=816"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}