4.16. OpenShift Pipelines サプライチェーンセキュリティーでの Tekton Chains の使用

重要

Tekton Chains はテクノロジープレビュー機能のみです。テクノロジープレビュー機能は、Red Hat 製品のサービスレベルアグリーメント (SLA) の対象外であり、機能的に完全ではないことがあります。Red Hat は、実稼働環境でこれらを使用することを推奨していません。テクノロジープレビュー機能は、最新の製品機能をいち早く提供して、開発段階で機能のテストを行いフィードバックを提供していただくことを目的としています。

Red Hat のテクノロジープレビュー機能のサポート範囲に関する詳細は、テクノロジープレビュー機能のサポート範囲 を参照してください。

Tekton Chains は、Kubernetes カスタムリソース定義 (CRD) コントローラーです。これを使用して、Red Hat OpenShift Pipelines を使用して作成されたタスクおよびパイプラインのサプライチェーンセキュリティーを管理できます。

デフォルトでは、Tekton Chains は OpenShift Container Platform クラスター内のすべてのタスク実行を監視します。タスクの実行が完了すると、Tekton Chains はタスク実行のスナップショットを取得します。次に、スナップショットを 1 つ以上の標準ペイロード形式に変換し、最後にすべてのアーティファクトに署名して保存します。

タスクの実行に関する情報を取得するために、Tekton Chains は Result オブジェクトと PipelineResource オブジェクトを使用します。オブジェクトが使用できない場合、Tekton は OCI イメージの URL と修飾されたダイジェストをチェーンします。

注記

PipelineResource オブジェクトは非推奨であり、将来のリリースで削除される予定です。手動で使用する場合は、Results オブジェクトを推奨します。

4.16.1. 主な特長

  • 暗号化キータイプと cosign などのサービスを使用して、タスク実行、タスク実行結果、および OCI レジストリーイメージに署名できます。
  • in-toto などの認証形式を使用できます。
  • OCI リポジトリーをストレージバックエンドとして使用して、署名と署名されたアーティファクトを安全に保存できます。

4.16.2. Red Hat OpenShift Pipelines Operator を使用した Tekton Chains のインストール

クラスター管理者は、TektonChain カスタムリソース (CR) を使用して、Tekton Chains をインストールおよび管理できます。

注記

Tekton Chains は、Red Hat パイプラインのオプションのコンポーネントです。現在、TektonConfig を使用してインストールすることはできません。

前提条件

  • Red Hat OpenShift Pipelines Operator がクラスターの openshift-pipelines namespace にインストールされていることを確認します。

手順

  1. OpenShift Container Platform クラスター用の TektonChain を作成します。

    apiVersion: operator.tekton.dev/v1alpha1
    kind: TektonChain
    metadata:
      name: chain
    spec:
      targetNamespace: openshift-pipelines
  2. TektonChain CR を適用します。

    $ oc apply -f TektonChain.yaml 1
    1
    TektonChain CR のファイル名に置き換えます。
  3. インストールのステータスを確認します。

    $ oc get tektonchains.operator.tekton.dev

4.16.3. Tekton Chains の設定

Tekton Chains は、設定に openshift-pipelines namespace で chains-config という名前の ConfigMap オブジェクトを使用します。

Tekton Chains を設定するには、次の例を使用します。

例: Tekton Chains の設定

$ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.oci.storage": "", "artifacts.taskrun.format":"tekton", "artifacts.taskrun.storage": "tekton"}}' 1

1
JSON ペイロードでサポートされているキーと値のペアの組み合わせを使用します。

4.16.3.1. Tekton Chains 設定でサポートされているキー

クラスター管理者は、サポートされているさまざまなキーと値を使用して、タスクの実行、OCI イメージ、およびストレージに関する仕様を設定できます。

4.16.3.1.1. タスク実行でサポートされるキー

表4.13 Chains 設定: タスク実行でサポートされるキー

サポートされているキー説明サポート対象の値デフォルト値

artifacts.taskrun.format

タスク実行ペイロードを格納するためのフォーマット。

tektonin-toto

tekton

artifacts.taskrun.storage

タスク実行署名のストレージバックエンド。“tekton,oci" のように、複数のバックエンドをコンマ区切りのリストとして指定できます。このアーティファクトを無効にするには、空の文字列 “" を指定します。

tektonoci

tekton

artifacts.taskrun.signer

タスク実行ペイロードに署名するための署名バックエンド。

