这是尚未发布的文档。 Admission Controller 1.39-dev.

安全供应链

安全供应链基础设施可以验证其各个部分或环节的有效性。它让用户和开发者展示其软件组件或工件的保管链。这是一种积极的方式来减轻安全问题。

Sigstore 项目提供了用于此的工具和基础设施。它用于验证工件供应链的完整性。

Admission Controller 使用 cosign 以及 fulcio 和 rekor 基础设施,这些都是由 Sigstore 项目提供的。

集群操作员可以配置 SUSE Security Admission Controller 仅运行由受信任实体签署的策略。策略开发者可以签署他们的策略并将其发布在注册表中。

先决条件

在接下来的部分中,您需要安装一些工具。这些工具是为了让用户能够签署和验证 OCI 工件签名。示例展示了使用 cosign 和 kwctl 工具来签署和检查策略。

要使用 GitHub 签署策略,您需要安装 GitHub actions。

无密钥签名使用 Sigstore 项目提供的默认 fulcio 和 rekor 实例。如果需要,请查看 Sigstore 文档以获取有关如何使用您自己的基础设施的详细信息。

签署策略

Admission Controller 建议使用 Sigstore 的 cosign 工具来签署策略。本节展示了一种基于密钥的签署策略的方法。您需要为此生成一对私钥和公钥。生成的密钥有助于验证签署的工件是否来自预期的用户。要生成此密钥对,请使用此 cosign generate-key-pair 命令:

cosign generate-key-pair

结果是提示您输入并验证密码:

Enter password for private key: ●●●●●●●●
Enter password for private key again: ●●●●●●●●
Private key written to cosign.key
Public key written to cosign.pub

现在您可以使用此密钥来签署策略。

请勿分享私钥文件,cosign.key。这是一个仅供密钥拥有者用于签署策略的秘密文件。

要签署策略,您可以使用 cosign sign,并传递 --key 命令行参数与您的私钥文件:

cosign sign --key cosign.key ghcr.io/kubewarden/policies/user-group-psp:latest

结果是提示输入指定私钥的密码:

an error occurred: no provider found for that key reference, will try to load key from disk...
Enter password for private key: ●●●●●●●●
Pushing signature to: ghcr.io/kubewarden/policies/user-group-psp

此命令通过创建一个新的签名对象来签署策略。签名对象随后与策略一起上传到注册表。现在该策略已准备好在使用签名验证的 Admission Controller 安装中使用。

同一策略可以由同一用户或不同用户多次签署。这些签名与原始签名一起添加到签名对象中。

有关签署过程如何工作的更多信息,请查看 Sigstore 项目文档。

无密钥签署

通常,策略是通过 CI/CD 管道自动构建的。这使得密钥生成过程变得复杂。这个无密钥的 Sigstore 工作流程适用于这些情况。无须使用长期有效的签名密钥,无密钥工作流程使用证书颁发机构(CA)和证书链。

您将生成的短期证书密钥链接到信任链中。这是通过身份挑战来确认签名者的身份。证书密钥的有效期足够长,以便进行签名。身份挑战通过对 OpenID Connect(OIDC)提供者进行身份验证来进行。Sigstore 的 Fulcio 公共基础设施提供信任链。

签名使用 Sigstore 的 cosign 工具。

$ cosign sign ghcr.io/kubewarden/policies/user-group-psp:latest
cosign 输出
Generating ephemeral keys...
Retrieving signed certificate...
Your browser will now be opened to:
https://oauth2.sigstore.dev/auth/auth?access_type=online&client_id=sigstore&code_challenge=<REDACTED>&code_challenge_method=S256&nonce=<REDACTED>&redirect_uri=http%3A%2F%2Flocalhost%3A34021%2Fauth%2Fcallback&response_type=code&scope=openid+email&state=<REDACTED>
client.go:196: root pinning is not supported in Spec 1.0.19
Successfully verified SCT...
tlog entry created with index: 1819248
Pushing signature to: ghcr.io/kubewarden/policies/user-group-psp

这会签署策略并将其推送到储存库。没有生成任何作为副产品的密钥。

如何在 GitHub 工作流程中签署工件

