---
component: provenance-governor
version: "1.7"
slug: provenance-governor/evaluating-policies
canonical_url: "https://docs.gradle.com/develocity/provenance-governor/1.7/evaluating-policies/"
title: "Evaluating Policies"
description: "Explains how policy evaluation and Policy Scan(TM) evaluations work in Develocity Provenance Governor."
keywords:
  - "attestation"
  - "supply chain"
  - "API"
status: current
---

<!-- llms-index: https://docs.gradle.com/develocity/llms.txt -->

# Evaluating Policies

<a id="preamble"></a>

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:

1.  After building and publishing a package
    
2.  After attestations are published to the attestation store
    
3.  Before promoting to the next environment
    
4.  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.

<a id="policy-scan-strategies"></a>

## Policy Scan™ Strategies

Choose a Policy Scan organization strategy:

  
| Strategy | Use When | Example Scans |
| --- | --- | --- |
| By Environment | Different rules per deployment stage | dev-scan, staging-scan, prod-scan |
| By Package Type | Different rules per artifact type | oci-scan, maven-scan |
| By Team | Different teams have different rules | frontend-scan, backend-scan |
| By Compliance | Regulatory requirements vary | soc-scan, hipaa-scan, pci-scan |

Most organizations combine strategies, for example: `prod-backend-scan` or `staging-frontend-scan`.

<a id="verification-summary-attestation"></a>

## 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](https://slsa.dev/spec/v1.2/verification_summary) and provides cryptographically verifiable evidence of policy compliance.

<a id="how-vsas-are-generated"></a>

### How VSAs Are Generated

For each Policy Scan execution:

1.  **Policies are evaluated** against the artifact’s attestations
    
2.  **Results are collected** — all policy evaluation results (`satisfied`, `unsatisfied`, `not-applicable`)
    
3.  **VSA is created** with:
    
    *   Verification result (`PASSED` if all applicable policies satisfied, `FAILED` otherwise)
        
    *   Reference to the Policy Scan Definition used
        
    *   List of input attestations that were evaluated
        
    *   Timestamp of verification
        
    *   Verifier information (Develocity Provenance Governor instance)
        
    
4.  **VSA is signed** using the configured signing keys
    
5.  **VSA is published** to all configured attestation stores
    

<a id="vsa-storage-and-retrieval"></a>

### 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:

```shell
curl --request GET \
  --url https://provenance-governor.example.com/packages/maven/com.example/acme-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](https://slsa.dev/verification_summary/v1)`. See the [Verification Summary Predicate Reference](https://docs.gradle.com/develocity/provenance-governor/1.7/attestation-verification-summary/) for the complete structure.

<a id="vsa-signing-configuration"></a>

### 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.

<a id="failure-handling"></a>

### 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:

1.  **Signing keys are configured** — VSAs require signing keys for production use
    
2.  **Write permissions** — The service account must have write access to attestation stores
    
3.  **Storage connectivity** — Verify network access to S3/Artifactory instances
    
4.  **Logs** — Check application logs for VSA publication errors
    

<a id="dynamic-attestation-insights"></a>

## 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.

<a id="how-dynamic-insights-work"></a>

### How Dynamic Insights Work

During a Policy Scan:

1.  **Attestation Retrieval**: Static attestations (e.g., `ResolvedDependencies`) are retrieved from the attestation store.
    
2.  **Insight Resolution**: For supported attestation types, Develocity Provenance Governor triggers a resolution request to external providers (e.g., OSI, OSV).
    
3.  **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.
    
4.  **Insight Evaluation**: The new insight attestations are immediately merged into the current evaluation loop and processed by applicable policies.
    
5.  **Traceability**: All evaluated insights are automatically included in the `inputAttestations` list of the final **Verification Summary Attestation**.
    

<a id="store-affinity"></a>

### 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.

> [!IMPORTANT]
> 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.

> [!IMPORTANT]
> 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 AccessControl policies are configured to allow the authenticated identity to write to the repository where the artifact’s attestations are stored. If the user only has read access, the Policy Scan will fail to publish the VSA (but will still return policy evaluation results).

<a id="policyscandefinition"></a>

## 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.

**Example: PolicyScanDefinition:**

```
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`.

<a id="example-build-gate-scenario"></a>

## 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.

1\. Label Policies

Ensure all relevant policies are labeled with `policy.my-corp.com/gate: build`. For example:

```yaml
apiVersion: policy.gradle.com/v1
kind: BuildTool
metadata:
  name: require-gradle
  labels:
    policy.my-corp.com/gate: build
spec:
  # ... policy details ...
```

2\. Define Policy Scan

Create a PolicyScanDefinition that selects these policies.

```yaml
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
```

3\. Evaluate

Trigger the Policy Scan via the API to validate the package against the build gate requirements:

```shell
curl --request POST \
  --url https://provenance-governor.example.com/packages/maven/com.example/acme-app/1.0.0/policy-scans/build-gate \
  --header 'authorization: Basic ...' \
  --header 'content-type: application/json' \
  --data '{ ... }'
```

<a id="understanding-policy-scan-results"></a>

## 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.
    

> [!TIP]
> Use Accept: application/x-ndjson to stream scan results directly into tools like jq in your pipeline for fast feedback on unsatisfied policies.

<a id="http-status-codes"></a>

### HTTP Status Codes

 
| Status Code | Meaning |
| --- | --- |
| 200 OK | Policy Scan completed. Check status field: SUCCESS means all policies passed, FAILURE means one or more policies failed. |
| 400 Bad Request | Invalid request (missing required fields, invalid package URL format, etc.). |
| 401 Unauthorized | Authentication credentials missing or invalid. |
| 403 Forbidden | Authenticated but not authorized to scan this package. |
| 404 Not Found | Policy Scan definition not found, or package/attestations not found. |
| 500 Internal Server Error | Server error during policy evaluation. |

<a id="interpreting-results"></a>

### 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`.

```json
[
  {
    "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/acme-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`.

```json
[
  {
    "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/acme-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"
    }
  }
]
```