Verify Release Bundles (v2)

JFrog Artifactory Documentation

Products
JFrog Artifactory
Content Type
User Guide
ft:sourceType
Paligo

This procedure describes how to verify the signature and contents of a Release Bundle v2. Use this procedure if you want to verify independently that:

  • The Release Bundle manifest has not been tampered with en route to its current location (for example, a deployment server)Release Bundle Manifest for Builds

  • The artifacts contained in the Release Bundle have not been tampered with en route

The basic steps are outlined in the following table.

#

Action

Command

1

Get the Release Bundle manifest file

Use the Get Release Bundle v2 Version Signature API:Get Release Bundle v2 Version Signature

GET {artifactory-host}}/lifecycle/api/v2/release_bundle/signatures/{name}/{version}?project=default

Sample result:

{    
    "payload": 
"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJ1...", 
    "payloadType": "application/vnd.in-toto+json", 
    "signatures": [ 
        {     
            "keyid": "PGP-RSA-2048", 
            "sig": 
"LS0tLS1CRUdJTiBQR1AgU0lHTkFUVVJFLS0tLS0KVmVyc2lvbjogQkNQRyB2QFJFTEVBU0..." 
        }
    ]
}

2

Get the public key from Artifactory using the keyid defined in the Release Bundle manifest

Use the Get Key Pair API:Get Key Pair

GET {artifactory-host}/artifactory/api/security/keypair/{keyid}

Sample result:

{ 
    "pairName": "PGP-RSA-2048", 
    "pairType": "GPG", 
    "alias": "pgp-rsa-2048", 
    "publicKey": "-----BEGIN PGP PUBLIC KEY BLOCK-----
\n\nmI0EZJA1TAEEAOjFw17MiG608NR60PZ/zpX7GoOjJr2/CNUQwytQXC3BPWMkuVTx\nxajKZj6... 
-----END PGP PUBLIC KEY BLOCK-----", 
    "unavailable": false
}

3

Verify the DSSE signature in the manifest file

Following is a sample Bash script for performing signature verification:

# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# Construct a PAE (Pre-Authentication Encoding) according to the DSSE protocol.
# Use the payload type from in-toto Attestation Framework. Save it as a new file.
#
function build_pre_auth_encoding() { 
    payload=$(cat "evidence.json" | jq '.payload' -r | base64 -d) 
    payload_length=${#payload} 
    payload_type=$(cat "evidence.json" | jq '.payloadType' -r) 
    payload_type_length=${#payload_type} 
    echo "DSSEv1 $payload_type_length $payload_type $payload_length $payload" > "tmp/pae.txt"
} 

# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# Verify a digital signature (RSA-2048 + SHA-256) for PAE.
#
function verify_digital_signature() { 
    signature=$(cat "evidence.json" | jq '.signatures[0].sig' -r | base64 -d) 
    echo "$signature" > "tmp/signature.txt" 
    openssl dgst -sha256 -verify key/public.key -signature "tmp/signature.txt" "tmp/pae.txt"
} 

# == == == == == == == == == == == == == == == == == == == == == == == == == ==
# WORKFLOW: 

build_pre_auth_encoding
Verify_digital_signature

4

Verify the artifacts in the Release Bundle

Following is a sample command for getting the list of artifacts from the manifest and comparing each artifact to its sha256 digest:

cat release-bundle.json | jq .payload -r | base64 -d | jq '[.subject[]|{uri, digest}]'

[
{ 
    "uri": "artifacts/docker/commons/1.0.0/manifest.json", 
    "digest": { 
        "sha256": "c32c8946f9fce70a153a06b99636f8269fa869825fe0ce5de7efd8b7" 
    }
},
{ 
    "uri": 
"artifacts/docker/commons/1.0.0/sha256__9270ca3b7b122596e6871820724eb9fd16bd", 
    "digest": { 
        "sha256": "9270ca2a0ad3396353d2fe727b12143ac562596e6871820724eb9fd16bd" 
    }
},
{ 
    "uri": "artifacts/generic/commons-1.0.0.txt", 
    "digest": { 
        "sha256": "f87e4c72e60300b451739d545afc0251a6e2f4bd1b1902ba739455897ecb8" 
    }
}
]

Tip

Use the sha256sum util to calculate the actual sha256 of the files in the Release Bundle. For example:

>sha256sum commons-1.0.0.txt 
f87e4c72e60300b451739d545afc0251a6e2f4bd1b1902ba739455897ecb8 commons-1.0.0.txt

You can then compare this calculated value with the value defined in the Release Bundle manifest.