在使用无密钥签名时,在 GitHub 操作中,cosign 不需要用户登录到 OIDC 提供者。在执行 GitHub 工作流程期间,可以使用 GitHub 令牌。它用于验证用户并生成临时密钥。签名过程与无密钥模式下使用的相同。这是 Admission Controller 项目如何签名其策略的示例:

描述 Admission Controller 策略签名的 YAML
# ... beginning of the workflow file ...
jobs:
  build:
    name: Build container image
    runs-on: ubuntu-latest
    steps:
      # ... other steps building the container image ...
      -
      name: Login to GitHub Container Registry
      uses: docker/login-action@v1
      with:
        registry: ghcr.io
        username: ${{ github.repository_owner }}
        password: ${{ inputs.GITHUB_TOKEN }}
      -
      name: Publish Wasm policy artifact to OCI registry with the 'latest' tag
      shell: bash
      if: ${{ startsWith(github.ref, 'refs/heads/') }}
      env:
        COSIGN_EXPERIMENTAL: 1
      run: |
        set -ex
        echo Pushing policy to OCI container registry
        IMMUTABLE_REF=$(kwctl push -o json ${{ PATH_TO_BUILT_WASM_FILE }} ghcr.io/myorg/policies/my-great-policy:latest | jq -r .immutable_ref)
        echo Keyless signing of policy using cosign
        cosign sign ${IMMUTABLE_REF}
      # ... other build steps ...

# ... remainder of the workflow file ...

策略开发人员可以使用 Admission Controller 策略模板。他们有 GitHub 操作来构建、测试、签名和发布策略。

列出策略签名

您可以通过 kwctl inspect 检查已发布策略中的签名。这显示了关于策略及其签名的信息,如下所示:

kwctl inspect registry://ghcr.io/kubewarden/policies/us…​。
$ kwctl inspect registry://ghcr.io/kubewarden/policies/user-group-psp:v0.2.0
Details
title:              psp-user-group
description:        Short description
author:             José Guilherme Vanz <jguilhermevanz@suse.com>
url:                https://github.com/kubewarden/user-group-psp-policy
source:             https://github.com/kubewarden/user-group-psp-policy
license:            Apache-2.0
mutating:           true
context aware:      false
execution mode:     kubewarden-wapc
protocol version:   1

Annotations
io.kubewarden.kwctl 0.2.5-rc2

Rules
────────────────────
---
- apiGroups:
    - ""
  apiVersions:
    - v1
  resources:
    - pods
  operations:
    - CREATE
────────────────────

Usage
This policy enforce the user and group used in the container.

Sigstore signatures

Digest:                            sha256:026af67682a85d424e7d95db460171635f5c3957d67b53499bece912cc0413cc
Media type:                        application/vnd.dev.cosign.simplesigning.v1+json
Size:                              258
Annotations
dev.sigstore.cosign/certificate    -----BEGIN CERTIFICATE-----
                                   MIIDRzCCAsygAwIBAgITbPUZlUFkkAHtbzc3rzC/3zXj1DAKBggqhkjOPQQDAzAq
                                   MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIy
                                   MDIyNTE2MzAwMloXDTIyMDIyNTE2NDAwMVowEzERMA8GA1UEChMIc2lnc3RvcmUw
                                   WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR/O5c6ZI5BzBweoEIam4uWu5fqzHx0
                                   3PTCgfXyyvIjorz9wX08bsndkHdWfFObU+PztbxX78An43Yw9/fHtO93o4IB5jCC
                                   AeIwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMAwGA1UdEwEB
                                   /wQCMAAwHQYDVR0OBBYEFCP/v7NEJQglbDmyC5VMgnvhiuBUMB8GA1UdIwQYMBaA
                                   FFjAHl+RRaVmqXrMkKGTItAqxcX6MHgGA1UdEQRxMG+GbWh0dHBzOi8vZ2l0aHVi
                                   LmNvbS9rdWJld2FyZGVuL2dpdGh1Yi1hY3Rpb25zLy5naXRodWIvd29ya2Zsb3dz
                                   L3JldXNhYmxlLXJlbGVhc2UtcG9saWN5LXJ1c3QueW1sQHJlZnMvaGVhZHMvdjEw
                                   NgYKKwYBBAGDvzABAwQoMmJiMGQ4NjZjMzFmOGMyZTQ3NDMxMDI4M2ExNmFkMWFi
                                   NjBlZjA1YjAuBgorBgEEAYO/MAEFBCBrdWJld2FyZGVuL3VzZXItZ3JvdXAtcHNw
                                   LXBvbGljeTAcBgorBgEEAYO/MAEEBA5SZWxlYXNlIHBvbGljeTASBgorBgEEAYO/
                                   MAECBARwdXNoMDkGCisGAQQBg78wAQEEK2h0dHBzOi8vdG9rZW4uYWN0aW9ucy5n
                                   aXRodWJ1c2VyY29udGVudC5jb20wHgYKKwYBBAGDvzABBgQQcmVmcy90YWdzL3Yw
                                   LjIuMDAKBggqhkjOPQQDAwNpADBmAjEAyGQbNCkOifStO7yCCfF8yXyc144ANn2x
                                   Ty92WYC0pTaVhviOED47fgD6TncKf+92AjEAjBfjLmCG/Mwrh8t+gfHJEAWWEc9Q
                                   +j9NR4wF66uABS/TTh5CYlrnIuqSD+GBHGwV
                                   -----END CERTIFICATE-----