x509

x509

4.16.3.1.2. OCI でサポートされているキー

表4.14 Chains 設定: OCI でサポートされているキー

サポートされているキー説明サポート対象の値デフォルト値

artifacts.oci.format

OCI ペイロードを格納するためのフォーマット。

simplesigning

simplesigning

artifacts.oci.storage

OCI 署名用のストレージバックエンド。“oci,tekton" のように、複数のバックエンドをコンマ区切りのリストとして指定できます。OCI アーティファクトを無効にするには、空の文字列 “" を指定します。

tektonoci

oci

artifacts.oci.signer

OCI ペイロードに署名するための署名バックエンド。

x509cosign

x509

4.16.3.1.3. ストレージ用にサポートされているキー

表4.15 Chains 設定: ストレージでサポートされているキー

サポートされているキー説明サポート対象の値デフォルト値

artifacts.oci.repository

OCI 署名を格納するための OCI リポジトリー。

現在、Chains は内部 OpenShift OCI レジストリーのみをサポートしています。Quay などの他の一般的なオプションはサポートされていません。

 

4.16.4. Tekton Chains のシークレットに署名する

クラスター管理者は、キーペアを生成し、Tekton Chains を使用して、Kubernetes シークレットを使用してアーティファクトに署名できます。Tekton Chains が機能するには、暗号化されたキーの秘密鍵とパスワードが、openshift-pipelines namespace の signing-secrets Kubernetes シークレットの一部として存在している必要があります。

現在、Tekton Chains は x509 および cosign 署名スキームをサポートしています。

注記

サポートされている署名スキームの 1 つのみを使用してください。

4.16.4.1. x509 を使用した署名

Tekton Chains で x509 署名スキームを使用するには、ed25519 または ecdsa タイプの x509.pem 秘密鍵を signing-secrets Kubernetes シークレットに保存します。キーが暗号化されていない PKCS8 PEM ファイル (BEGIN PRIVATE KEY) として保存されていることを確認します。

4.16.4.2. cosign を使用した署名

Tekton Chains で cosign 署名スキームを使用するには:

  1. cosign をインストールします。
  2. cosign.key キーと cosign.pub キーのペアを生成します。

    $ cosign generate-key-pair k8s://openshift-pipelines/signing-secrets

    Cosign はパスワードの入力を求め、Kubernetes シークレットを作成します。

  3. 暗号化された cosign.key 秘密鍵と cosign.password 復号化パスワードを signing-secrets Kubernetes シークレットに保存します。秘密鍵が ENCRYPTED COSIGN PRIVATE KEY タイプの暗号化された PEM ファイルとして保存されていることを確認します。

4.16.4.3. 署名のトラブルシューティング

署名シークレットがすでに入力されている場合は、次のエラーが発生する可能性があります。

Error from server (AlreadyExists): secrets "signing-secrets" already exists

エラーを解決するには:

  1. シークレットを削除します。

    $ oc delete secret signing-secrets -n openshift-pipelines
  2. キーペアを再作成し、好みの署名スキームを使用してシークレットに保存します。

4.16.5. OCI レジストリーへの認証

署名を OCI レジストリーにプッシュする前に、クラスター管理者は、レジストリーで認証するように Tekton Chains を設定する必要があります。Tekton Chains コントローラーは、タスクの実行と同じサービスアカウントを使用します。署名を OCI レジストリーにプッシュするために必要な認証情報を使用してサービスアカウントを設定するには、次の手順を実行します。

手順

  1. Kubernetes サービスアカウントの namespace と名前を設定します。

    $ export NAMESPACE=<namespace> 1
    $ export SERVICE_ACCOUNT_NAME=<service_account> 2
    1
    サービスアカウントに関連付けられた namespace。
    2
    サービスアカウントの名前
  2. Kubernetes シークレットを作成します。

    $ oc create secret registry-credentials \
      --from-file=.dockerconfigjson \ 1
      --type=kubernetes.io/dockerconfigjson \
      -n $NAMESPACE
    1
    Docker 設定ファイルへのパスに置き換えます。デフォルトのパスは ~/.docker/config.json です。
  3. サービスアカウントにシークレットへのアクセス権限を付与します。

    $ oc patch serviceaccount $SERVICE_ACCOUNT_NAME \
      -p "{\"imagePullSecrets\": [{\"name\": \"registry-credentials\"}]}" -n $NAMESPACE

    Red Hat OpenShift Pipelines がすべてのタスク実行に割り当てるデフォルトの pipeline サービスアカウントにパッチを適用すると、Red Hat OpenShift Pipelines Operator はサービスアカウントをオーバーライドします。ベストプラクティスとして、次の手順を実行できます。

    1. ユーザーのタスク実行に割り当てる別のサービスアカウントを作成します。

      $ oc create serviceaccount <service_account_name>
    2. タスク実行テンプレートの serviceaccountname フィールドの値を設定して、サービスアカウントをタスク実行に関連付けます。

      apiVersion: tekton.dev/v1beta1
      kind: TaskRun
      metadata:
      name: build-push-task-run-2
      spec:
      serviceAccountName: build-bot 1
      taskRef:
        name: build-push
      ...
      1
      新しく作成したサービスアカウントの名前に置き換えます。

