Skip to main content

jfrog-evidence

info

This promotion step is only available in Kargo on the Akuity Platform, versions v1.7 and above.

The jfrog-evidence promotion step provides comprehensive integration with JFrog Artifactory's evidence management capabilities, allowing you to create, verify, and delete evidence for artifacts. This enables secure attestation and verification of your promotion workflows through cryptographically signed evidence that can track artifact provenance, test results, and compliance status.

This promotion step supports three main operations: creating evidence with digital signatures, querying and verifying existing evidence, and cleaning up evidence when needed. It's particularly valuable for maintaining supply chain security and compliance in enterprise environments.

For more information about JFrog's Evidence feature, see the official JFrog Evidence documentation.

Credentials Configuration

All JFrog Evidence operations require proper authentication credentials stored in a Kubernetes Secret.

NameTypeRequiredDescription
credentials.secretNamestringYName of the Secret containing the JFrog credentials in the project namespace.

The referenced Secret should contain the following keys:

  • url: The URL of your JFrog Artifactory instance (e.g., https://yourcompany.jfrog.io)
  • accessToken: Your JFrog access token with appropriate permissions for evidence management
  • privateKey (optional): Private key in PEM format for signing evidence. This key can be stored in a separate secret and referenced when required.

Evidence Management

Create Evidence

Creates cryptographically signed kargo promotion evidence for an artifact in JFrog Artifactory.

Configuration

NameTypeRequiredDescription
create.privateKeystringYThe private key to sign the evidence.
create.packageRepostringYThe package repository name of the artifact.
create.packageNamestringYThe package name of the artifact inside the repository.
create.packageVersionstringYThe package version of the artifact.
create.promotionStatusstringYStatus indicating the promotion state. Valid values: Pending, Running, Succeeded, Failed, Errored, Aborted.
create.privateKeyAliasstringNName for the public key created from the private key. Used for verification. If omitted, verification is skipped.
create.metadataobjectNJSON metadata that will be stored inside the evidence predicate.

Output

NameTypeDescription
namestringThe name/identifier of the created evidence for later reference.

The Kargo promotion evidence predicate stored in the artifact will have a predicate type of https://akuity.io/evidence/promotion/v1 and will look something like this:

{
"project": "my-project",
"stage": "production",
"promotion": "production.01k22r0jkhfgheh57ywp9t15ya.67018d8",
"actor": "admin@company.com",
"freightName": "abc123def456",
"metadata": {
"env": "production",
"result": "pass",
"testSuite": "integration-tests",
"coverage": "85%"
},
"promotionStatus": "Succeeded",
"promotionTimestamp": 1672531200
}

Example

This example creates evidence for a successful test promotion with custom metadata.

steps:
- uses: jfrog-evidence
as: create-test-evidence
config:
credentials:
secretName: jfrog-credentials
create:
privateKey: ${{ secret("jfrog-credentials").privateKey }}
privateKeyAlias: "test-evidence-key"
packageRepo: ${{ vars.packageRepo }}
packageName: ${{ vars.packageName }}
packageVersion: ${{ imageFrom(vars.packageRegistry+"/"+vars.packageRepo+"/"+vars.packageName).Tag }}
metadata:
env: "${{ ctx.stage }}"
result: "pass"
testSuite: "integration-tests"
coverage: "85%"
promotionStatus: "Succeeded"

Delete Evidence

Removes specific evidence from an artifact in JFrog Artifactory. This is typically used as a cleanup step in conjunction with the create step when a promotion fails.

Configuration

NameTypeRequiredDescription
delete.packageRepostringYThe package repository name of the artifact.
delete.packageNamestringYThe package name of the artifact inside the repository.
delete.packageVersionstringYThe package version of the artifact.
delete.evidenceNamestringYEvidence name/identifier to delete.

Output

This step does not produce any output.

Example

This example deletes evidence when a promotion fails, using the evidence name from a previous step.

steps:
- uses: jfrog-evidence
as: cleanup-failed-evidence
if: ${{ failure() && status('create-test-evidence') == 'Succeeded' }}
config:
credentials:
secretName: jfrog-credentials
delete:
packageRepo: ${{ vars.packageRepo }}
packageName: ${{ vars.packageName }}
packageVersion: ${{ imageFrom(vars.packageRegistry+"/"+vars.packageRepo+"/"+vars.packageName).Tag }}
evidenceName: ${{ outputs['create-test-evidence'].name }}

Process Evidence (Query and Verify)

Queries for existing evidence and verifies its authenticity and content. This operation is commonly used as a promotion gating mechanism to ensure that only artifacts with valid evidence and compliance status proceed through the deployment pipeline. This step can also extract data from the queried evidence as step outputs, which can then be used as inputs in subsequent steps.

Configuration

NameTypeRequiredDescription
process.query.packageRepostringYThe package repository name of the artifact.
process.query.packageNamestringYThe package name of the artifact inside the repository.
process.query.packageVersionstringYThe package version of the artifact.
process.query.evidenceNameRegexstringN*Regular expression to match evidence names. *Either this or predicateType is required.
process.query.predicateTypestringN*The predicate type to query for. *Either this or evidenceNameRegex is required.
process.verify.verifyExpressionstringN**Expr expression to evaluate on the predicate. Must return boolean. **One of the verify options is required.
process.verify.localKeysarrayN**Local private/public keys for signature verification. **One of the verify options is required.
process.verify.useArtifactoryKeysbooleanN**Use keys present in evidence data for verification. **One of the verify options is required.
process.outputsarrayNOutput configurations to extract data from evidence results.
process.outputs[].namestringYName of the output variable.
process.outputs[].expressionstringYExpr expression to extract data from evidence query results.

Available Data for Expressions

Both verification expressions (verifyExpression) and output expressions (outputs[].expression) have access to the following data structure:

evidence:
predicate: <object> # The evidence predicate data (varies by predicate type)
predicateType: <string> # The predicate type of the evidence
createdAt: <string> # ISO timestamp when the evidence was created
name: <string> # The name/identifier of the evidence
verified: <boolean> # Whether the evidence signature was verified
downloadPath: <string> # The download path for the evidence
signingKey:
alias: <string> # The alias of the signing key
publicKey: <string> # The public key used for signing

Output

The outputs are dynamic based on the process.outputs configuration. Each output creates a variable with the specified name containing the result of the expression evaluation.

Example

This example verifies test evidence and extracts relevant information for subsequent steps.

steps:
- uses: jfrog-evidence
as: verify-test-evidence
config:
credentials:
secretName: jfrog-credentials
process:
query:
packageRepo: ${{ vars.packageRepo }}
packageName: ${{ vars.packageName }}
packageVersion: ${{ imageFrom(vars.packageRegistry+"/"+vars.packageRepo+"/"+vars.packageName).Tag }}
predicateType: "https://in-toto.io/attestation/test-result/v0.1"
evidenceNameRegex: ".*-test-result-.*"
verify:
localKeys:
- ${{ secret("jfrog-credentials").privateKey }}
useArtifactoryKeys: true
verifyExpression: |
evidence.predicate.result == "pass" &&
evidence.predicate.coverage >= 80
outputs:
- name: testResult
expression: evidence.predicate.result
- name: coverage
expression: evidence.predicate.coverage
- name: createdAt
expression: evidence.createdAt
- name: environment
expression: evidence.predicate.metadata.env

# Use the extracted values in subsequent steps
- uses: http
config:
method: POST
url: https://api.slack.com/api/chat.postMessage
headers:
- name: Authorization
value: "Bearer ${{ secret('slack-token').token }}"
- name: Content-Type
value: application/json
body: |
${{ quote({
"channel": "#deployments",
"text": "Test evidence verified! Result: " + outputs['verify-test-evidence'].testResult +
", Coverage: " + string(outputs['verify-test-evidence'].coverage) + "%" +
", Environment: " + outputs['verify-test-evidence'].environment
}) }}

Trusted Release Evidence Verification

JFrog Trusted Release evidence is a special type of evidence generated exclusively for the release stage. This evidence creates a distinct certification artifact that verifies an application version has been officially released with policy evaluation. It is possible to validate this type of evidence with Kargo and use it as a promotion gating mechanism for promotions in production environments.

Configuration

This example demonstrates verifying trusted release evidence before production deployment. The verifyExpression can be modified according to your requirements.

steps:
- uses: jfrog-evidence
as: verify-trusted-release
config:
credentials:
secretName: jfrog-credentials
process:
query:
packageRepo: ${{ vars.packageRepo }}
packageName: ${{ vars.packageName }}
packageVersion: ${{ imageFrom(vars.packageRegistry+"/"+vars.packageRepo+"/"+vars.packageName).Tag }}
predicateType: "https://jfrog.com/evidence/release_certify/v1"
verify:
localKeys:
- ${{ secret("jfrog-credentials").privateKey }}
useArtifactoryKeys: true
verifyExpression: |
evidence.predicate.release_type == "Trusted Release" &&
len(evidence.predicate.policy_results) > 0 &&
evidence.predicate.outcome == "passed"
outputs:
- name: releaseType
expression: evidence.predicate.release_type
- name: releaseTimestamp
expression: evidence.predicate.evaluated_at

# Only proceed with production deployment if trusted release is verified in previous step
# Update the Argo CD Application directly. Not ideal for practical purposes.
- uses: argocd-update
config:
apps:
- name: production-app
namespace: argocd
sources:
- repoURL: https://github.com/company/app-config.git
kustomize:
images:
- repoURL: ${{ vars.packageRegistry }}/{{ vars.packageRepo }}/{{ vars.packageName }}
tag: ${{ imageFrom(vars.packageRegistry+"/"+vars.packageRepo+"/"+vars.packageName).Tag }}

This verification ensures that:

  • The evidence is for a "Trusted Release"
  • Policy evaluations were performed (policy_results is not empty). You can perform more complex checks on the policy_results according to your requirements.
  • All compliance checks passed
  • The evidence signature is valid