Deploy Evidence Directly Using Your Own DSSE

JFrog Artifactory Documentation

Products
JFrog Artifactory
Content Type
User Guide

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.Deploy EvidenceCreate Evidence CLI

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:

  1. 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
    
  2. 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 predicate

  • payloadType: a label that interprets the payload

  • keyid: the alias of the signing key in Artifactory

  • sig: 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.Deploy Evidence

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.