4.16.5.1. 追加認証なしでタスク実行の署名を作成および検証する

追加認証を使用して Tekton Chains でタスク実行の署名を検証するには、次のタスクを実行します。

  • 暗号化された x509 キーペアを作成し、Kubernetes シークレットとして保存します。
  • Tekton Chains バックエンドストレージを設定します。
  • タスク実行を作成して署名し、署名とペイロードをタスク実行自体にアノテーションとして保存します。
  • 署名されたタスクの実行から署名とペイロードを取得します。
  • タスク実行の署名を確認します。

前提条件

以下がクラスターにインストールされていることを確認します。

  • Red Hat OpenShift Pipelines Operator
  • Tekton Chains
  • Cosign

手順

  1. 暗号化された x509 鍵ペアを作成し、Kubernetes シークレットとして保存します。

    $ cosign generate-key-pair k8s://openshift-pipelines/signing-secrets

    プロンプトが表示されたらパスワードを入力します。Cosign は、結果の秘密鍵を signing-secrets Kubernetes シークレットの一部として openshift-pipelines namespace に保存します。

  2. Tekton Chains 設定で、OCI ストレージを無効にし、タスク実行ストレージとフォーマットを tekton に設定します。

    $ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.oci.storage": "", "artifacts.taskrun.format":"tekton", "artifacts.taskrun.storage": "tekton"}}'
  3. Tekton Chains コントローラーを再起動して、変更された設定が適用されていることを確認します。

    $ oc delete po -n openshift-pipelines -l app=tekton-chains-controller
  4. タスク実行を作成します。

    $ oc create -f https://raw.githubusercontent.com/tektoncd/chains/main/examples/taskruns/task-output-image.yaml 1
    taskrun.tekton.dev/build-push-run-output-image-qbjvh created
    1
    タスクの実行を指す URI またはファイルパスに置き換えます。
  5. ステップのステータスを確認し、プロセスが終了するまで待ちます。

    $ tkn tr describe --last
    [...truncated output...]
    NAME                            STATUS
    ∙ create-dir-builtimage-9467f   Completed
    ∙ git-source-sourcerepo-p2sk8   Completed
    ∙ build-and-push                Completed
    ∙ echo                          Completed
    ∙ image-digest-exporter-xlkn7   Completed
  6. base64 でエンコードされたアノテーションとして保存されているオブジェクトから署名とペイロードを取得します。

    $ export TASKRUN_UID=$(tkn tr describe --last -o  jsonpath='{.metadata.uid}')
    $ tkn tr describe --last -o jsonpath="{.metadata.annotations.chains\.tekton\.dev/signature-taskrun-$TASKRUN_UID}" > signature
    $ tkn tr describe --last -o jsonpath="{.metadata.annotations.chains\.tekton\.dev/payload-taskrun-$TASKRUN_UID}" | base64 -d > payload
  7. 署名を確認します。

    $ cosign verify-blob --key k8s://openshift-pipelines/signing-secrets --signature ./signature ./payload
    Verified OK

4.16.6. Tekton Chains を使用してイメージと証明書を署名検証する

クラスター管理者は、Tekton Chains を使用して、以下のタスクを実行することで、イメージと証明書を署名および検証できます。

  • 暗号化された x509 鍵ペアを作成し、Kubernetes シークレットとして保存します。
  • OCI レジストリーの認証を設定して、イメージ、イメージ署名、および署名されたイメージ証明書を保存します。
  • Tekton Chains を設定して、証明書を生成し署名します。
  • タスク実行で Kaniko を使用してイメージを作成します。
  • 署名されたイメージと署名された証明書を検証する。

