-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Push SBOM to TPA in gitops PR pipeline #975
Conversation
|
||
} | ||
|
||
download_blob() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should absolutely not be done in Bash. We should use oras blob fetch
. But we would have to productize oras.
attestation_file="$WORKDIR/$image/attestation.json" | ||
sbom_blob_url=$(jq -r \ | ||
'.payload | @base64d | fromjson | .. | select(.name? == "SBOM_BLOB_URL").value' \ | ||
"$attestation_file" | ||
) | ||
mkdir -p "$SBOMS_DIR/$image" | ||
download_blob "$sbom_blob_url" "$SBOMS_DIR/$image/sbom.json" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively, we could just get the SBOM with cosign download sbom
. But that's even less secure.
Given a container image:
- With the "find SBOM_BLOB_URL in the attestation" solution:
- The pipeline can verify that the SBOM_BLOB_URL was returned by the Tekton pipeline that built the image. You still have to trust that the build pipeline created a real SBOM and returned the correct url.
- With the cosign solution:
- The pipeline takes the image digest and downloads the
sha256-$digest.sbom
tag from the image repository. You have to trust (everything above and) that nobody tampered with the tag between the build time and the SBOM download time.
- The pipeline takes the image digest and downloads the
- bombastic_api_url: URL of the BOMbastic api host (e.g. https://sbom.trustification.dev) | ||
- oidc_issuer_url: URL of the OIDC token issuer (e.g. https://sso.trustification.dev/realms/chicken) | ||
- oidc_client_id: OIDC client ID | ||
- oidc_client_secret: OIDC client secret |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do RHTAP customers get the client ID and secret? Do they all use the single "walker" client created at install time?
echo "Getting OIDC token from $token_endpoint" | ||
token_response="$( | ||
curl "${curl_opts[@]}" \ | ||
-H "authorization: Basic $basic_auth" \ | ||
-d "grant_type=client_credentials" \ | ||
"$token_endpoint" | ||
)" | ||
# https://www.rfc-editor.org/rfc/rfc6749.html#section-5.1 | ||
access_token="$(jq -r .access_token <<< "$token_response")" | ||
token_type="$(jq -r .token_type <<< "$token_response")" | ||
expires_in="$(jq -r ".expires_in // empty" <<< "$token_response")" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This task is also too complex for Bash. But as far as I know, there are no plans to productize the CLI that should do this.
if ! jq empty "$filepath" 2>/dev/null; then | ||
echo "$file_relpath: not JSON" | ||
continue | ||
fi | ||
|
||
if ! jq -e '.bomFormat == "CycloneDX"' "$filepath" >/dev/null; then | ||
echo "$file_relpath: not a CycloneDX SBOM" | ||
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Supports only CycloneDX JSONs, I hope that's good enough.
PTAL @mmorhun @jduimovich. I don't like this at all. But it does work if we must have it (some fixes and a lot of polish needed). Tested in https://github.com/acmiel-rhtap/rhtap-idk-gitops/pull/2 (failed on EC validation because I didn't set up ACS) |
One more thing - there's probably nothing that would tie the SBOM uploaded to TPA with the user's container image or with their idea of a "product" A solution could be to document that if user's want their SBOMs to be possible to find, they need to commit Syft configuration into their repo to give their product a name and version source:
name: foo
version: "1.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just put a few of my thought, they are not a request to rework something.
task/download-sbom-from-url-in-attestation/0.1/download-sbom-from-url-in-attestation.yaml
Outdated
Show resolved
Hide resolved
"$image" > "$WORKDIR/$image/attestation.json" | ||
done | ||
|
||
- name: download-sboms |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should have some functionality in ec itself to download certain artifacts associated with an image.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would certainly make this task less awful. If you feel that downloading SBOMs based on the SBOM_BLOB_URL in the attestation makes sense for the EC CLI, I wouldn't mind that.
retry_max_time="$expires_in" | ||
fi | ||
|
||
sbom_id="$(basename -s .json "$sbom_path")" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you want something more unique here. Maybe uuidgen
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The id is the sha256 checksum of the SBOM content (before downgrading its CycloneDX version). The idea is that this avoids duplication when the same SBOM is uploaded multiple times.
(It's not very clear from the code though, so I'll add a comment to clarify).
fi | ||
done | ||
|
||
- name: upload-sboms |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been playing around with uploading to TPA recently but from GitLab. I'll share what I did here in case it's useful to you: https://gitlab.com/lucarval/sign-attest-poc/-/blob/c24001db921c8c2bbb12aeb1c33ae1d910f20504/.gitlab-ci.yml#L108-140
6b5c2af
to
2333a40
Compare
I've cleaned this up as much as I could. Managed to get rid of the
(the |
Apart from the temp commit with the create-trustification-secret.sh script, this is about as clean as it's going to be. PTAL @mmorhun @jduimovich |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job!
9eae59f
to
24edb32
Compare
Quality Gate passedIssues Measures |
Script for creating #!/bin/bash
set -o errexit -o nounset -o pipefail
secret_name=${secret_name:-'tpa-secret'}
private_env_path=${private_env_path:-'../rhtap-installer/private.env'}
tpa_namespace=${tpa_namespace:-'rhtap'}
source "$private_env_path"
oc create secret generic "$secret_name" \
--from-literal bombastic_api_url="https://$(oc -n "$tpa_namespace" get route --selector app.kubernetes.io/name=bombastic-api -o jsonpath='{.items[].spec.host}')" \
--from-literal oidc_issuer_url="https://$(oc -n "$tpa_namespace" get route --selector app.kubernetes.io/name=keycloak -o jsonpath='{.items[].spec.host}')/realms/chicken" \
--from-literal oidc_client_id=walker \
--from-literal oidc_client_secret="$TPA__OIDC__WALKER_CLIENT_SECRET" \
--from-literal supported_cyclonedx_version=1.4 |
task/upload-sbom-to-trustification/0.1/upload-sbom-to-trustification.yaml
Outdated
Show resolved
Hide resolved
Add ENVIRONMENTS param, defaults to ["development", "stage", "prod"]. Signed-off-by: Adam Cmiel <acmiel@redhat.com>
STONEBLD-2335 The task accepts the output of 'gather-deploy-images' as input. It downloads the attestation for each image, using the same technique as the EC task to verify them. The task extracts the SBOM_BLOB_URL from the attestation and downloads the SBOM from the url. The vast majority of the download_blob code could be replaced with 'oras blob fetch'. But oras is not productized for use in RHTAP. Signed-off-by: Adam Cmiel <acmiel@redhat.com>
STONEBLD-2335 Takes a workspace containing CycloneDX JSON SBOMs, uploads them to Trustification using the BOMBastic API. See the task description for more details. Signed-off-by: Adam Cmiel <acmiel@redhat.com>
STONEBLD-2335 When a PR updates the image in the stage or prod deployment, download the SBOM for that image and upload it to Trustification. Signed-off-by: Adam Cmiel <acmiel@redhat.com>
When FAIL_IF_TRUSTIFICATION_NOT_CONFIGURED=false and the required Trustification configuration is missing, the task will exit with success. Signed-off-by: Adam Cmiel <acmiel@redhat.com>
/retest |
When a PR in a gitops repo updates the stage or prod image:
cosign verify-attestation
sha256:<pre-conversion-digest>
This is split into two separate tasks
download-sbom-from-url-in-attestation
Gets an array of images, downloads their attestations, downloads the SBOM blobs found in those attestations
upload-sbom-to-trustification
Gets a directory of SBOMs, uploads them to Trustification.
Requires the
trustification-secret
(see the task README).