Artifactory enables you to attach evidence (signed metadata) to a designated subject, such as an artifact, build, package, or Release Bundle v2. These evidence files provide a record of an external process performed on the subject, such as test results, vulnerability scans, or official approval.
This document describes how to use the JFrog CLI to create different types of evidence related to a Docker image deployed to Artifactory, including:
- Package evidence
- Generic evidence
- Build evidence
- Release Bundle evidence
The following workflow is described:
- Bootstrapping
- Build the Docker Image
- Attach Package Evidence
- Upload README File and Associated Evidence
- Publish Build Info and Attach Build Evidence
- Create a Release Bundle v2 from the Build
- Attach Release Bundle Evidence
Refer to build.yaml for the complete script.
For more information about evidence on the JFrog platform, see Evidence Management.
- Make sure JFrog CLI 2.65.0 or above is installed and in your system PATH. For installation instructions, see Install JFrog CLI.
- Make sure Artifactory can be used as a Docker registry. Please refer to Getting Started with Artifactory as a Docker Registry in the JFrog Artifactory User Guide. You should end up with a Docker registry URL, which is mapped to a local Docker repository (or a virtual Docker repository with a local deployment target) in Artifactory. You'll need to know the name of the Docker repository to later collect the published image build-info.
- Make sure the following repository variables are configured in GitHub settings:
- ARTIFACTORY_URL (location of your Artifactory installation)
- BUILD_NAME (planned name for the build of the Docker image)
- BUNDLE_NAME (planned name for the Release Bundle created from the build)
- Make sure the following repository secrets are configured in GitHub settings:
- ARTIFACTORY_ACCESS_TOKEN (access token used for authentication)
- JF_USER (your username in Artifactory)
- PRIVATE_KEY (the key used to sign evidence)
This section of build.yaml installs the latest version of the JFrog CLI and performs checkout. Please note that a valid access token is required.
jobs:
Docker-build-with-evidence:
runs-on: ubuntu-latest
steps:
- name: Install jfrog cli
uses: jfrog/setup-jfrog-cli@v4
env:
JF_URL: ${{ vars.ARTIFACTORY_URL }}
JF_ACCESS_TOKEN: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
- uses: actions/checkout@v4
This section of build.yaml logs into the Docker registry, as described in the prerequisites, and sets up QEMU and Docker Buildx in preparation for building the Docker image.
- name: Log in to Artifactory Docker Registry
uses: docker/login-action@v3
with:
registry: ${{ vars.ARTIFACTORY_URL }}
username: ${{ secrets.JF_USER }}
password: ${{ secrets.ARTIFACTORY_ACCESS_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
platforms: linux/amd64,linux/arm64
install: true
This section of build.yaml builds the Docker image and deploys it to Artifactory.
- name: Build Docker image
run: |
URL=$(echo ${{ vars.ARTIFACTORY_URL }} | sed 's|^https://||')
REPO_URL=${URL}'/example-project-docker-dev-virtual'
docker build --build-arg REPO_URL=${REPO_URL} -f Dockerfile . \
--tag ${REPO_URL}/example-project-app:${{ github.run_number }} \
--output=type=image --platform linux/amd64 --metadata-file=build-metadata --push
jfrog rt build-docker-create example-project-docker-dev --image-file build-metadata --build-name ${{ vars.BUILD_NAME }} --build-number ${{ github.run_number }}
This section of build.yaml creates evidence for the package containing the Docker image. The evidence is signed with your private key, as defined in the Prerequisites.
- name: Evidence on docker
run: |
echo '{ "actor": "${{ github.actor }}", "date": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'" }' > sign.json
jf evd create --package-name example-project-app --package-version 32 --package-repo-name example-project-docker-dev \
--key "${{ secrets.PRIVATE_KEY }}" \
--predicate ./sign.json --predicate-type https://jfrog.com/evidence/signature/v1
echo ' Evidence attached: `signature` '
This section of build.yaml uploads the README file and creates signed evidence about this generic artifact. The purpose of this section is to demonstrate the ability to create evidence for any type of file uploaded to Artifactory, in addition to packages, builds, and Release Bundles.
- name: Upload readme file
run: |
jf rt upload ./README.md example-project-generic-dev/readme/${{ github.run\_number }}/ --build-name ${{ vars.BUILD_NAME }} --build-number ${{ github.run_number }}
jf evd create --subject-repo-path example-project-generic-dev/readme/${{ github.run_number }}/README.md \
--key "${{ secrets.PRIVATE_KEY }}" \
--predicate ./sign.json --predicate-type https://jfrog.com/evidence/signature/v1
This section of build.yaml creates a build from the package containing the Docker image and then creates signed evidence attesting to its creation.
- name: Publish build info
run: jfrog rt build-publish ${{ vars.BUILD_NAME }} ${{ github.run_number }}
- name: Sign build evidence
run: |
echo '{ "actor": "${{ github.actor }}", "date": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'" }' > sign.json
jf evd create --build-name ${{ vars.BUILD_NAME }} --build-number ${{ github.run_number }} \
--predicate ./sign.json --predicate-type https://jfrog.com/evidence/build-signature/v1 \
--key "${{ secrets.PRIVATE_KEY }}"
echo ' Evidence attached: `build-signature` ' >> $GITHUB_STEP_SUMMARY
This section of build.yaml creates an immutable Release Bundle v2 from the build containing the Docker image. Having a Release Bundle prevents any changes to the Docker image as it progresses through the various stages of your SDLC towards eventual distribution to your end users.
- name: Create release bundle
run: |
echo '{ "files": [ {"build": "'"${{ vars.BUILD_NAME }}/${{ github.run_number }}"'" } ] }' > bundle-spec.json
jf release-bundle-create ${{ vars.BUNDLE_NAME }} ${{ github.run_number }} --signing-key PGP-RSA-2048 --spec bundle-spec.json --sync=true
NAME_LINK=${{ vars.ARTIFACTORY_URL }}'/ui/artifactory/lifecycle/?bundleName='${{ vars.BUNDLE_NAME }}'&bundleToFlash='${{ vars.BUNDLE_NAME }}'&repositoryKey=example-project-release-bundles-v2&activeKanbanTab=promotion'
VER_LINK=${{ vars.ARTIFACTORY_URL }}'/ui/artifactory/lifecycle/?bundleName='${{ vars.BUNDLE_NAME }}'&bundleToFlash='${{ vars.BUNDLE_NAME }}'&releaseBundleVersion='${{ github.run_number }}'&repositoryKey=example-project-release-bundles-v2&activeVersionTab=Version%20Timeline&activeKanbanTab=promotion'
echo ' Release bundle ['${{ vars.BUNDLE_NAME }}']('${NAME_LINK}'):['${{ github.run_number }}']('${VER_LINK}') created' >> $GITHUB_STEP_SUMMARY
Note
For more information about using the JFrog CLI to create a Release Bundle, see https://docs.jfrog-applications.jfrog.io/jfrog-applications/jfrog-cli/cli-for-jfrog-artifactory/release-lifecycle-management.
This section of build.yaml creates signed evidence about the Release Bundle.
- name: Evidence on release-bundle v2
run: |
echo '{ "actor": "${{ github.actor }}", "date": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'" }' > rbv2_evidence.json
JF_LINK=${{ vars.ARTIFACTORY_URL }}'/ui/artifactory/lifecycle/?bundleName='${{ vars.BUNDLE_NAME }}'&bundleToFlash='${{ vars.BUNDLE_NAME }}'&releaseBundleVersion='${{ github.run_number }}'&repositoryKey=release-bundles-v2&activeVersionTab=Version%20Timeline&activeKanbanTab=promotion'
echo 'Test on Release bundle ['${{ vars.BUNDLE_NAME }}':'${{ github.run_number }}']('${JF_LINK}') success' >> $GITHUB_STEP_SUMMARY
jf evd create --release-bundle ${{ vars.BUNDLE_NAME }} --release-bundle-version ${{ github.run_number }} \
--predicate ./rbv2_evidence.json --predicate-type https://jfrog.com/evidence/rbv2-signature/v1 \
--key "${{ secrets.PRIVATE_KEY }}"
echo ' Evidence attached: integration-test ' >> $GITHUB_STEP_SUMMARY