使用企业合同管理合规性
了解企业合同如何使您更好地验证和管理您提升的代码合规性。另外,自定义示例策略以适合您的企业标准。
摘要
前言
企业合同是一种策略驱动的工作流工具,通过定义和执行策略来构建和测试容器镜像来维护软件供应链安全性。安全 CI/CD 工作流应包含工件验证,以尽早检测问题。这是企业合同的任务,以验证容器镜像是否已签名并由已知可信的构建系统测试。
第 1 章 Red Hat Trusted Application Pipeline 的企业合同
软件供应链更复杂的变得复杂,更关键是利用可靠的检查和最佳实践来确保软件构件的完整性和源代码依赖。镜像容器等工件。在这里,Red Hat Enterprise Contract 输入您的 Red Hat Trusted Application Pipeline 构建和部署体验。
企业合同是一种策略驱动的工作流工具,通过定义和执行策略来构建和测试容器镜像来维护软件供应链安全性。对于在测试时为软件 Artifacts (SLSA)验证创建 Supply-chain Levels (SLSA)的构建系统,如带有 SLSA GitHub Generator 的 Tekton 带有 Tekton 链和 GitHub Actions 的 Tekton,检查签名并确认该签名并确认是否符合验证和维护软件提供链的完整性的关键部分。安全 CI/CD 工作流应包含工件验证,以尽早检测问题。这是企业合同的任务,以验证容器镜像是否已签名并由已知可信的构建系统测试。
验证签名和测试的容器镜像的一般步骤如下:
- 使用 Red Hat Trusted Application Pipeline 创建或复制容器镜像。
- 使用 Cosign 生成签名密钥。
- 使用 Cosign 为容器镜像签名。
- 使用 Cosign 测试镜像。
- 使用 Enterprise Contract CLI 验证您已签名和经测试的容器镜像。
但是,它意味着为软件工件(如容器镜像) 签名和 attest 吗?为什么要这样做?如何?
与未签名工件相比,签名的软件工件(如容器镜像)会显著降低多个攻击向量的风险。签名容器镜像时,各种加密技术将镜像绑定到特定的实体或机构。结果是一种数字签名,验证镜像的真实性,以便您可以将其追踪回其创建者(即实体或机构),同时验证镜像是否在签名后没有被更改或篡改。有关软件供应链威胁的更多信息,请参阅 Supply 链威胁。
企业合同使用行业标准 Sigstore Cosign 作为资源库来验证您的容器镜像。使用 Red Hat Trusted Artifact Signer,红帽支持的 Sigstore 框架版本,您可以使用您自己的 Sigstore 服务实例来通过 Cosign CLI 签发和测试容器镜像。有关 RHTAS 的更多信息,请参阅 Red Hat Trusted Artifact Signer。
与测试过程中的软件构件一样,在没有验证的情况下,它可能无法发生。经验证的 是有关软件工件的可验证信息,如描述生成工件的位置、时间和方式的容器镜像。attestation 本身是一个经过身份验证的声明,其元数据形式证明工件是完整且可信的。Enterprise Contract 使用该认证来加密验证构建没有被篡改,并根据任何一组策略(如 SLSA 要求)检查构建。有关 SLSA 的更多信息,请参阅关于 SLSA。
当您将代码从 RHTAP 开发命名空间推送到 stage 命名空间,或从 stage 命名空间推送到 production 命名空间时,企业合同会自动运行其验证检查,以确保容器镜像由已知和可信的构建系统签名和测试。当您的镜像通过企业合同检查时,您可以合并代码更改,以完成从一个环境到下一个环境的提升。有关将应用程序部署到其他命名空间的更多信息,请参阅 受信任的应用程序管道软件模板。有关 RHTAP 保存部署清单的更多信息,请参阅 RHTAP GitOps 存储库 及其 YAML 文件。
其他资源
有关签名和测试容器镜像的更多信息,请参阅 签署容器镜像。
第 2 章 安装企业合同命令行
先决条件
- 在 Red Hat OpenShift Container Platform 版本 4.13 或更高版本上安装 Red Hat Trusted Artifact Signer 安装。
-
安装了
cosign
和oc
二进制文件的工作站。 - 访问 OpenShift Web 控制台。
流程
从 OpenShift 集群下载
ec
二进制文件。- 登录 OpenShift Web 控制台。在主页中,单击 ? 图标,选择 Command line tools,转至 ec 下载部分,然后单击您的平台的链接。
在工作站上打开一个终端,解压缩二进制
.gz
文件,然后设置 execute 位:Example
gunzip ec-amd64.gz chmod +x ec-amd64
将二进制文件移到
$PATH
环境中的位置:Example
sudo mv ec-amd64 /usr/local/bin/ec
验证
-
运行
ec version
命令。结果应该是您刚才安装的企业合同 CLI 的版本。
第 3 章 创建策略
企业合同 策略是 规则或一组规则以及特定于企业合同的注解。企业合同可以执行多种策略检查,包括检查 红帽产品所需的所有策略规则。企业合同使用名为 Open Policy Agent 或 OPA 的一般目的策略引擎。opa 使用自己的语言(称为 Rego )定义其策略规则。这意味着,在 Enterprise Contract 策略中的 OPA 中的策略规则也会在 Rego 中定义。
流程
创建一个 Rego 文件来定义一个新的策略规则,如下例所示:
echo 'package zero_to_hero import future.keywords.contains import future.keywords.if import future.keywords.in # METADATA 1 # title: Builder ID # description: Verify the SLSA Provenance has the builder.id set to # the expected value. # custom: # short_name: builder_id 2 # failure_msg: The builder ID %q is not the expected %q # solution: >- # Ensure the correct build system was used to build the container # image. deny contains result if { some attestation in input.attestations 3 attestation.statement.predicateType == "https://slsa.dev/provenance/v0.2" expected := "https://localhost/dummy-id" got := attestation.statement.predicate.builder.id expected != got result := { "code": "zero_to_hero.builder_id", "msg": sprintf("The builder ID %q is not expected, %q", [got, expected]) } } ' > rules.rego
提示您可以将
输入
对象保存到 JSON 文件,以查看可用的值,这有助于编写新的策略规则。要将输入
对象保存为名为input.json
的 JSON 文件,请运行类似以下示例的命令:ec validate image --public-key cosign.pub --image "$REPOSITORY:latest" --policy policy.yaml \ --output policy-input=input.json
创建策略配置以使用您的新策略规则,如下例所示:
echo " --- sources: - policy: - $(pwd)/rules.rego " > policy.yaml
使用您的新策略验证您的容器镜像,并在成功和违反报告中显示其他信息,如下例所示:
ec validate image --public-key cosign.pub --image "$REPOSITORY:latest" --policy policy.yaml \ --show-successes --info --output yaml
验证
-
检查 Successes 和 violations 报告,以确保您的新规则位于
successes
列表中。
其他资源
- 有关一组有用的企业合同策略规则,请参阅 ec-policies GitHub 存储库。
- 有关 OPA 和 Rego 的更多信息,请参阅 OPA 的策略 语言 内容。
- 有关 SLSA 验证的更多信息,请参阅 SLSA Provenance。
3.1. 配置策略
您可以使用内联 JSON 或 YAML 字符串配置企业合同策略。此策略有时称为配置或 合同,指定企业合同应在哪里找到用于应用您要实施的策略的规则和数据。您还可以包含或排除单个规则或特定规则软件包。
流程
在命令行中配置您的策略作为 JSON 或 YAML 字符串,如下例所示:
ec validate image --policy '{ "sources": [ { "policy": ["oci::quay.io/enterprise-contract/ec-release-policy:latest"], "data": ["git::https://github.com/enterprise-contract/ec-policies//example/data"], "config": {"include": ["@minimal"]} } ] }' ...
(可选)从您的企业合同策略中排除特定规则软件包,如下例所示:
{ "sources": [ { "policy": [ "oci::quay.io/enterprise-contract/ec-release-policy:latest" ], "data": [ "git::https://github.com/enterprise-contract/ec-policies//example/data" ], "config": { "exclude": [ "attestation_task_bundle", "slsa_build_scripted_build" ] } } ] }
此命令包含来自每个软件包的每个规则,但指定软件包中的规则除外。
(可选) Exclude 单个规则,如下例所示:
{ "sources": [ { "policy": [ "oci::quay.io/enterprise-contract/ec-release-policy:latest" ], "data": [ "git::https://github.com/enterprise-contract/ec-policies//example/data" ], "config": { "exclude": [ "attestation_task_bundle.unacceptable_task_bundle" ] } } ] }
此命令包括
attestation_task_bundle
软件包中的每个规则,但unacceptable_task_bundle
规则除外。(可选)只包括特定软件包的规则,如下例所示:
{ "sources": [ { "policy": [ "oci::quay.io/enterprise-contract/ec-release-policy:latest" ], "data": [ "git::https://github.com/enterprise-contract/ec-policies//example/data" ], "config": { "include": [ "test", "java" ] } } ] }
此命令仅包含指定软件包中的规则。
(可选)只包括特定软件包中的一些规则。这意味着,您可以指定
include
和exclude
来仅选择要包含企业合同策略的规则,如下例所示:{ "sources": [ { "policy": [ "oci::quay.io/enterprise-contract/ec-release-policy:latest" ], "data": [ "git::https://github.com/enterprise-contract/ec-policies//example/data" ], "config": { "include": [ ""*"", 1 "attestation_task_bundle.unacceptable_task_bundle" ], "exclude": [ "attestation_task_bundle.*" ] } } ] }
- 1
- 星号 integrity 充当匹配任何软件包的通配符。请注意,它不匹配部分名称,这意味着您无法指定 "s*" 以匹配以"s"开头的每个软件包。
这些命令指定您 只包括
attestation
unacceptable_task_bundle 规则,并排除该软件包中的所有其他规则。_task_bundle
软件包中的(可选) Exclude 某些检查,以便企业合同可以验证您的容器镜像,即使这些检查失败或未完成,如下例所示:
{ "sources": [ { "policy": [ "oci::quay.io/enterprise-contract/ec-release-policy:latest" ], "data": [ "git::https://github.com/enterprise-contract/ec-policies//example/data" ], "config": { "exclude": [ "test:get-clair-scan", "test:clamav-scan" ] } } ] }
此命令指定,如果已确定的检查失败或未完成,企业合同仍然可以完成以验证您的容器镜像。
(可选)通过运行 config.policy.
include 命令或
命令以及字符串列表来修改软件包中的规则的默认值。config.policy
.exclude您的字符串列表应包括以下之一:
- "package name" - 从可用 规则集合列表中的软件包 中进行选择。
-
"rule name" - 输入软件包名称和规则代码(用点分隔)来指定规则名称,如下例所示:attestation
_type.unknown_att_type
。您可以在此处找到"Attestation type"下的规则代码。https://enterprisecontract.dev/docs/ec-policies/release_policy.html#attestation_type_package - "package name:term" - 某些策略规则处理项目列表。将 "term" 添加到 "package name" 字符串时,您可以从该列表中排除或包含特定项。这的工作方式与"软件包名称"类似,但它仅适用于与该术语匹配的软件包中的策略规则。例如,如果您运行 test 软件包,您可以选择忽略给定的测试案例,但包含所有测试。
- "rule name:term" - 这与 "package name:term" 类似,除了从软件包中包含或排除某个项目外,您可以包括 ot 排除特定的软件包 策略规则。
-
"@collection name" - 将其添加到字符串中,以指定预定义的规则集合。TMake 请确定您使用
@
符号为集合名称添加前缀。从此处 提供的规则集合中选择。
其他资源
有关发行策略详情的完整列表,请参阅发布策略 https://enterprisecontract.dev/docs/ec-policies/release_policy.html。
第 4 章 签名容器镜像
先决条件
- 访问 OpenShift Web 控制台。
- 在 OpenShift 版本 4.13 或更高版本上运行的 Red Hat Trusted Artifact Signer (RHTAS)安装。
-
安装了
ec
、cosign
和oc
二进制文件的工作站。
流程
登录到您的 OpenShift 集群:
语法
oc login --token=TOKEN --server=SERVER_URL_AND_PORT
Example
oc login --token=sha256~ZvFDBvoIYAbVECixS4-WmkN4RfnNd8Neh3y1WuiFPXC --server=https://example.com:6443
注意要查找您的命令行登录令牌和 URL,请登录 OpenShift Web 控制台。单击您的用户名,然后单击 Copy login command。如有提示,再次输入您的用户名和密码,然后单击 显示令牌。
登录 RHTAS。确保配置 RHTAS shell 环境以签署和验证容器镜像;例如:
cd sigstore-ocp source tas-env-variables.sh
您还可以选择手动设置环境变量,例如:
export OPENSHIFT_APPS_SUBDOMAIN=apps.$(oc get dns cluster -o jsonpath='{ .spec.baseDomain }') export OIDC_AUTHENTICATION_REALM=sigstore export FULCIO_URL=https://fulcio.$OPENSHIFT_APPS_SUBDOMAIN export OIDC_ISSUER_URL=https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/auth/realms/$OIDC_AUTHENTICATION_REALM export REKOR_URL=https://rekor.$OPENSHIFT_APPS_SUBDOMAIN export TUF_URL=https://tuf.$OPENSHIFT_APPS_SUBDOMAIN
Example
$ source ./tas-env-vars.sh
-
运行以下命令,从 OpenShift 集群注销:
oc logout
。 -
识别您要签名的容器镜像和 attest;例如:
IMAGE=quay.io/lucarval/rhtas-test@sha256:6b95efc134c2af3d45472c0a2f88e6085433df058cc210abb2bb061ac4d74359
。 -
向 RHTAP 指明您要使用 Red Hat Trusted Artifact Signer 而不是公共 Sigstore 部署进行签名和测试您的容器镜像。输入此命令:co
sign initialize --mirror=$TUF_URL --root=$TUF_URL/root.json
。 使用以下命令为您的容器镜像签名:
cosign sign -y --fulcio-url=$FULCIO_URL --rekor-url=$REKOR_URL \ --oidc-issuer=$OIDC_ISSUER_URL $IMAGE
- 出现提示时,登录安装 RHTAS 时安装的 RHTAP 的 Keycloak 实例。因此 Keycloak 可以为您进行身份验证。
后续步骤
您的镜像现已签名。现在,您可以:
- 在测试时创建 SLSA 验证,并将它与容器镜像相关联。
- 使用 Red Hat Enterprise Contract 来验证容器镜像。
其他资源
- 有关 Red Hat Trusted Artifact Signer 的更多信息,特别是它如何与 RHTAP 和企业合同一起使用,请参阅 Red Hat Trusted Artifact Signer Deployment。
- 有关 Keycloak 的更多信息,请参阅 Keycloak.org。
4.1. 生成签名密钥以签名和测试容器镜像
您必须有签名密钥,然后才能签名和测试容器镜像。
先决条件
-
安装了
cosign
二进制文件的工作站。
流程
-
在 CLI 中,运行这个命令:co
sign generate-key-pair
。 - 出现提示时,输入新密码作为密钥对。确保您的密码是 memorable 且强强。
验证
您现在应当有两个新文件位于工作目录中:cosign
.pub 文件和
cosign.key
文件。-
cosign.pub
文件包含您的公钥。您可以与需要验证容器镜像的任何协作者共享此密钥。 -
cosign.key
文件是用于签名内容的私钥。只有负责签名和测试镜像的人员应有权访问cosign.key
文件。
-
4.2. 使用 Enterprise Contract 和 Red Hat Trusted Artifact Signer 验证容器镜像签名
安装 Red Hat Trusted Artifact Signer (RHTAS)服务时,您可以使用 ec
二进制文件来验证使用 RHTAS 服务的无密钥签名框架的容器镜像的测试和签名。有关安装 RHTAS 的更多信息,请参阅使用 Operator Lifecycle Manager 安装 Red Hat Trusted Artifact Signer。
先决条件
- 在 OpenShift 版本 4.13 或更高版本上运行的可正常工作的 RHTAS 安装。
- 访问 OpenShift Web 控制台。
-
安装了
cosign
和oc
二进制文件的工作站。
流程
从 OpenShift 集群下载
ec
二进制文件:- 登录 OpenShift Web 控制台。在主页中,单击右上角的 ? 图标,然后选择 Command Line Tools。
- 在 ec download 部分中,单击您的平台的链接。
打开终端,解压缩
.gz
文件,并在ec
二进制文件上设置 execute 位:Linux 和 macOS 示例
-
$ gunzip ec-amd64.gz
-
$ chmod +x ec-amd64
-
将
ec
二进制文件移到$PATH
环境中的目录中:Example
$ sudo mv ec-amd64 /usr/local/bin/ec
运行 ec validate image --help
命令来查看所有 image 验证命令选项。
为容器镜像签名和验证配置 shell 环境。
打开终端,并从
sigstore-ocp
目录中运行tas-env-variables.sh
脚本:Example
cd sigstore-ocp source tas-env-variables.sh
(可选)手动设置环境变量:
Example
export OPENSHIFT_APPS_SUBDOMAIN=apps.$(oc get dns cluster -o jsonpath='{ .spec.baseDomain }') export OIDC_AUTHENTICATION_REALM=sigstore export FULCIO_URL=https://fulcio.$OPENSHIFT_APPS_SUBDOMAIN export OIDC_ISSUER_URL=https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/auth/realms/$OIDC_AUTHENTICATION_REALM export REKOR_URL=https://rekor.$OPENSHIFT_APPS_SUBDOMAIN export TUF_URL=https://tuf.$OPENSHIFT_APPS_SUBDOMAIN
Example
$ source ./tas-env-vars.sh
初始化更新框架(TUF)系统:
Example
cosign initialize --mirror=$TUF_URL --root=$TUF_URL/root.json
为您的容器镜像签名:
语法
cosign sign -y --fulcio-url=$FULCIO_URL --rekor-url=$REKOR_URL --oidc-issuer=$OIDC_ISSUER_URL IMAGE_NAME
Example
cosign sign -y --fulcio-url=$FULCIO_URL --rekor-url=$REKOR_URL --oidc-issuer=$OIDC_ISSUER_URL example-hello-world@sha256:2788a47fd0ef1ece30898c1e608050ea71036d3329b9772dbb3d1f693f693f745c
在打开的 Web 浏览器中,使用电子邮件地址签署容器镜像。
创建
predicate.json
文件:Example
{ "builder": { "id": "https://localhost/dummy-id" }, "buildType": "https://example.com/tekton-pipeline", "invocation": {}, "buildConfig": {}, "metadata": { "completeness": { "parameters": false, "environment": false, "materials": false }, "reproducible": false }, "materials": [] }
将
predicate.json
文件与容器镜像关联:语法
cosign attest -y --predicate ./predicate.json \ --type slsaprovenance IMAGE_NAME:TAG
Example
$ cosign attest -y --predicate ./predicate.json \ --type slsaprovenance example.io/hello-world:latest
验证容器镜像至少有一个至少测试和签名:
语法
cosign tree IMAGE_NAME:TAG
Example
$ cosign tree example.io/hello-world:latest 📦 Supply Chain Security Related artifacts for an image: example.io/hello-world@sha256:7de5fa822a9d1e507c36565ee0cf50c08faa64505461c844a3ce3944d23efa35 └── 💾 Attestations for an image tag: example.io/hello-world:sha256-7de5fa822a9d1e507c36565ee0cf50c08faa64505461c844a3ce3944d23efa35.att └── 🍒 sha256:40d94d96a6d3ab3d94b429881e1b470ae9a3cac55a3ec874051bdecd9da06c2e └── 🔐 Signatures for an image tag: example.io/hello-world:sha256-7de5fa822a9d1e507c36565ee0cf50c08faa64505461c844a3ce3944d23efa35.sig └── 🍒 sha256:f32171250715d4538aec33adc40fac2343f5092631d4fc2457e2116a489387b7
使用企业合同验证容器镜像:
语法
ec validate image --image IMAGE_NAME:TAG \ --certificate-identity-regexp 'SIGNER_EMAIL_ADDR' \ --certificate-oidc-issuer-regexp 'keycloak-keycloak-system' \ --output yaml --show-successes
Example
$ ec validate image --image example.io/hello-world:latest \ --certificate-identity 'jdoe@example.com' \ --certificate-oidc-issuer 'keycloak-keycloak-system' \ --output yaml --show-successes success: true successes: - metadata: code: builtin.attestation.signature_check msg: Pass - metadata: code: builtin.attestation.syntax_check msg: Pass - metadata: code: builtin.image.signature_check msg: Pass ec-version: v0.1.2427-499ef12 effective-time: "2024-01-21T19:57:51.338191Z" key: "" policy: {} success: true
企业合同生成通过/失败报告,其中包含有关任何安全违反情况的详细信息。当您添加 the-
info
标志时,报告会包括任何违反情况的更多详情和可能的解决方案。
其他资源
- 有关 RHTAS 的更多信息,请参阅 Red Hat Trusted Artifact Signer 的产品文档。
- 有关 TUF 的更多信息,请参阅 更新框架。
- 有关使用 Cosign 签名和验证容器镜像的更多信息,请参阅 ADD LATER。
- 有关 SLSA provenance predicate 规格的更多信息,请参阅 SLSA Provenance。
第 5 章 测试和验证容器镜像
在企业合同可以验证您签名的容器镜像之前,您必须先创建 SLSA 证明,并将它与容器镜像关联。经验证的是有关软件工件的可验证信息,包括供应链中给定软件"链接"的位置、时间和方式。有关软件工件(SLSA)验证的 Supply-chain Levels 的更多信息,请参阅 SLSA Provenance。
先决条件
- 签名的容器镜像。
- 访问 OpenShift Web 控制台。
- 在 OpenShift 版本 4.13 或更高版本上运行的 Red Hat Trusted Artifact Signer 安装。
-
安装了
cosign
和oc
二进制文件的工作站。
流程
创建 SLSA provenance
predicate.json
文件,例如:echo '{ "builder": { "id": "https://localhost/dummy-id" }, "buildType": "https://localhost/dummy-type", "invocation": {}, "buildConfig": {}, "metadata": { "buildStartedOn": "2023-09-25T16:26:44Z", "buildFinishedOn": "2023-09-25T16:28:59Z", "completeness": { "parameters": false, "environment": false, "materials": false }, "reproducible": false }, "materials": [] } ' > predicate.json
签名并测试您刚才创建的
predicate.json
文件,例如:cosign attest -y --fulcio-url=$FULCIO_URL \ --rekor-url=$REKOR_URL \ --oidc-issuer=$OIDC_ISSUER_URL \ --predicate predicate.json \ --type slsaprovenance $IMAGE
Keycloak 打开,以便在对容器镜像进行签名时基于您的登录自动验证。
使用企业合同验证签名和测试,例如:
ec validate image --image $IMAGE \ --certificate-identity-regexp '.*' \ --certificate-oidc-issuer-regexp '.*' \ --output yaml --show-successes
运行 ec validate image
命令时尽量具体,以便每个签名与预期 的身份
匹配。
验证
- 当企业合同验证容器镜像后,会打开所有企业合同验证和签名的详细报告。
其他资源
- 有关 Red Hat Trusted Artifact Signer 的更多信息,特别是它如何与 RHTAP 和企业合同一起使用,请参阅 Red Hat Trusted Artifact Signer Deployment。
- 有关 SLSA 的更多信息,请参阅 slsa.dev。
- 有关 Keycloak 的更多信息,请参阅 keycloak.org。