dev.sigstore.cosign/timestamp      {"signatures":[{"keyid":"b6710623a30c010738e64c5209d367df1c0a18cf90e6ab5292fb01680f83453d","sig":"3046022100f666a7f4b3d85d8003f2c166e27827dfa0c4ab9282e9dab19485f4e702c61700022100dfe826e0edab5f80a40f08cc87b87777a4db30775d85684fe4950e797f2f565c"}],"signed":{"_type":"timestamp","spec_version":"1.0","version":15,"expires":"2022-03-08T19:14:05Z","meta":{"snapshot.json":{"length":1655,"hashes":{"sha256":"36cf063d0717f6dc03e23027721adcd69b684d293956d3a1a7db7b0848f711d7","sha512":"f90946d0a2dc58dae4505cfb91517a40299adf9e8719f52af187e2025aad69fcdeaeded271ec25db24869841c16fbe24f3fc56f56af8fdbb8808dccec4636b64"},"version":15}}}}
dev.sigstore.cosign/bundle         {"SignedEntryTimestamp":"MEUCIEfu4qR+HsexSDk5h2QXMduvoRCX10J+4CLQWtYw5VD6AiEAyYCEjvJdv2Sr5tZ4LApnddH/4v+CoV1QkuvbCQ3iIUM=","Payload":{"body":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJkYXRhIjp7Imhhc2giOnsiYWxnb3JpdGhtIjoic2hhMjU2IiwidmFsdWUiOiIwMjZhZjY3NjgyYTg1ZDQyNGU3ZDk1ZGI0NjAxNzE2MzVmNWMzOTU3ZDY3YjUzNDk5YmVjZTkxMmNjMDQxM2NjIn19LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FWUNJUUNXNWZRZ1BUUTdaTlNuRkhzbHJOTlFrS2dTSVFpOGNSMTU5UEExc0s4VGlRSWhBSndMOWJPcUJKbVduN1lLZG9Tem80c2xPZ2s4SkJCanFYZHNydDNyeVF0QiIsInB1YmxpY0tleSI6eyJjb250ZW50IjoiTFMwdExTMUNSVWRKVGlCRFJWSlVTVVpKUTBGVVJTMHRMUzB0Q2sxSlNVUlNla05EUVhONVowRjNTVUpCWjBsVVlsQlZXbXhWUm10clFVaDBZbnBqTTNKNlF5OHplbGhxTVVSQlMwSm5aM0ZvYTJwUFVGRlJSRUY2UVhFS1RWSlZkMFYzV1VSV1VWRkxSWGQ0ZW1GWFpIcGtSemw1V2xNMWExcFlXWGhGVkVGUVFtZE9Wa0pCVFZSRFNFNXdXak5PTUdJelNteE5RalJZUkZSSmVRcE5SRWw1VGxSRk1rMTZRWGROYkc5WVJGUkplVTFFU1hsT1ZFVXlUa1JCZDAxV2IzZEZla1ZTVFVFNFIwRXhWVVZEYUUxSll6SnNibU16VW5aamJWVjNDbGRVUVZSQ1oyTnhhR3RxVDFCUlNVSkNaMmR4YUd0cVQxQlJUVUpDZDA1RFFVRlNMMDgxWXpaYVNUVkNla0ozWlc5RlNXRnROSFZYZFRWbWNYcEllREFLTTFCVVEyZG1XSGw1ZGtscWIzSjZPWGRZTURoaWMyNWthMGhrVjJaR1QySlZLMUI2ZEdKNFdEYzRRVzQwTTFsM09TOW1TSFJQT1ROdk5FbENOV3BEUXdwQlpVbDNSR2RaUkZaU01GQkJVVWd2UWtGUlJFRm5aVUZOUWsxSFFURlZaRXBSVVUxTlFXOUhRME56UjBGUlZVWkNkMDFFVFVGM1IwRXhWV1JGZDBWQ0NpOTNVVU5OUVVGM1NGRlpSRlpTTUU5Q1FsbEZSa05RTDNZM1RrVktVV2RzWWtSdGVVTTFWazFuYm5ab2FYVkNWVTFDT0VkQk1WVmtTWGRSV1UxQ1lVRUtSa1pxUVVoc0sxSlNZVlp0Y1ZoeVRXdExSMVJKZEVGeGVHTllOazFJWjBkQk1WVmtSVkZTZUUxSEswZGlWMmd3WkVoQ2VrOXBPSFphTW13d1lVaFdhUXBNYlU1MllsTTVjbVJYU214a01rWjVXa2RXZFV3eVpIQmtSMmd4V1dreGFGa3pVbkJpTWpWNlRIazFibUZZVW05a1YwbDJaREk1ZVdFeVduTmlNMlI2Q2t3elNteGtXRTVvV1cxNGJFeFlTbXhpUjFab1l6SlZkR05IT1hOaFYwNDFURmhLTVdNelVYVmxWekZ6VVVoS2JGcHVUWFpoUjFab1draE5kbVJxUlhjS1RtZFpTMHQzV1VKQ1FVZEVkbnBCUWtGM1VXOU5iVXBwVFVkUk5FNXFXbXBOZWtadFQwZE5lVnBVVVROT1JFMTRUVVJKTkUweVJYaE9iVVpyVFZkR2FRcE9ha0pzV21wQk1WbHFRWFZDWjI5eVFtZEZSVUZaVHk5TlFVVkdRa05DY21SWFNteGtNa1o1V2tkV2RVd3pWbnBhV0VsMFdqTktkbVJZUVhSalNFNTNDa3hZUW5aaVIyeHFaVlJCWTBKbmIzSkNaMFZGUVZsUEwwMUJSVVZDUVRWVFdsZDRiRmxZVG14SlNFSjJZa2RzYW1WVVFWTkNaMjl5UW1kRlJVRlpUeThLVFVGRlEwSkJVbmRrV0U1dlRVUnJSME5wYzBkQlVWRkNaemM0ZDBGUlJVVkxNbWd3WkVoQ2VrOXBPSFprUnpseVdsYzBkVmxYVGpCaFZ6bDFZM2sxYmdwaFdGSnZaRmRLTVdNeVZubFpNamwxWkVkV2RXUkROV3BpTWpCM1NHZFpTMHQzV1VKQ1FVZEVkbnBCUWtKblVWRmpiVlp0WTNrNU1GbFhaSHBNTTFsM0NreHFTWFZOUkVGTFFtZG5jV2hyYWs5UVVWRkVRWGRPY0VGRVFtMUJha1ZCZVVkUllrNURhMDlwWmxOMFR6ZDVRME5tUmpoNVdIbGpNVFEwUVU1dU1uZ0tWSGs1TWxkWlF6QndWR0ZXYUhacFQwVkVORGRtWjBRMlZHNWpTMllyT1RKQmFrVkJha0ptYWt4dFEwY3ZUWGR5YURoMEsyZG1TRXBGUVZkWFJXTTVVUW9yYWpsT1VqUjNSalkyZFVGQ1V5OVVWR2cxUTFsc2NtNUpkWEZUUkN0SFFraEhkMVlLTFMwdExTMUZUa1FnUTBWU1ZFbEdTVU5CVkVVdExTMHRMUW89In19fX0=","integratedTime":1645806604,"logIndex":1506651,"logID":"c0d23d6ad406973f9559f3ba2d1ca01f84147d8ffc5b8445c224f98b9591801d"}}
dev.sigstore.cosign/chain          -----BEGIN CERTIFICATE-----
                                   MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMw
                                   KjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y
                                   MTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3Jl
                                   LmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7
                                   XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxex
                                   X69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92j
                                   YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRY
                                   wB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQ
                                   KsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCM
                                   WP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9
                                   TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ
                                   -----END CERTIFICATE-----
dev.cosignproject.cosign/signature MEYCIQCW5fQgPTQ7ZNSnFHslrNNQkKgSIQi8cR159PA1sK8TiQIhAJwL9bOqBJmWn7YKdoSzo4slOgk8JBBjqXdsrt3ryQtB

验证策略

您可以通过 cosign 或 kwctl 检查策略是否正确签名。他们有类似的命令行选项来检查策略签名。要使用密钥检查签名二进制文件,请使用 kwctl,如下所示:

$ kwctl verify -k cosign.pub ghcr.io/kubewarden/policies/user-group-psp:latest
2022-03-29T14:49:31.878180Z  INFO kwctl::verify: Policy successfully verified

或 cosign:

$ cosign verify --key cosign.pub ghcr.io/kubewarden/policies/user-group-psp:latest

Verification for ghcr.io/kubewarden/policies/user-group-psp:latest --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - The signatures were verified against the specified public key
  - Any certificates were verified against the Fulcio roots.

[{"critical":{"identity":{"docker-reference":"ghcr.io/kubewarden/policies/user-group-psp"},"image":{"docker-manifest-digest":"sha256:af520a8ccee03811d426c48634b7007f1220c121cc23e14962bb64510585ce97"},"type":"cosign container image signature"},"optional":null}]

配置策略服务器以检查策略签名

您可以使用 Admission Controller 和 ConfigMap 配置仅运行受信任的策略。ConfigMap 结构在 签名配置参考 中描述。它用于使用 kwctl 验证策略。ConfigMap 应该在 verification-config 字段下定义允许的配置。

例如,您想运行由 Admission Controller GitHub 组织签名的策略。那么这个场景的示例 ConfigMap 将是:

$ cat kubewarden_signatures.yaml
$ cat kubewarden_signatures.yaml
apiVersion: v1
allOf:
  - kind: githubAction
    owner: kubewarden

# note that the data is stored under verification-config field
$ kubectl  create configmap my-signatures-configuration --from-file=verification-config=kubewarden_signatures.yaml

$ kubectl get configmap -o yaml my-signatures-configuration
apiVersion: v1
data:
  verification-config: |
    apiVersion: v1
    allOf:
      - kind: githubAction
        owner: kubewarden
kind: ConfigMap
metadata:
  creationTimestamp: "2022-03-29T18:27:20Z"
  name: my-signatures-configuration
  namespace: default
  resourceVersion: "10279"
  uid: d53e1c56-1fee-45de-92f5-9bd73b8cead4

您可以使用 kwctl scaffold verification-config 为 ConfigMap 生成默认的验证配置文件:

$ kwctl scaffold verification-config > verification_config.yaml
$ cat verification_config.yaml
$ kwctl scaffold verification-config > verification_config.yaml
$ cat verification_config.yaml
# Default Admission Controller verification config
#
# With this config, the only valid policies are those signed by Admission Controller
# infrastructure.
#
# This config can be saved to its default location (for this OS) with:
#   kwctl scaffold verification-config > /home/kubewarden/.config/kubewarden/verification-config.yml
#
# Providing a config in the default location enables Sigstore verification.
# See https://docs.kubewarden.io for more Sigstore verification options.
---
apiVersion: v1
allOf:
  - kind: githubAction
    owner: kubewarden
    repo: ~
    annotations: ~
anyOf: ~

您可以使用这个 verification_config.yml 创建 ConfigMap。

$ kubectl create configmap my-signatures-configuration --from-file==verification_config.yaml
configmap/my-signatures-configuration created

然后我们可以使用 get configmap 进行检查。

kubectl get configmap
$ kubectl get configmap -o yaml my-signatures-configuration
apiVersion: v1
data:
  verification-config: |+
    # Default Admission Controller verification config
    #
    # With this config, the only valid policies are those signed by Admission Controller
    # infrastructure.
    #
    # This config can be saved to its default location (for this OS) with:
    #   kwctl scaffold verification-config > /home/kubewarden/.config/kubewarden/verification-config.yml
    #
    # Providing a config in the default location enables Sigstore verification.
    # See https://docs.kubewarden.io for more Sigstore verification options.
    ---
    apiVersion: v1
    allOf:
      - kind: githubAction
        owner: kubewarden
        repo: ~
        annotations: ~
    anyOf: ~

kind: ConfigMap
metadata:
  creationTimestamp: "2022-04-07T11:54:27Z"
  name: my-signatures-configuration
  namespace: default
  resourceVersion: "1317"
  uid: 74dec846-7fcd-4b4b-8184-700c816f685a

在创建 ConfigMap 以存储签名要求后,您可以配置策略服务器。通过在字段 verificationConfig 中设置 ConfigMap 名称(标记为 ➀)来开始验证策略签名。

apiVersion: policies.kubewarden.io/v1alpha2
kind: PolicyServer
metadata:
  name: default
  finalizers:
    - kubewarden
spec:
  image: ghcr.io/kubewarden/policy-server:v0.2.7
  serviceAccountName: policy-server
  replicas: 1
//highlight-next-l
  # name of the confimap with the signatures requirements
  verificationConfig: your_configmap (1)
  env:
    - name: KUBEWARDEN_ENABLE_METRICS
      value: "1"
    - name: KUBEWARDEN_LOG_FMT
      value: otlp
    - name: "KUBEWARDEN_LOG_LEVEL"
      value: "info"
1 verificationConfig

如果您使用 kubewarden-defaults Helm 图表部署默认策略服务器,则可以通过在 policyServer.verificationConfig 值中设置 ConfigMap 名称来配置此字段。

现在,策略服务器通过拒绝启动来拒绝不受信任的 AdmissionPolicies 和 ClusterAdmissionPolicies。您需要删除不受信任的策略,或更改正在运行的策略服务器的签名要求。

签名配置参考

您可以验证文件中包含的签名要求。示例如下:

签名要求文件
apiVersion: v1

allOf: (1)
  - kind: githubAction
    owner: kubewarden   # mandatory
    annotations:
      env: prod

anyOf: # at least `+anyOf.minimumMatches+` are required to match (2)
  minimumMatches: 2 # default is 1
  signatures:
  - kind: pubKey
    owner: flavio # optional
    key: .... # mandatory
    annotations:  # optional
      env: prod
      foo: bar
  - kind: pubKey
    owner: victor # optional
    key: .... # mandatory
  - kind: genericIssuer
    issuer: https://github.com/login/oauth
    subject:
      equal: alice@example.com
  - kind: genericIssuer
    issuer: https://token.actions.githubusercontent.com
    subject:
      equal: https://github.com/flavio/policy-secure-pod-images/.github/workflows/release.yml@refs/heads/main
  - kind: genericIssuer
    issuer: https://token.actions.githubusercontent.com
    subject:
      urlPrefix: https://github.com/flavio/
  - kind: genericIssuer
    issuer: https://token.actions.githubusercontent.com
    subject:
      urlPrefix: https://github.com/kubewarden # <- it will be post-fixed with `+/+` for security reasons
  - kind: githubAction
    owner: flavio   # mandatory
    repo: policy1 # optional
  - kind: pubKey
    owner: alice # optional
    key: .... # mandatory
1 allOf
2 anyOf

签名验证

上述配置包含两个高亮部分,allOf 和 anyOf:

  • allOf:仅当此处的所有签名要求有效时,策略才被信任。

  • anyOf:如果满足 minimumMatches 标准,则策略被信任。

上面,minimumMatches 字段为 2。因此,必须满足至少两个签名要求。minimumMatches 字段的默认值为 1。

必须满足来自 allOf 的所有签名要求以及来自 anyOf 的最小数量。

公钥验证

要检查策略是否使用正确的公钥签名,您需要指定密钥数据和密钥的所有者。在此示例中,您将`kind`设置为`pubKey`,并且`key`具有公钥。所有者字段是可选的,但可以帮助澄清谁拥有该密钥。

  - kind: pubKey
    owner: bob # optional
    key: |
      -----BEGIN PUBLIC KEY-----
      MBFKHFDGHKIJH0CAQYIKoZIzj0DAQcDQgAEX0HFTtCfTtPmkx5p1RbDE6HJSGAVD
      BVDF6SKFSF87AASUspkQsN3FO4iyWodCy5j3o0CdIJD/KJHDJFHDFIu6sA==
      -----END PUBLIC KEY-----

无密钥签名验证

以无密钥模式签署的策略没有公钥可供验证。您仍然可以使用在签署过程中使用的OIDC数据验证该策略。为此,有必要将签名验证定义为`genericIssuer`。

可以验证签名中的信息:

  • issuer(必选):这与Fulcio生成的证书中的`Issuer`属性匹配。这显示了用于签署策略的OIDC。

  • subject:用于匹配Fulcio证书中`Subject`属性的字段。Subject(Fulcio)字段包含用于对OIDC提供者进行身份验证的用户。验证字段`subject`可以有两个子字段之一:

    • equal:证书中的`Subject`(Fulcio)必须等于签名验证中的值;

    • urlPrefix:证书的`Subject`(Fulcio)字段值必须以签名验证中定义的值为前缀。

`cosign verify`和`kwctl inspect`都可以显示有关无密钥签名的信息。

例如,此配置意味着策略必须具有来自Alice的无密钥签名,使用GitHub OIDC:

- kind: genericIssuer
  issuer: https://github.com/login/oauth
  subject:
    equal: alice@example.com

此配置需要在 GitHub Actions 中签署策略,且该策略来自由 GitHub 用户 flavio 拥有的储存库:

- kind: genericIssuer
  issuer: https://token.actions.githubusercontent.com
  subject:
    urlPrefix: https://github.com/flavio

GitHub Actions 签名验证

“kind”,githubAction 用于验证在 GitHub Actions 中签署的策略。 您也可以使用 genericIssuer kind 来完成此操作。为了简化签名要求流程,请使用两个额外字段用于 githubAction:

  • owner(必选):要信任的用户或组织的 GitHub ID

  • repo:要信任的储存库名称

例如,最后的代码片段,使用 genericIssuer,可以重写为:

- kind: githubAction
  owner: flavio

签名注释验证

所有签名类型都可以有其他可选的验证字段,annotations。 这些字段是在签署过程中添加的键/值数据。

使用 Admission Controller,您可以验证策略签名是否由受信任的用户签署,以及是否包含特定的注释。

下一个验证检查策略的两个条件:

  • 它是用特定密钥签署的

  • 它具有生产环境注释

- kind: pubKey
  key: |
    -----BEGIN PUBLIC KEY-----
    MBFKHFDGHKIJH0CAQYIKoZIzj0DAQcDQgAEX0HFTtCfTtPmkx5p1RbDE6HJSGAVD
    BVDF6SKFSF87AASUspkQsN3FO4iyWodCy5j3o0CdIJD/KJHDJFHDFIu6sA==
    -----END PUBLIC KEY-----
  annotations:
    environment: production

使用签名验证配置文件检查策略 OCI 工件

您可以使用验证配置文件测试策略是否通过验证。 使用 --verification-config-path 标志的 kwctl verify 命令

$ cat signatures_requirements.yaml
apiVersion: v1
allOf:
  - kind: pubKey
    key: |
      -----BEGIN PUBLIC KEY-----
      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5Q+cN1Jj2S7N05J4AXnqwP2DyzSg
      Mc+raYce2Wthrd30MSgFtoh5ADAkCd/nML2Nx8UD9KBuASRb0gG5jXqgMQ==
      -----END PUBLIC KEY-----

$ kwctl verify --verification-config-path signatures_requirements.yaml ghcr.io/kubewarden/policies/user-group-psp:latest
2022-03-29T17:34:37.847169Z  INFO kwctl::verify: Policy successfully verified

最后一个示例测试给定策略是否来自 Admission Controller 组织:

$ cat kubewarden_signatures.yaml
apiVersion: v1
allOf:
  - kind: githubAction
    owner: kubewarden

$ kwctl verify --verification-config-path kubewarden_signatures.yaml ghcr.io/kubewarden/policies/user-group-psp:latest
2022-03-29T18:07:39.062292Z  INFO kwctl::verify: Policy successfully verified