Subscription Information
This feature is supported with the Enterprise+ license.
This section describes how to create your own DSSE envelope containing evidence that can be attached to an artifact in Artifactory with the Deploy Evidence REST API without using the Create Evidence CLI. DSSE is a standard for signing arbitrary data, as described here.
The basic steps are as follows:
Create the Predicate
For the purposes of this example, the following predicate represents a GitHub Actions build attestation for SLSA provenance. The predicate contains the actual contents of the evidence, meaning a set of claims about the evidence subject.
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "example-file.txt",
"digest": {
"sha256": "<sha256>"
}
}
],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {
"buildDefinition": {
"buildType": "https://actions.github.io/buildtypes/example",
"externalParameters": {
"workflow": {
"ref": "refs/heads/main",
"repository": "https://github.com/example/attest",
"path": ".github/workflows/main.yml"
}
},
"internalParameters": {
"github": {
"event_name": "push",
"repository_id": 947952664,
"repository_owner_id": 4086454,
"runner_environment": "github-hosted"
}
},
"resolvedDependencies": [
{
"uri": "git+https://github.com/example/attest@refs/heads/main",
"digest": {
"gitCommit": "78fe991581dc9914b49e3cc49b9ac64fa32190bf"
}
}
]
},
"runDetails": {
"builder": {
"id": "https://github.com/example/test/.github/workflows/main.yml@refs/heads/main"
},
"metadata": {
"invocationId": "https://github.com/example/test/actions/runs/13882635751/attempts/1"
}
},
"createdAt": "1971-01-01T00:00:00.000Z",
"createdBy": "example-user"
}
}
Create and Encode the Signature
The signature for your evidence requires a PAE (pre-authenticated encoding) that includes the DSSE version, the payload type, and the predicate, all in a specific format.
Three pieces of information are required:
The predicate file (predicate.json) that you created above
A file describing the payload type (described in step 1 below)
The path to your private key
To create and encode the signature:
Create a file called payload_type.txt that contains the payload type (application/vnd.in-toto+json) as a string:
cat payload_type.txt application/vnd.in-toto+json
Run the following bash script in your terminal:
./sign_predicate.sh predicate.json payload_type.txt ./path/to/private-key.pem ✅ Done. Output files: - pae.txt (pre-authenticated encoding) - sig.bin (raw signature) - sig.b64 (base64-encoded signature) - payload.b64 (base64-encoded chomped predicate)
The four files created by this script will all be used in the final DSSE envelope (evidence.json), as described in the next section.
The contents of the script are shown below.
cat sign_predicate.sh #!/bin/bash set -e # === Input Validation === if [ "$#" -ne 2 ]; then echo "Usage: $0 <predicate.json> <payload_type.txt>" exit 1 fi PREDICATE_FILE="$1" PAYLOAD_TYPE_FILE="$2" PRIVATE_KEY="$3" # === Compute lengths === payload_type_len=$(perl -pe 'chomp if eof' "$PAYLOAD_TYPE_FILE" | wc -c | xargs) predicate_len=$(perl -pe 'chomp if eof' "$PREDICATE_FILE" | wc -c | xargs) # === Create pae.txt === { echo -n "DSSEv1 " echo -n "$payload_type_len " perl -pe 'chomp if eof' "$PAYLOAD_TYPE_FILE" echo -n " $predicate_len " perl -pe 'chomp if eof' "$PREDICATE_FILE" } > pae.txt # === Sign with private key === openssl dgst -sha256 -sign "$PRIVATE_KEY" -out sig.bin pae.txt # === Base64 encode the signature === base64 < sig.bin > sig.b64 # === Base64 encode chomped predicate file and output to payload.b64 === perl -pe 'chomp if eof' "$PREDICATE_FILE" | base64 > payload.b64 echo "✅ Done. Output files:" echo " - pae.txt (pre-authenticated encoding)" echo " - sig.bin (raw signature)" echo " - sig.b64 (base64-encoded signature)" echo " - payload.b64 (base64-encoded chomped predicate)"
Create the DSSE Envelope
Create a DSSE envelope called evidence.json based on the files created by the bash script above. The envelope contains a Base64-encoded payload and the signature.
{
"payload": <payload.b64>,
"payloadType": "application/vnd.in-toto+json",
"signatures": [
{
"keyid": "<key alias>",
"sig": <sig.b64>
}
]
}
This file contains:
payload: A base64-encoded JSON that includes the predicatepayloadType: a label that interprets the payloadkeyid: the alias of the signing key in Artifactorysig: the cryptographic signature that was created in conjunction with the private key
Deploy the Evidence with the REST API
Use the Deploy Evidence REST API to deploy the evidence to Artifactory. It uses the evidence.json file that you created in the previous steps.
curl -H"Authorization: Bearer $TOKEN" -T evidence.json -XPOST "https://server.jfrog.io/evidence/api/v1/subject/example-generic-local/example-file.txt"
This command attaches evidence to the example-file.txt file, which is located in the example-generic-local repository.