前提条件

以下がクラスターにインストールされていることを確認します。

  • Red Hat OpenShift Pipelines Operator
  • Tekton Chains
  • Cosign
  • Rekor
  • jq

手順

  1. 暗号化された x509 鍵ペアを作成し、Kubernetes シークレットとして保存します。

    $ cosign generate-key-pair k8s://openshift-pipelines/signing-secrets

    プロンプトが表示されたらパスワードを入力します。Cosign は、結果の秘密鍵を signing-secrets Kubernetes シークレットの一部として openshift-pipelinesnamespace に保存し、公開鍵を cosign.pub ローカルファイルに書き込みます。

  2. イメージレジストリーの認証を設定します。

    1. 署名を OCI レジストリーにプッシュするように Tekton Chains コントローラーを設定するには、タスク実行のサービスアカウントに関連付けられた認証情報を使用します。詳細については、OCI レジストリーへの認証を参照してください。
    2. イメージをビルドしてレジストリーにプッシュする Kaniko タスクの認証を設定するには、必要な認証情報を含む docker config.json ファイルの Kubernetes シークレットを作成します。

      $ oc create secret generic <docker_config_secret_name> \ 1
        --from-file <path_to_config.json> 2
      1
      docker 設定シークレットの名前に置き換えます。
      2
      docker config.json ファイルへのパスに置き換えます。
  3. Tekton Chains を設定するには、chains-config オブジェクトで artifacts.taskrun.formatartifacts.taskrun.storagetransparency.enabled パラメーターを設定します。

    $ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.taskrun.format": "in-toto"}}'
    
    $ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.taskrun.storage": "oci"}}'
    
    $ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"transparency.enabled": "true"}}'
  4. Kaniko タスクを開始します。

    1. Kaniko タスクをクラスターに適用します。

      $ oc apply -f examples/kaniko/kaniko.yaml 1
      1
      Kaniko タスクへの URI またはファイルパスに置き換えます。
    2. 適切な環境変数を設定します。

      $ export REGISTRY=<url_of_registry> 1
      
      $ export DOCKERCONFIG_SECRET_NAME=<name_of_the_secret_in_docker_config_json> 2
      1
      イメージをプッシュするレジストリーの URL に置き換えます。
      2
      docker config.json ファイルのシークレットの名前に置き換えます。
    3. Kaniko タスクを開始します。

      $ tkn task start --param IMAGE=$REGISTRY/kaniko-chains --use-param-defaults --workspace name=source,emptyDir="" --workspace name=dockerconfig,secret=$DOCKERCONFIG_SECRET_NAME kaniko-chains

      すべての手順が完了するまで、このタスクのログを確認してください。認証が成功すると、最終的なイメージが $REGISTRY/kaniko-chains にプッシュされます。

  5. Tekton Chains が証明書を生成して署名するまで 1 分ほど待ち、タスク実行時に chains.tekton.dev/signed=true アノテーションが利用可能か確認します。

    $ oc get tr <task_run_name> \ 1
    -o json | jq -r .metadata.annotations
    
    {
      "chains.tekton.dev/signed": "true",
      ...
    }
    1
    タスク実行の名前に置き換えます。
  6. イメージとアテステーションを確認します。

    $ cosign verify --key cosign.pub $REGISTRY/kaniko-chains
    
    $ cosign verify-attestation --key cosign.pub $REGISTRY/kaniko-chains
  7. Rekor でイメージの証明書を見つけます。

    1. $ REGISTRY/kaniko-chains イメージのダイジェストを取得します。タスクの実行中に検索するか、イメージをプルしてダイジェストをデプロイメントできます。
    2. Rekor を検索して、イメージの sha256 ダイジェストに一致するすべてのエントリーを見つけます。

      $ rekor-cli search --sha <image_digest> 1
      
      <uuid_1> 2
      <uuid_2> 3
      ...
      1
      イメージの sha256 ダイジェストに置き換えます。
      2
      最初に一致するユニバーサル一意識別子 (UUID)。
      3
      2 番目に一致する UUID。

      検索結果には、一致するエントリーの UUID が表示されます。それらの UUID の 1 つが証明書を保持します。

    3. アテステーションを確認してください。

      $ rekor-cli get --uuid <uuid> --format json | jq -r .Attestation | base64 --decode | jq

4.16.7. 関連情報