3.17. OpenShift Pipelines サプライチェーンセキュリティーでの Tekton Chains の使用
Tekton Chains は、Kubernetes カスタムリソース定義 (CRD) コントローラーです。これを使用して、Red Hat OpenShift Pipelines を使用して作成されたタスクおよびパイプラインのサプライチェーンセキュリティーを管理できます。
デフォルトでは、Tekton Chains は OpenShift Container Platform クラスター内のすべてのタスク実行の実行を監視します。タスクの実行が完了すると、Tekton Chains はタスクの実行のスナップショットを取得します。次に、スナップショットを 1 つ以上の標準ペイロード形式に変換し、最後にすべてのアーティファクトに署名して保存します。
タスクの実行に関する情報を取得するために、Tekton Chains は Result オブジェクトを使用します。オブジェクトが使用できない場合、Tekton は OCI イメージの URL と修飾されたダイジェストをチェーンします。
3.17.1. 主な特長
-
cosignやskopeoなどのツールで生成された暗号キーを使用して、タスク実行、タスク実行結果、OCI レジストリーイメージに署名できます。 -
in-totoなどの認証形式を使用できます。 - OCI リポジトリーをストレージバックエンドとして使用して、署名と署名されたアーティファクトを安全に保存できます。
3.17.2. Tekton Chains の設定
Red Hat OpenShift Pipelines Operator は、デフォルトで Tekton Chains をインストールします。TektonConfig カスタムリソースを変更することで、Tekton Chains を設定できます。Operator は、このカスタムリソースに加えた変更を自動的に適用します。
カスタムリソースを編集するには、次のコマンドを使用します。
$ oc edit TektonConfig config
カスタムリソースには、chain: 配列が含まれます。次の例に示すように、サポートされている設定パラメーターをこの配列に追加できます。
apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
name: config
spec:
addon: {}
chain:
artifacts.taskrun.format: tekton
config: {}3.17.2.1. Tekton Chains 設定でサポートされているパラメーター
クラスター管理者は、サポートされているさまざまなパラメーターのキーと値を使用して、タスクの実行、OCI イメージ、およびストレージに関する仕様を設定できます。
3.17.2.1.1. タスク実行アーティファクトでサポートされているパラメーター
表3.19 チェーン設定: タスク実行アーティファクトでサポートされているパラメーター
| キー | 説明 | サポート対象の値 | デフォルト値 |
|---|---|---|---|
|
| タスク実行ペイロードを保存するための形式。 |
|
|
|
|
タスク実行署名のストレージバックエンド。 |
|
|
|
| タスク実行ペイロードに署名するための署名バックエンド。 |
|
|
slsa/v1 は、下位互換性のための in-toto のエイリアスです。
3.17.2.1.2. パイプライン実行アーティファクトでサポートされているパラメーター
表3.20 チェーン設定: パイプライン実行アーティファクトでサポートされているパラメーター
| パラメーター | 説明 | サポート対象の値 | デフォルト値 |
|---|---|---|---|
|
| パイプライン実行ペイロードを保存する形式。 |
|
|
|
|
パイプライン実行署名を保存するためのストレージバックエンド。 |
|
|
|
| パイプライン実行ペイロードに署名するための署名バックエンド。 |
|
|
-
slsa/v1は、下位互換性のためのin-totoのエイリアスです。 -
Grafeasストレージバックエンドの場合、Container Analysis のみがサポートされます。Tekton Chains の現在のバージョンでは、grafeasサーバーアドレスを設定できません。
3.17.2.1.3. OCI アーティファクトでサポートされているパラメーター
表3.21 チェーン設定: OCI アーティファクトでサポートされているパラメーター
| パラメーター | 説明 | サポート対象の値 | デフォルト値 |
|---|---|---|---|
|
| OCI ペイロードを保存するための形式。 |
|
|
|
|
OCI 署名を保存するためのストレージバックエンド。 |
|
|
|
| OCI ペイロードに署名するための署名バックエンド。 |
|
|
3.17.2.1.4. KMS 署名者でサポートされているパラメーター
表3.22 チェーン設定: KMS 署名者用にサポートされているパラメーター
| パラメーター | 説明 | サポート対象の値 | デフォルト値 |
|---|---|---|---|
|
|
|
サポートされているスキーム: |
3.17.2.1.5. ストレージでサポートされているパラメーター
表3.23 Chains 設定: ストレージでサポートされているパラメーター
| パラメーター | 説明 | サポート対象の値 | デフォルト値 |
|---|---|---|---|
|
| ストレージ用の GCS バケット | ||
|
| OCI 署名と証明書を保存するための OCI リポジトリー。 |
アーティファクトストレージバックエンドの 1 つを | |
|
| in-toto 証明書に設定するビルダー ID |
|
任意のアーティファクトに対して docdb ストレージ方法を有効にする場合は、docstore ストレージオプションを設定します。go-cloud docstore URI 形式の詳細は、docstore パッケージのドキュメント を参照してください。Red Hat OpenShift Pipelines は、次の docstore サービスをサポートしています。
-
firestore -
dynamodb
表3.24 Chains 設定: docstore ストレージでサポートされているパラメーター
| パラメーター | 説明 | サポート対象の値 | デフォルト値 |
|---|---|---|---|
|
|
|
|
アーティファクトに対して Grafeas ストレージ方式を有効にする場合は、Grafeas ストレージオプションを設定します。Grafeas のメモとオカレンスの詳細は、 Grafeas の概念 を参照してください。
オカレンスを作成するには、Red Hat OpenShift Pipelines はまずオカレンスのリンクに使用されるノートを作成する必要があります。Red Hat OpenShift Pipelines は、ATESTATION オカレンスと BUILD オカレンスの 2 種類のオカレンスを作成します。
Red Hat OpenShift Pipelines は、設定可能な noteid をノート名の接頭辞として使用します。ATTESTATION ノートには接尾辞 -simplesigning が、BUILD ノートには接尾辞 -intoto が追加されます。noteid フィールドが設定されていない場合、Red Hat OpenShift Pipelines は接頭辞として tekton-<NAMESPACE> を使用します。
表3.25 Chains 設定: Grafeas ストレージでサポートされているパラメーター
| パラメーター | 説明 | サポート対象の値 | デフォルト値 |
|---|---|---|---|
|
| オカレンスを保存する Grafeas サーバーが配置されている OpenShift Container Platform プロジェクト。 | ||
|
| オプション: 作成されたすべてのメモの名前に使用する接頭辞。 | スペースなしの文字列。 | |
|
|
オプション: Grafeas |
|
オプションで、バイナリー透過性証明書の追加アップロードを有効にすることができます。
表3.26 Chains 設定: 透過性証明書ストレージでサポートされているパラメーター
| パラメーター | 説明 | サポート対象の値 | デフォルト値 |
|---|---|---|---|
|
| 自動バイナリー透過アップロードを有効または無効にします。 |
|
|
|
| バイナリー透過性証明書をアップロードするための URL (有効な場合)。 |
|
Transparency.enabled を manual に設定すると、次のアノテーションが付いたタスク実行とパイプライン実行のみが透明性ログにアップロードされます。
chains.tekton.dev/transparency-upload: "true"
x509 署名バックエンドを設定する場合、オプションで Fulcio を使用したキーレス署名を有効にすることができます。
表3.27 チェーン設定: Fulcio を使用した x509 キーレス署名でサポートされているパラメーター
| パラメーター | 説明 | サポート対象の値 | デフォルト値 |
|---|---|---|---|
|
| Fulcio からの自動証明書の要求を有効または無効にします。 |
|
|
|
| 証明書を要求するための Fulcio アドレス (有効な場合)。 |
| |
|
| 予想される OIDC 発行者。 |
| |
|
| ID トークンを要求するプロバイダー。 |
| Red Hat OpenShift Pipelines はすべてのプロバイダーの使用を試みます |
|
| ID トークンを含むファイルへのパス。 | ||
|
|
TUF サーバーの URL。 |
|
kms 署名バックエンドを設定する場合は、必要に応じて OIDC や Spire を含む KMS 設定を設定します。
表3.28 Chains 設定: KMS 署名でサポートされているパラメーター
| パラメーター | 説明 | サポート対象の値 | デフォルト値 |
|---|---|---|---|
|
|
KMS サーバーの URI ( |
|
KMS サーバーの認証トークン ( |
|
|
OIDC 認証のパス (Vault の場合は |
| OIDC 認証のロール。 |
|
|
KMS トークンの Spire ソケットの URI (例: |
| Spire から SVID をリクエストする対象者。 |
3.17.3. Tekton Chains でデータに署名するための秘密
クラスター管理者は、キーペアを生成し、Tekton Chains を使用して、Kubernetes シークレットを使用してアーティファクトに署名できます。Tekton Chains が機能するには、暗号化されたキーの秘密鍵とパスワードが、openshift-pipelines namespace の signing-secrets シークレットの一部として存在している必要があります。
現在、Tekton Chains は x509 および cosign 署名スキームをサポートしています。
サポートされている署名スキームの 1 つのみを使用してください。
Tekton Chains で x509 署名スキームを使用するには、ed25519 または ecdsa タイプの x509.pem 秘密鍵を signing-secrets Kubernetes シークレットに保存します。
3.17.3.1. cosign を使用した署名
cosign 署名ツールを使用すると、Tekton Chains で cosign スキームを使用できます。
前提条件
- cosign ツールをインストールしました。
手順
次のコマンドを実行して、
cosign.keyとcosign.pubキーのペアを生成します。$ cosign generate-key-pair k8s://openshift-pipelines/signing-secrets
Cosign はパスワードの入力を求め、Kubernetes シークレットを作成します。
-
暗号化された
cosign.key秘密鍵とcosign.password復号化パスワードをsigning-secretsKubernetes シークレットに保存します。秘密鍵がENCRYPTED COSIGN PRIVATE KEYタイプの暗号化された PEM ファイルとして保存されていることを確認します。
3.17.3.2. skopeo を使用した署名
skopeo ツールを使用してキーを生成し、Tekton Chains で cosign 署名スキームで使用できます。
前提条件
- skopeo ツールがインストールされました。
手順
次のコマンドを実行して、公開キーと秘密キーのペアを生成します。
$ skopeo generate-sigstore-key --output-prefix <mykey> 1- 1
<mykey>を選択したキー名に置き換えます。
Skopeo は秘密キーのパスフレーズの入力を求め、
<mykey>.privateおよび<mykey>.pubという名前のキーファイルを作成します。次のコマンドを実行して、
base64ツールを使用して<mykey>.pubファイルをエンコードします。$ base64 -w 0 <mykey>.pub > b64.pub
次のコマンドを実行して、
base64ツールを使用して<mykey>.privateファイルをエンコードします。$ base64 -w 0 <mykey>.private > b64.private
次のコマンドを実行して、
base64ツールを使用してパスフレーズをエンコードします。$ echo -n '<passphrase>' | base64 -w 0 > b64.passphrase 1- 1
<passphrase>をキーペアに使用したパスフレーズに置き換えます。
次のコマンドを実行して、
openshift-pipelinesnamespace にsigned-secretsシークレットを作成します。$ oc create secret generic signing-secrets -n openshift-pipelines
以下のコマンドを実行して
signing-secretsシークレットを編集します。$ oc edit secret -n openshift-pipelines signing-secrets
次の方法で、エンコードされたキーをシークレットのデータに追加します。
apiVersion: v1 data: cosign.key: <Encoded <mykey>.private> 1 cosign.password: <Encoded passphrase> 2 cosign.pub: <Encoded <mykey>.pub> 3 immutable: true kind: Secret metadata: name: signing-secrets # ... type: Opaque
3.17.3.3. シークレットはすでに存在しますエラーの解決
signed-secret シークレットがすでに入力されている場合、このシークレットを作成するコマンドは次のエラーメッセージを出力する可能性があります。
Error from server (AlreadyExists): secrets "signing-secrets" already exists
このエラーは、シークレットを削除することで解決できます。
手順
次のコマンドを実行して、
signing-secretシークレットを削除します。$ oc delete secret signing-secrets -n openshift-pipelines
- キーペアを再作成し、好みの署名スキームを使用してシークレットに保存します。
3.17.4. OCI レジストリーへの認証
署名を OCI レジストリーにプッシュする前に、クラスター管理者は、レジストリーで認証するように Tekton Chains を設定する必要があります。Tekton Chains コントローラーは、タスクの実行と同じサービスアカウントを使用します。署名を OCI レジストリーにプッシュするために必要なクレデンシャルを使用してサービスアカウントを設定するには、次の手順を実行します。
手順
Kubernetes サービスアカウントの namespace と名前を設定します。
$ export NAMESPACE=<namespace> 1 $ export SERVICE_ACCOUNT_NAME=<service_account> 2
Kubernetes シークレットを作成します。
$ oc create secret registry-credentials \ --from-file=.dockerconfigjson \ 1 --type=kubernetes.io/dockerconfigjson \ -n $NAMESPACE- 1
- Docker 設定ファイルへのパスに置き換えます。デフォルトのパスは
~/.docker/config.jsonです。
サービスアカウントにシークレットへのアクセス権限を付与します。
$ oc patch serviceaccount $SERVICE_ACCOUNT_NAME \ -p "{\"imagePullSecrets\": [{\"name\": \"registry-credentials\"}]}" -n $NAMESPACERed Hat OpenShift Pipelines がすべてのタスク実行に割り当てるデフォルトの
pipelineサービスアカウントにパッチを適用すると、Red Hat OpenShift Pipelines Operator はサービスアカウントをオーバーライドします。ベストプラクティスとして、次の手順を実行できます。ユーザーのタスク実行に割り当てる別のサービスアカウントを作成します。
$ oc create serviceaccount <service_account_name>
タスク実行テンプレートの
serviceaccountnameフィールドの値を設定して、サービスアカウントをタスク実行に関連付けます。apiVersion: tekton.dev/v1beta1 kind: TaskRun metadata: name: build-push-task-run-2 spec: serviceAccountName: build-bot 1 taskRef: name: build-push ...- 1
- 新しく作成したサービスアカウントの名前に置き換えます。
3.17.5. 追加の認証なしでタスク実行署名を作成および検証する
追加の認証を使用して Tekton Chains を使用してタスク実行の署名を検証するには、次のタスクを実行します。
- 暗号化された x509 キーペアを作成し、Kubernetes シークレットとして保存します。
- Tekton Chains バックエンドストレージを設定します。
- タスク実行を作成して署名し、署名とペイロードをタスク実行自体にアノテーションとして保存します。
- 署名されたタスクの実行から署名とペイロードを取得します。
- タスク実行の署名を確認します。
前提条件
次のコンポーネントがクラスターにインストールされていることを確認してください。
- Red Hat OpenShift Pipelines Operator
- Tekton Chains
- Cosign
手順
- 暗号化された x509 キーペアを作成し、Kubernetes シークレットとして保存します。キーペアの作成とシークレットとしての保存の詳細については、Tekton Chains でのシークレットの署名を参照してください。
Tekton Chains 設定で、OCI ストレージを無効にし、タスク実行ストレージとフォーマットを
tektonに設定します。TektonConfigカスタムリソースで次の値を設定します。apiVersion: operator.tekton.dev/v1alpha1 kind: TektonConfig metadata: name: config spec: # ... chain: artifacts.oci.storage: "" artifacts.taskrun.format: tekton artifacts.taskrun.storage: tekton # ...TektonConfigカスタムリソースを使用した Tekton チェーンの設定の詳細は、Tekton チェーンの設定を参照してください。Tekton Chains コントローラーを再起動して、変更した設定が確実に適用されるようにするには、次のコマンドを入力します。
$ oc delete po -n openshift-pipelines -l app=tekton-chains-controller
次のコマンドを入力してタスク実行を作成します。
$ oc create -f https://raw.githubusercontent.com/tektoncd/chains/main/examples/taskruns/task-output-image.yaml 1- 1
- サンプル URI を、タスクの実行を指す URI またはファイルパスに置き換えます。
出力例
taskrun.tekton.dev/build-push-run-output-image-qbjvh created
次のコマンドを入力して、ステップのステータスを確認します。プロセスが完了するまで待ちます。
$ 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
Base64でエンコードされたアノテーションとして保存されたオブジェクトから署名を取得するには、次のコマンドを入力します。$ tkn tr describe --last -o jsonpath="{.metadata.annotations.chains\.tekton\.dev/signature-taskrun-$TASKRUN_UID}" | base64 -d > sig$ export TASKRUN_UID=$(tkn tr describe --last -o jsonpath='{.metadata.uid}')- 作成した公開キーを使用して署名を検証するには、次のコマンドを入力します。
$ cosign verify-blob-attestation --insecure-ignore-tlog --key path/to/cosign.pub --signature sig --type slsaprovenance --check-claims=false /dev/null 1- 1
path/to/cosign.pubを公開キーファイルのパス名に置き換えます。出力例
Verified OK
3.17.5.1. 関連情報
3.17.6. Tekton Chains を使用してイメージと証明書を署名検証する
クラスター管理者は、Tekton Chains を使用して、以下のタスクを実行することで、イメージと証明書を署名および検証できます。
- 暗号化された x509 キーペアを作成し、Kubernetes シークレットとして保存します。
- OCI レジストリーの認証を設定して、イメージ、イメージ署名、および署名されたイメージ証明書を保存します。
- Tekton Chains を設定して、証明書を生成し署名します。
- タスク実行で Kaniko を使用してイメージを作成します。
- 署名されたイメージと署名された証明書を検証する。
前提条件
以下がクラスターにインストールされていることを確認します。
手順
暗号化された x509 キーペアを作成し、Kubernetes シークレットとして保存します。
$ cosign generate-key-pair k8s://openshift-pipelines/signing-secrets
プロンプトが表示されたらパスワードを入力します。Cosign は、結果の秘密鍵を
signing-secretsKubernetes シークレットの一部としてopenshift-pipelinesnamespace に保存し、公開鍵をcosign.pubローカルファイルに書き込みます。イメージレジストリーの認証を設定します。
- 署名を OCI レジストリーにプッシュするように Tekton Chains コントローラーを設定するには、タスク実行のサービスアカウントに関連付けられたクレデンシャルを使用します。詳細については、OCI レジストリーへの認証を参照してください。
イメージをビルドしてレジストリーにプッシュする Kaniko タスクの認証を設定するには、必要なクレデンシャルを含む docker
config.jsonファイルの Kubernetes シークレットを作成します。$ oc create secret generic <docker_config_secret_name> \ 1 --from-file <path_to_config.json> 2
Tekton Chains を設定するには、
chains-configオブジェクトでartifacts.taskrun.format、artifacts.taskrun.storage、transparency.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"}}'Kaniko タスクを開始します。
Kaniko タスクをクラスターに適用します。
$ oc apply -f examples/kaniko/kaniko.yaml 1- 1
- Kaniko タスクへの URI またはファイルパスに置き換えます。
適切な環境変数を設定します。
$ export REGISTRY=<url_of_registry> 1 $ export DOCKERCONFIG_SECRET_NAME=<name_of_the_secret_in_docker_config_json> 2
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にプッシュされます。
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
- タスク実行の名前に置き換えます。
イメージとアテステーションを確認します。
$ cosign verify --key cosign.pub $REGISTRY/kaniko-chains $ cosign verify-attestation --key cosign.pub $REGISTRY/kaniko-chains
Rekor でイメージの証明書を見つけます。
- $ REGISTRY/kaniko-chains イメージのダイジェストを取得します。タスクの実行中に検索するか、イメージをプルしてダイジェストを展開できます。
Rekor を検索して、イメージの
sha256ダイジェストに一致するすべてのエントリーを見つけます。$ rekor-cli search --sha <image_digest> 1 <uuid_1> 2 <uuid_2> 3 ...
検索結果には、一致するエントリーの UUID が表示されます。それらの UUID の 1 つが証明書を保持します。
アテステーションを確認してください。
$ rekor-cli get --uuid <uuid> --format json | jq -r .Attestation | base64 --decode | jq