This page describes how to access security metadata from the
assuredoss-metadata
Cloud Storage bucket. For a description of the security
metadata, see
Security metadata fields.
This page applies to the Assured OSS premium tier only. For the free tier, see Verify signatures in the Assured OSS free tier.
Before you begin
Extract the metadata
You can use either gcloud
or curl
commands to download the metadata.
Construct the URL for both using the following information:
- Language:
java
,python
, orjavascript
. The value must be in lowercase. - Package_ID: for Java, it's
groupId:artifactId
, for Python it'spackageName
, and for JavaScript, it's one of@org-name/package-name
,@username/package-name
, orpackage-name
. The value must be in lower case. - Version: the version of the package.
The URL must have the following format:
gcloud
gs://assuredoss-metadata/language/package_id/version/metadata.json
The URL must be in lowercase.
Sample Python URL: gs://assuredoss-metadata/python/blessed/1.20.0/metadata.json
Sample Java URL: gs://assuredoss-metadata/java/org.apache.logging.log4j:log4j-core/2.17.1/metadata.json
Sample JavaScript URL: gs://assuredoss-metadata/javascript/@stoplight/spectral-core/0.0.0/metadata.json
curl
https://storage.googleapis.com/assuredoss-metadata/language/package_id/version/metadata.json
The URL must be in lowercase.
Sample Python URL: https://storage.googleapis.com/assuredoss-metadata/python/blessed/1.20.0/metadata.json
Sample Java URL: https://storage.googleapis.com/assuredoss-metadata/java/org.apache.logging.log4j:log4j-core/2.17.1/metadata.json
Sample JavaScript URL: https://storage.googleapis.com/assuredoss-metadata/javascript/@stoplight/spectral-core/0.0.0/metadata.json
- Download the metadata:
gcloud
gcloud storage cp "gs://assuredoss-metadata/language/package_id/version/metadata.json" outputFolderLocation
curl
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" -L https://storage.googleapis.com/assuredoss-metadata/language/package_id/version/metadata.json -o metadata.json
You can now verify the signatures. There are two options:
- Verify the signatures using the aoss-verifier tool
- Verify the signatures of downloaded packages manually
Verify the signatures of downloaded packages using the aoss-verifier tool
Use the aoss-verifier
tool to verify package metadata.
Before using this tool, install Go.
Install the aoss-verifier tool.
Export
$(go env GOPATH)/bin
.Run the
aoss-verifier verify-metadata
command.aoss-verifier verify-metadata \ --metadata_type TYPE \ --language LANGUAGE \ --package_id PACKAGE_ID \ --version VERSION \ [--disable_certificate_verification] \ [--temp_downloads_path TEMP_DOWNLOADS_DIR_PATH] \ [--disable_deletes]
Replace the following:
TYPE
: The possible values arepremiuminfo
.LANGUAGE
: The package language. The value must be in lowercase.PACKAGE_ID
: For Java, the format isgroupId:artifactId
. For Python, the format ispackageName
. The value must be in lower case.VERSION
: The version of the package.
--disable_certificate_verification
is an optional flag which skips matching the leaf certificate to the root certificate through the certificate chain, if used.--temp_downloads_path
is an optional flag to set the path where you want to download the files (replaceTEMP_DOWNLOADS_DIR_PATH
). If the flag isn't set, the files are downloaded to thetmp_downloads
folder in the current directory.--disable_deletes
is an optional flag which keeps the downloaded files. By default, the tool cleans all the downloaded files.
For more information, see the README.
Verify the signatures of downloaded packages manually
You can verify the artifact signature only for the binaries that are securely built by Assured OSS, not the ones that are provided by Assured OSS through proxies.
To verify signatures manually, you can use various tools. The following steps use gcloud CLI, OpenSSL (version 3.0.1 or higher), and jq (1.7.1 or higher) to verify the signatures on Linux.
Download the metadata file. As described in Access metadata using Cloud Storage, the metadata file contains an
SBOM
field inside thebuildInfo
field. The SBOM contains the artifact (for example, a JAR or EGG file) that was built along with an annotation that represents the signature. This artifact lets you determine the SPDX ID.For example, if the artifact name is
artifact_name
, thespdx_id
isSPDXRef-Package-artifact_name
. To validate a package that is namedgradio-3.30.0-py3-none-any.whl
, thespdx_id
isSPDXRef-Package-gradio-3.30.0-py3-none-any.whl
.Extract the SHA-256 digest from the metadata file:
cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.digest[0].digest' | cut -d ' ' -f1 > expectedDigest.txt
Replace the following:
METADATA_FILENAME
: The name of your security metadata file.SPDX_ID
: The SPDX identifier.
Compute the artifact digest:
sha256sum ARTIFACT_FILE | cut -d ' ' -f1 > actualDigest.txt
Replace
ARTIFACT_FILE
with the name of the artifact file.Check for any differences between the two:
diff actualDigest.txt expectedDigest.txt
If there is no difference, there is no output.
Extract the digest of the field to a
.bin
file:cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.digest[0].digest' | cut -d ':' -f2 | xxd -r -p > digest.bin
Extract the signature of the digest to a
.sig
file:cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.signature[0].signature' | xxd -r -p > sig.sig
Extract the public certificate to a
.pem
file:cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.certInfo.cert' | openssl x509 -pubkey -noout > pubKey.pem
Verify the signature of the digest using the certificate:
openssl pkeyutl -in digest.bin -inkey pubKey.pem -pubin -verify -sigfile sig.sig
If successful, this command returns
Signature Verified Successfully
. You can now verify the certificate.Extract the public certificate chain to a
.pem
file:cat METADATA_FILENAME | jq -rj '.buildInfo' | jq -rj '.sbom' | jq -rj '.packages' | jq '.[] | select(.SPDXID=="SPDX_ID")' | jq -rj '.annotations[0].comment' | jq -rj '.certInfo.certChain' | openssl x509 -pubkey -noout > pubKeyChain.pem
Download the root certificate (
ca.crt
in the following command):curl -o ca.crt https://privateca-content-6333d504-0000-2df7-afd6-30fd38154590.storage.googleapis.com/a2c725a592f1d586f1f8/ca.crt
Verify the certificate using the certificate chain and the root certificate:
openssl verify -verbose -CAfile ca.crt -untrusted pubKeyChain.pem pubKey.pem
If successful, this command returns
pubKey.pem: OK
.
Verify the signatures for security metadata fields
You can verify the signature of the following fields in the security metadata file independently:
buildInfo
vexInfo
healthInfo
(if present)
The data inside the fields are hashed using SHA-256, and then the hash is signed using the ECDSAP256_DER algorithm. The certificate and certificate chain are provided inside the metadata so that you can verify the signature. Use the following root certificate to verify the certificate chain:
https://privateca-content-6333d504-0000-2df7-afd6-30fd38154590.storage.googleapis.com/a2c725a592f1d586f1f8/ca.crt
You can verify signatures manually or you can verify signatures using the Assured OSS Verifier Tool.
The following steps describe how to manually verify the signature of the
buildInfo
field in the metadata.json
file. You can use similar steps to
verify the signature of the vexInfo
field or the healthInfo
field.
You can verify signatures using various tools. The following example uses gcloud CLI, OpenSSL (version 3.0.1 or later) and jq (1.7.1 or later) to verify the signatures on a Linux system.
Generate the SHA-256 digest of the field:
cat metadata.json | jq -rj '.buildInfo' | sha256sum | cut -d ' ' -f1 > actualDigest.txt
Extract the digest of the field that is provided in the
metadata.json
file:cat metadata.json | jq -rj '.buildInfoSignature.digest[0].digest' | cut -d ':' -f2 > expectedDigest.txt
Check for any differences between the two digests:
diff actualDigest.txt expectedDigest.txt
If there is no difference then there will be no output, which is the ideal case. You can now verify the signature.
Extract the digest of the field to a
.bin
file:cat metadata.json | jq -rj '.buildInfoSignature.digest[0].digest' | cut -d ':' -f2 | xxd -r -p > digest.bin
Extract the signature of the digest to a
.sig
file:cat metadata.json | jq -rj '.buildInfoSignature.signature[0].signature' | xxd -r -p > sig.sig
Extract the public certificate to a
.pem
file:cat metadata.json | jq -rj '.buildInfoSignature.certInfo.cert' | openssl x509 -pubkey -noout > pubKey.pem
Verify the signature of the digest using the certificate:
openssl pkeyutl -in digest.bin -inkey pubKey.pem -pubin -verify -sigfile sig.sig
If the verification is successful, this command returns
Signature Verified Successfully
. You can now verify the certificate.Extract the public certificate to a
.pem
file:cat metadata.json | jq -rj '.buildInfoSignature.certInfo.cert' | openssl x509 -pubkey -noout > pubKey.pem
Extract the public certificate chain to a
.pem
file:cat metadata.json | jq -rj '.buildInfoSignature.certInfo.certChain' | openssl x509 -pubkey -noout > pubKeyChain.pem
Download the root certificate, named
ca.crt
in the following command:curl -o ca.crt https://privateca-content-6333d504-0000-2df7-afd6-30fd38154590.storage.googleapis.com/a2c725a592f1d586f1f8/ca.crt
Verify the certificate using the certificate chain and the root certificate:
openssl verify -verbose -CAfile ca.crt -untrusted pubKeyChain.pem pubKey.pem
If successful, the command returns
pubKey.pem: OK
.