Evaluating Policies
You evaluate policies by running Policy Scan™ evaluations against a software package. A Policy Scan is defined declaratively in YAML using a PolicyScanDefinition and is stored alongside your policies.
Policy Scan evaluations execute during your CI/CD pipeline, typically:
-
After building and publishing a package
-
After attestations are published to Artifactory
-
Before promoting to the next environment
-
Before deploying to production
The scan results determine whether the pipeline proceeds or fails based on policy compliance.
When you execute a Policy Scan, Develocity Provenance Governor retrieves the relevant policies based on the label selectors defined in the PolicyScanDefinition. It then evaluates each policy against the attestations associated with the specified software package.
Policy Scan evaluations help you create reusable, targeted validation strategies by grouping related policies together.
Policy Scan™ Strategies
Choose a Policy Scan organization strategy:
| Strategy | Use When | Example Scans |
|---|---|---|
By Environment |
Different rules per deployment stage |
|
By Package Type |
Different rules per artifact type |
|
By Team |
Different teams have different rules |
|
By Compliance |
Regulatory requirements vary |
|
Most organizations combine strategies, for example: prod-backend-scan or staging-frontend-scan.
Verification Summary Attestation
When you execute a Policy Scan, Develocity Provenance Governor automatically generates and publishes a Verification Summary Attestation (VSA). This VSA serves as a durable, signed record that the specific artifact was verified against the specific policy at a specific time.
The VSA follows the SLSA Verification Summary v1.2 specification and provides cryptographically verifiable evidence of policy compliance.
How VSAs Are Generated
For each Policy Scan execution:
-
Policies are evaluated against the artifact’s attestations
-
Results are collected — all policy evaluation results (
satisfied,unsatisfied,not-applicable) -
VSA is created with:
-
Verification result (
PASSEDif all applicable policies satisfied,FAILEDotherwise) -
Reference to the Policy Scan Definition used
-
List of input attestations that were evaluated
-
Timestamp of verification
-
Verifier information (Develocity Provenance Governor instance)
-
-
VSA is signed using the configured signing keys
-
VSA is published to all configured attestation stores
VSA Storage and Retrieval
Where VSAs Are Stored:
The VSA is published to all attestation store instances configured for your deployment (Artifactory, S3, or both). The VSA is stored alongside the artifact’s other attestations using the same storage hierarchy.
Retrieving a VSA:
You can retrieve VSAs using the standard "Fetch Attestation by ID" endpoint:
curl --request GET \
--url https://provenance-governor.example.com/packages/maven/com.example/my-app/1.0.0/sha256:abc.../attestations/s3:prod/vsa-uuid \
--header 'authorization: Basic ***********=' \
--header 'accept: application/json'
The VSA identifier and storage location are logged during Policy Scan execution.
VSA Structure:
The returned VSA is a DSSE envelope containing an in-toto Statement with predicate type https://slsa.dev/verification_summary/v1. See the Verification Summary Predicate Reference for the complete structure.
VSA Signing Configuration
VSAs are signed using the same signing keys configured for other attestations. Ensure you have configured signing keys in your application configuration.
Without signing keys configured, VSAs will still be generated but will not be cryptographically signed.
Failure Handling
VSA Publication Failures:
If VSA publication to any attestation store fails:
-
The error is logged but does not fail the Policy Scan
-
Policy Scan results are still returned to the caller
-
The Policy Scan continues to return success/failure based on policy evaluation, not VSA publication
This design ensures that policy enforcement is not disrupted by transient storage issues.
Troubleshooting VSA Publication:
If VSAs are not being published, check:
-
Signing keys are configured — VSAs require signing keys for production use
-
Write permissions — The service account must have write access to attestation stores
-
Storage connectivity — Verify network access to S3/Artifactory instances
-
Logs — Check application logs for VSA publication errors
Dynamic Attestation Insights
Develocity Provenance Governor automatically enriches Policy Scan evaluations by resolving static attestations into live, dynamic insights. This allows policies to evaluate up-to-date information — such as current vulnerability data or version hygiene — that may have changed since the original attestation was created.
How Dynamic Insights Work
During a Policy Scan:
-
Attestation Retrieval: Static attestations (e.g.,
ResolvedDependencies) are retrieved from the attestation store. -
Insight Resolution: For supported attestation types, Develocity Provenance Governor triggers a resolution request to external providers (e.g., OSI, OSV).
-
Insight Publication: The resolved insights are signed as new in-toto attestations and persisted back to the same store instance (Store Affinity) that provided the source attestation.
-
Insight Evaluation: The new insight attestations are immediately merged into the current evaluation loop and processed by applicable policies.
-
Traceability: All evaluated insights are automatically included in the
inputAttestationslist of the final Verification Summary Attestation.
Store Affinity
To ensure data locality and consistent access control, Develocity Provenance Governor maintains Store Affinity for dynamic insights. Insights generated from an attestation stored in a specific Artifactory or S3 instance will always be published back to that same instance.
|
Write Permissions for Insights
Similar to VSAs, the resolution and publication of dynamic insights require the service to have write permissions to the attestation store. If publication fails, a warning is logged, and the scan continues with the available data. |
|
Access Control for VSA Publication
Because the Policy Scan operation involves writing a new attestation (the VSA) to storage, the user or service account performing the scan must have write permissions to the target repository in the Attestation Store. Ensure your |
PolicyScanDefinition
A PolicyScanDefinition defines a PolicyScan and selects which policies to apply using label selectors. This allows grouping and targeting of policies for specific enforcement scenarios.
apiVersion: policy.gradle.com/v1
kind: PolicyScanDefinition
metadata:
name: build-gate
labels:
policy.my-corp.com/gate: build
spec:
description: Policy scan definition for the build gate
policySelector:
matchLabels:
policy.my-corp.com/gate: build
The above Policy Scan will include all policies labeled with policy.my-corp.com/gate: build.
Example: Build Gate Scenario
This example demonstrates a "Build Gate" scenario, where a set of policies are applied to an artifact. The goal is to ensure that any artifact passing this gate meets specific criteria, such as being built with a trusted build tool and having the necessary attestations.
Ensure all relevant policies are labeled with policy.my-corp.com/gate: build.
For example:
apiVersion: policy.gradle.com/v1
kind: BuildTool
metadata:
name: require-gradle
labels:
policy.my-corp.com/gate: build
spec:
# ... policy details ...
Create a PolicyScanDefinition that selects these policies.
apiVersion: policy.gradle.com/v1
kind: PolicyScanDefinition
metadata:
name: build-gate
spec:
description: Validate build standards for the build gate
policySelector:
matchLabels:
policy.my-corp.com/gate: build
Trigger the Policy Scan via the API to validate the package against the build gate requirements:
curl --request POST \
--url https://provenance-governor.example.com/packages/maven/com.example/my-app/1.0.0/policy-scans/build-gate \
--header 'authorization: Basic ...' \
--header 'content-type: application/json' \
--data '{ ... }'
Understanding Policy Scan™ Results
Policy Scan results provide detailed information about which policies passed or failed for a package.
The format of the response depends on the Accept header provided in the request:
-
application/json: The server collects all results and returns them as a single JSON array. This is the default behavior. -
application/x-ndjson: The server streams individual results as Newline Delimited JSON objects as soon as they are available. This is recommended for CI/CD pipelines to provide immediate feedback and prevent timeouts.
|
Use |
HTTP Status Codes
| Status Code | Meaning |
|---|---|
|
Policy Scan completed. Check |
|
Invalid request (missing required fields, invalid package URL format, etc.). |
|
Authentication credentials missing or invalid. |
|
Authenticated but not authorized to scan this package. |
|
Policy Scan definition not found, or package/attestations not found. |
|
Server error during policy evaluation. |
Interpreting Results
Successful Scan (All Policies Pass):
When all policies pass, the API returns an array where each PolicyScan.Result object has a status of satisfied or not-applicable.
[
{
"labels": {
"policy.my-corp.com/gate": "build"
},
"status": "satisfied",
"policyUri": "/policies/BuildTool/only-gradle-builds",
"policyDescription": "Ensure only Gradle is used as the build tool.",
"policyRemediation": "Use Gradle as the build tool. Consult migration guides if necessary.",
"attestationUri": "/packages/maven/com.example/my-app/1.0.0/sha256:73f482a2.../attestations/jfrog-artifactory:prod/maven-app-1.0.0-build-env",
"sourcedFromUri": "https://develocity.example.com/s/abcdef1234567",
"details": {
"buildTool": "Gradle",
"predicateType": "https://gradle.com/attestation/build-tool/v1"
}
}
]
Failed Scan (One or More Policies Fail):
When one or more policies fail, the API returns an array that includes PolicyScan.Result objects with a status of unsatisfied.
[
{
"labels": {
"policy.my-corp.com/gate": "build"
},
"status": "unsatisfied",
"policyUri": "/policies/ResolvedDependenciesRepositories/disallow-untrusted-repos",
"policyDescription": "Disallow untrusted Maven repositories.",
"policyRemediation": "Remove 'https://untrusted.repo.com/maven2' from your build's dependency repositories.",
"attestationUri": "/packages/maven/com.example/my-app/1.0.0/sha256:73f482a2.../attestations/jfrog-artifactory:prod/maven-app-1.0.0-deps",
"sourcedFromUri": "https://develocity.example.com/s/abcdef1234567",
"details": {
"predicateType": "https://gradle.com/attestation/resolved-dependencies-repositories/v1"
}
}
]