PageSourceSearch

https://ratify.dev/assets/js/a0b07333.c5e84245.js

js ratify.dev collected 2026-09-24 19:26:26 UTC 19,873 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkratify=globalThis.webpackChunkratify||[]).push([[106],{20746(e,n,i){i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"quickstarts/ratify-with-aws-signer","title":"Ratify with AWS Signer","description":"This guide will explain how to get started with Ratify on AWS using EKS, ECR, and AWS Signer. This will involve setting up necessary AWS resources, installing necessary components, and configuring them properly. Once everything is set up we will walk through a simple scenario of verifying the signature on a container image at deployment time.","source":"@site/versioned_docs/version-1.0/quickstarts/ratify-with-aws-signer.md","sourceDirName":"quickstarts","slug":"/quickstarts/ratify-with-aws-signer","permalink":"/docs/1.0/quickstarts/ratify-with-aws-signer","draft":false,"unlisted":false,"editUrl":"https://github.com/ratify-project/ratify-web/blob/main/versioned_docs/version-1.0/quickstarts/ratify-with-aws-signer.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"tutorialSidebar","previous":{"title":"Ratify on Azure","permalink":"/docs/1.0/quickstarts/ratify-on-azure"},"next":{"title":"Ratify with Venafi CodeSign Protect","permalink":"/docs/1.0/quickstarts/ratify-with-venafi"}}');var s=i(74848),a=i(28453);const r={},o="Ratify with AWS Signer",l={},c=[{value:"Table of Contents",id:"table-of-contents",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Set Up ECR",id:"set-up-ecr",level:2},{value:"Set up EKS",id:"set-up-eks",level:2},{value:"Prepare Container Image",id:"prepare-container-image",level:2},{value:"Sign Container Image",id:"sign-container-image",level:2},{value:"Deploy Gatekeeper",id:"deploy-gatekeeper",level:2},{value:"Configure IAM Permissions",id:"configure-iam-permissions",level:2},{value:"Deploy Ratify",id:"deploy-ratify",level:2},{value:"Deploy Container Image",id:"deploy-container-image",level:2},{value:"Cleaning Up",id:"cleaning-up",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"ratify-with-aws-signer",children:"Ratify with AWS Signer"})}),"\n",(0,s.jsx)(n.p,{children:"This guide will explain how to get started with Ratify on AWS using EKS, ECR, and AWS Signer. This will involve setting up necessary AWS resources, installing necessary components, and configuring them properly. Once everything is set up we will walk through a simple scenario of verifying the signature on a container image at deployment time."}),"\n",(0,s.jsx)(n.p,{children:"By the end of this guide you will have a public ECR repository, an EKS cluster with Gatekeeper and Ratify installed, and have validated that only images signed by a trusted AWS Signer SigningProfile can be deployed."}),"\n",(0,s.jsx)(n.p,{children:"This guide assumes you are starting from scratch, but portions of the guide can be skipped if you have an existing EKS cluster, ECR repository, or AWS Signer resources."}),"\n",(0,s.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#set-up-ecr",children:"Set up ECR"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#set-up-eks",children:"Set up EKS"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#prepare-container-image",children:"Prepare Container Image"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#sign-container-image",children:"Sign Container Image"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#deploy-gatekeeper",children:"Deploy Gatekeeper"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#configure-iam-permissions",children:"Configure IAM Permissions"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#deploy-ratify",children:"Deploy Ratify"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#deploy-container-image",children:"Deploy Container Image"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cleaning-up",children:"Cleaning Up"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(n.p,{children:"There are a couple tools you will need locally to complete this guide:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://aws.amazon.com/cli/",children:"awscl
1i"}),": This is used to interact with AWS and provision necessary resources"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.aws.amazon.com/eks/latest/userguide/eksctl.html",children:"eksctl"}),": This is used to easily provision EKS clusters"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/tools/",children:"kubectl"}),": This is used to interact with the EKS cluster we will create"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://helm.sh/docs/intro/quickstart/",children:"helm"}),": This is used to install ratify components into the EKS cluster"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://www.docker.com/get-started",children:"docker"}),": This is used to build the container image we will deploy in this guide"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/ratify-project/ratify/releases",children:"ratify"}),": This is used to check images from ECR locally"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://stedolan.github.io/jq/",children:"jq"}),": This is used to capture variables from json returned by commands"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/notaryproject/notation",children:"notation"}),": This is used to sign the container image we will deploy in this guide"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.aws.amazon.com/signer/latest/developerguide/image-signing-prerequisites.html",children:"AWS Signer notation plugin"}),": this is required to use ",(0,s.jsx)(n.code,{children:"notation"})," with AWS Signer resources"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["If you have not done so already, configure awscli to interact with your AWS account by following these ",(0,s.jsx)(n.a,{href:"https://docs.aws.amazon.com/cli/latest/userguide/getting-started-prereqs.html",children:"instructions"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"set-up-ecr",children:"Set Up ECR"}),"\n",(0,s.jsx)(n.p,{children:"We need to provision a public container repository to make our container images and their associated artifacts available to our EKS cluster. We will do this using awscli. For this guide we will be provisioning a public ECR repository to keep things simple."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'export REPO_NAME=ratifydemo\nexport REPO_URI=$(aws ecr-public create-repository --repository-name $REPO_NAME --region us-east-1 | jq -r ."repository"."repositoryUri" )\n'})}),"\n",(0,s.jsx)(n.p,{children:"We will use the repository URI returned by the create command later to build and tag the images we create."}),"\n",(0,s.jsxs)(n.p,{children:["For more information on provisioning ECR repositories check the ",(0,s.jsx)(n.a,{href:"https://docs.aws.amazon.com/AmazonECR/latest/public/public-getting-started.html",children:"documentation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"set-up-eks",children:"Set up EKS"}),"\n",(0,s.jsxs)(n.p,{children:["We will need to provision a Kubernetes cluster to deploy everything on. We will do this using the ",(0,s.jsx)(n.code,{children:"eksctl"})," command line\nutility. Before provisioning our EKS cluster we will need to create a key pair for the nodes:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"aws ec2 create-key-pair --region us-east-1 --key-name ratifyDemo\n"})}),"\n",(0,s.jsx)(n.p,{children:"Save the output to your local machine, then run the following to create the cluster:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"eksctl create cluster \\\n  --name ratify-demo \\\n  --region us-east-1 \\\n  --zones us-east-1c,us-east-1d \\\n  --with-oidc \\\n  --ssh-access \\\n  --ssh-public-key ratifyDemo\n\naws eks update-kubeconfig --name ratify-demo\n"})}),"\n",(0,s.jsx)(n.p,{children:"The template will provision a basic EKS cluster with default settings."}),"\n",(0,s.jsxs)(n.p,{children:["Additional information on EKS deployment can be found in the EKS ",(0,s.jsx)(n.a,{href:"https://docs.aws.amazon.com/eks/latest/userguide/getting-started-console.html",children:"documentation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"prepare-container-image",children:"Prepare Container Image"}),"\n",(0,s.jsx)(n.p,{children:"For this guide we will create a basic container image we can use to simulate deployments of a service. We will start by\nbuilding the container image:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"docker build -t $REPO_URI:v1 https://github.com/wabbit-networks/net-monitor.git#main\n"})}),"\n",(0,s.jsx)(n.p,{children:"After the container is built we need to push it to the repository:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"aws ecr-public get-login-password --region us-east-1 | docker login --u
1sername AWS --password-stdin $REPO_URI\n\ndocker push $REPO_URI:v1\n"})}),"\n",(0,s.jsx)(n.h2,{id:"sign-container-image",children:"Sign Container Image"}),"\n",(0,s.jsxs)(n.p,{children:["For this guide, we will sign the image using ",(0,s.jsx)(n.code,{children:"notation"})," and AWS Signer resources. First, we will create a SigningProfile in AWS Signer and get the ARN:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"aws signer put-signing-profile \\\n    --profile-name ratifyDemo \\\n    --platform-id Notation-OCI-SHA384-ECDSA\n\nexport PROFILE_ARN=$(aws signer get-signing-profile --profile-name ratifyDemo | jq .arn -r)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["To use the SigningProfile in ",(0,s.jsx)(n.code,{children:"notation"}),", we will add the profile as signing key:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"notation key add \\\n    --plugin com.amazonaws.signer.notation.plugin \\\n    --id $PROFILE_ARN \\\n    --default ratifyDemo\n"})}),"\n",(0,s.jsxs)(n.p,{children:["After the profile has been added, we will use ",(0,s.jsx)(n.code,{children:"notation"})," to sign the image with the SigningProfile:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"notation sign $REPO_URI:v1\n"})}),"\n",(0,s.jsx)(n.p,{children:"Both the container image and the signature should now be in the public ECR repository. We can also inspect the signature information using notation:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"notation inspect $REPO_URI:v1\n"})}),"\n",(0,s.jsxs)(n.p,{children:["More information on signing can be found in the ",(0,s.jsx)(n.a,{href:"https://docs.aws.amazon.com/signer/latest/developerguide/Welcome.html",children:"AWS Signer"})," and ",(0,s.jsx)(n.a,{href:"https://github.com/notaryproject/notation",children:"notation"})," documentation."]}),"\n",(0,s.jsx)(n.h2,{id:"deploy-gatekeeper",children:"Deploy Gatekeeper"}),"\n",(0,s.jsxs)(n.p,{children:["The Ratify container will perform the actual validation of images and their artifacts, but ",(0,s.jsx)(n.a,{href:"https://github.com/open-policy-agent/gatekeeper",children:"Gatekeeper"})," is used as the policy controller for Kubernetes."]}),"\n",(0,s.jsx)(n.p,{children:"We first need to install Gatekeeper into the cluster. We will use the Gatekeeper helm chart with some customizations:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts\n\nhelm install gatekeeper/gatekeeper  \\\n    --name-template=gatekeeper \\\n    --namespace gatekeeper-system --create-namespace \\\n    --set enableExternalData=true \\\n    --set validatingWebhookTimeoutSeconds=5 \\\n    --set mutatingWebhookTimeoutSeconds=2\n"})}),"\n",(0,s.jsx)(n.p,{children:"Next, we need to deploy a Gatekeeper policy and constraint. For this guide, we will use a sample policy and constraint that requires images to have at least one trusted signature."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl apply -f https://raw.githubusercontent.com/deislabs/ratify/main/library/notation-validation/template.yml\nkubectl apply -f https://raw.githubusercontent.com/deislabs/ratify/main/library/notation-validation/samples/constraint.yaml\n"})}),"\n",(0,s.jsxs)(n.p,{children:["More complex combinations of regos and Ratify verifiers can be used to accomplish many types of checks. See the ",(0,s.jsx)(n.a,{href:"https://open-policy-agent.github.io/gatekeeper/website/docs/",children:"Gatekeeper docs"})," for more information on rego authoring."]}),"\n",(0,s.jsx)(n.h2,{id:"configure-iam-permissions",children:"Configure IAM Permissions"}),"\n",(0,s.jsx)(n.p,{children:"Before deploying Ratify, we need to configure permissions for Ratify to be able to make requests to AWS Signer. To do this we will use the IAM Roles for Service Accounts integration. First, we need to create an IAM policy that has AWS Signer permissions:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'cat > signer_policy.json << EOF\n{\n    "Version": "2012-10-17",\n    "Statement": [\n        {\n            "Effect": "Allow",\n            "Action": [\n                "signer:GetRevocationStatus"\n            ],\n            "Resource": "*"\n        }\n    ]\n}\nEOF\n\nexport POLICY_ARN=$(aws iam create-policy \\\n    --policy-name signerGetRevocationStatus \\\n    --policy-document file://signer_policy.json \\\n    | jq ."Policy"."Arn" -r)\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Then, we will use ",(0,s.jsx)(n.code,{children:"eksctl"})," to create a service account and role and attach the policies to the role:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"\neksctl create iamserviceaccount \\\n    --name ratify-admin \\\n    --namespace gatekeeper-system \\\n    --cluster ratify-demo \\\n    --attach-policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \\\n    --attach-policy-arn $POLICY_ARN \\\n    --approve\n"})}),"\n",(0,s.jsxs)(n.p,{children:["We can validate that the service account was created by using ",(0,s.jsx)(n.code,{children:"kubectl"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl -n gatekeeper-system get sa ratify-admin -oyaml\n"})}),"\n",(0,s.jsx)(n.h2,{id:"deploy-ratify",children:"Deploy Ratify"}),"\n",(0,s.jsx)(n.p,{children:"Now we can deploy Ratify to our cluster with the AWS Signer root as the notation verification certificate:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"curl -sSLO https://d2hvyiie56hcat.cloudfront.net/aws-signer-notation-root.cert\n\nhelm install ratify \\\n    ratify/ratify --atomic \\\n    --namespace gatekeeper-system \\\n    --set-file notationCert=./aws-signer-notation-root.cert \\\n    --set featureFlags.RATIFY_EXPERIMENTAL_DY
1NAMIC_PLUGINS=true \\\n    --set serviceAccount.create=false \\\n    --set oras.authProviders.awsEcrBasicEnabled=true\n"})}),"\n",(0,s.jsxs)(n.p,{children:["After deploying Ratify, we will download the AWS Signer notation plugin to the Ratify pod using the ",(0,s.jsx)(n.a,{href:"/docs/1.0/reference/dynamic-plugins",children:"Dynamic Plugins feature"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"cat > aws-signer-plugin.yaml << EOF\napiVersion: config.ratify.deislabs.io/v1beta1\nkind: Verifier\nmetadata:\n  name: aws-signer-plugin\nspec:\n  name: notation-com.amazonaws.signer.notation.plugin\n  artifactTypes: application/vnd.oci.image.manifest.v1+json\n  source:\n    artifact: public.ecr.aws/aws-signer/notation-plugin:linux-amd64-latest\nEOF\n\nkubectl apply -f aws-signer-plugin.yaml\n"})}),"\n",(0,s.jsx)(n.p,{children:"Finally, we will create a verifier that specifies the trust policy to use when verifying signatures. In this guide, we will use a trust policy that only trusts images signed by the SigningProfile we created earlier:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:'cat > notation-verifier.yaml << EOF\napiVersion: config.ratify.deislabs.io/v1beta1\nkind: Verifier\nmetadata:\n  name: verifier-notation\nspec:\n  name: notation\n  artifactTypes: application/vnd.cncf.notary.signature\n  parameters:\n    verificationCertStores:\n      certs:\n        - ratify-notation-inline-cert\n    trustPolicyDoc:\n      version: "1.0"\n      trustPolicies:\n        - name: default\n          registryScopes:\n            - "*"\n          signatureVerification:\n            level: strict\n          trustStores:\n            - signingAuthority:certs\n          trustedIdentities:\n            - $PROFILE_ARN\nEOF\n\nkubectl apply -f notation-verifier.yaml\n'})}),"\n",(0,s.jsxs)(n.p,{children:["More complex trust policies can be used to customize verification. See ",(0,s.jsx)(n.a,{href:"https://github.com/notaryproject/notaryproject/blob/main/specs/trust-store-trust-policy.md#trust-policy",children:"notation documentation"})," for more information on writing trust policies."]}),"\n",(0,s.jsx)(n.h2,{id:"deploy-container-image",children:"Deploy Container Image"}),"\n",(0,s.jsx)(n.p,{children:"Now that the signed container image is in the registry and Ratify is installed into the EKS cluster we can deploy our\ncontainer image:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl run demosigned --image $REPO_URI:v1\n"})}),"\n",(0,s.jsx)(n.p,{children:"We should be able to see from the Ratify and Gatekeeper logs that the container signature was validated. The pod for the container should also be running."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl logs -n gatekeeper-system deployment/ratify\n"})}),"\n",(0,s.jsx)(n.p,{children:"We can also test that an image without a valid signature is not able to run:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"kubectl run demounsigned --image hello-world\n"})}),"\n",(0,s.jsx)(n.p,{children:"The command should fail with an error and we should be able to see from the Ratify and Gatekeeper logs that the signature validation failed."}),"\n",(0,s.jsx)(n.h2,{id:"cleaning-up",children:"Cleaning Up"}),"\n",(0,s.jsx)(n.p,{children:"We can use awscli and eksctl to delete any resources created:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-shell",children:"aws ecr-public delete-repository --region us-east-1 --repository-name $REPO_NAME\n\neksctl delete cluster --region us-east-1 --name ratify-demo\n\naws signer cancel-signing-profile --profile-name ratifyDemo\n"})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453(e,n,i){i.d(n,{R:()=>r,x:()=>o});var t=i(96540);const s={},a=t.createContext(s);function r(e){const n=t.useContext(a);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]);

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