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

<a id="component-eol-banner"></a>

You are viewing **Develocity Provenance Governor 1.5**. To view the latest available version of the docs, see [1.7](https://docs.gradle.com/develocity/provenance-governor/1.7/quickstart/).

# Quickstart

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

Get Develocity Provenance Governor running locally in under 10 minutes using k3d and basic HTTP ingress.

> [!NOTE]
> Prerequisites: kubectl installed (Install kubectl) macOS or Linux (for brew/bash commands) Your Develocity license file saved as develocity.license in your current directory The manifest.yaml file downloaded

> [!TIP]
> This quickstart creates a local, non-production environment with HTTP-only access for testing. For production deployments, see the complete Deployment Guide.

<a id="step-1-create-a-local-kubernetes-cluster"></a>

## Step 1: Create a Local Kubernetes Cluster

Install k3d and create a cluster with port 80 exposed for HTTP traffic.

```bash
brew install k3d
k3d cluster create --port "80:80@loadbalancer"
```

Expected output: `Cluster 'k3s-default' created successfully!`

<a id="step-2-create-the-namespace"></a>

## Step 2: Create the Namespace

Create a dedicated namespace for the Develocity Provenance Governor components. The manifest references this namespace but doesn’t create it.

```bash
kubectl create namespace develocity-provenance-governor
```

<a id="step-3-configure-ingress"></a>

## Step 3: Configure Ingress

Set up basic HTTP ingress using `nip.io` for local DNS resolution. This allows you to access the service at `api.127.0.0.1.nip.io`.

```bash
kubectl --namespace develocity-provenance-governor apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: api.127.0.0.1.nip.io
spec:
  rules:
    - host: api.127.0.0.1.nip.io
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-http
                port:
                  number: 80
EOF
```

> [!NOTE]
> nip.io is a wildcard DNS service that maps 127.0.0.1.nip.io to 127.0.0.1, allowing you to use a domain name for local testing without editing /etc/hosts.

<a id="step-4-configure-image-pull-secret"></a>

## Step 4: Configure Image Pull Secret

Create a secret that allows Kubernetes to pull the Develocity Provenance Governor image from the Gradle registry. Your license file is used for authentication.

```bash
kubectl create secret docker-registry registry-secret \
  --namespace develocity-provenance-governor \
  --docker-server=https://registry.gradle.com \
  --docker-username=user \
  --docker-password=$(cat ./develocity.license)
```

> [!TIP]
> The user: prefix in the command is for clarity and is ignored by the registry.

🚀 Alternative: Use local image with k3d (skip registry secret)

If you prefer to avoid creating a registry secret, you can load the image directly into k3d:

```bash
# First, pull the image locally using your license for authentication
docker login registry.gradle.com -p "ge:$(cat ./develocity.license)"
docker pull registry.gradle.com/develocity/provenance-governor:<version>

# Load the image into k3d
k3d image import registry.gradle.com/develocity/provenance-governor:<version>

# Then modify manifest.yaml to remove imagePullSecrets before applying in Step 6
```

**Note:** You’ll need to edit `manifest.yaml` and remove the `imagePullSecrets` section from the Deployment before applying it.

This approach is faster and simpler for local development but requires manual steps that aren’t needed with the registry secret approach.

<a id="step-5-create-license-secret"></a>

## Step 5: Create License Secret

Store your license file as a Kubernetes secret so the application can access it.

```bash
kubectl create secret generic license \
  --namespace develocity-provenance-governor \
  --from-file=develocity.license=./develocity.license
```

<a id="step-6-deploy-the-application"></a>

## Step 6: Deploy the Application

Apply the manifest to deploy Develocity Provenance Governor and its components.

```bash
kubectl --namespace develocity-provenance-governor apply -f manifest.yaml
```

<a id="step-7-wait-for-deployment"></a>

## Step 7: Wait for Deployment

Wait for the deployment to complete (this may take 1-2 minutes).

```bash
kubectl rollout status deployment/api --namespace develocity-provenance-governor --timeout=90s
```

Expected output: `deployment "api" successfully rolled out`

<a id="step-8-verify-the-installation"></a>

## Step 8: Verify the Installation

Check the application logs to confirm it started successfully.

```bash
kubectl logs deployment/api --namespace develocity-provenance-governor | head -n 50
```

Look for log messages indicating successful startup (no error messages).

<a id="step-9-test-the-endpoint"></a>

## Step 9: Test the Endpoint

Verify the service is accessible. You should receive a `401 Unauthorized` response since authentication isn’t configured yet.

```bash
curl -i api.127.0.0.1.nip.io
```

Expected output:

```text
HTTP/1.1 401 Unauthorized
...
```

> [!TIP]
> A 401 Unauthorized response means the service is running correctly! You just need to configure authentication in the next steps.

<a id="step-10-configure-attestation-storage"></a>

## Step 10: Configure Attestation Storage

Develocity Provenance Governor requires an attestation store (S3 or Artifactory) to function. For this quickstart, we will deploy LocalStack to simulate an S3 bucket within the cluster.

**Deploy LocalStack and expose it:**

```
kubectl create deployment localstack --image=localstack/localstack:3.0.0 --port=4566 -n develocity-provenance-governor
kubectl expose deployment localstack --port=4566 --name=localstack -n develocity-provenance-governor
kubectl rollout status deployment/localstack -n develocity-provenance-governor --timeout=120s
```

**Create an S3 bucket named 'dpg-bucket':**

```
kubectl run aws-cli --image=amazon/aws-cli --restart=Never -n develocity-provenance-governor \
  --env="AWS_ACCESS_KEY_ID=test" --env="AWS_SECRET_ACCESS_KEY=test" --env="AWS_REGION=us-east-1" \
  -- s3 mb s3://dpg-bucket --endpoint-url=http://localstack:4566
```

<a id="step-11-configure-policies-and-properties"></a>

## Step 11: Configure Policies and Properties

Now configure the application to use the S3 bucket and define the basic policies.

**Create placeholder Secrets/ConfigMaps:**

```
kubectl create secret generic secrets --namespace develocity-provenance-governor --dry-run=client -o yaml | kubectl apply -f - || true
kubectl create configmap properties --namespace develocity-provenance-governor --dry-run=client -o yaml | kubectl apply -f - || true
kubectl create configmap policies --namespace develocity-provenance-governor --dry-run=client -o yaml | kubectl apply -f - || true
```

**Add Access Control (including S3 access) and Build policies to the policies ConfigMap:**

```
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: policies
  namespace: develocity-provenance-governor
data:
  access-control.yaml: |
    apiVersion: policy.gradle.com/v1
    kind: AccessControl
    metadata:
      name: admin-full-access
    spec:
      identityMatchingStrategy:
        withBasicIdentity:
          - withName: "admin"
      canPerform:
        - publish-attestations
        - publish-policy-scans
        - read-attestations
      withResources:
        - "*:*/*"
        - "s3:local-s3/*"
        - "pkg:maven/*"

  scan-build.yaml: |
    apiVersion: policy.gradle.com/v1
    kind: PolicyScanDefinition
    metadata:
      name: build
    spec:
      description: Validate the software package against the build gate policies.
      policy-selector:
        match-labels:
          gate: build

  policy-require-build-tool.yaml: |
    apiVersion: policy.gradle.com/v1
    kind: AttestationsExist
    metadata:
      name: require-build-tool
      labels:
        gate: build
    spec:
      description: Ensure Build Tool attestation exists
      remediation: Fix build
      matchingStrategy: must-match
      expectedPredicates:
        - https://gradle.com/attestation/build-tool/v1
EOF
```

**Configure Develocity and S3 Properties (Replace https://develocity.example.com with your instance URL):**

```
kubectl patch configmap properties --namespace develocity-provenance-governor --type=merge -p '{"data":{
  "develocity.instances.main.uri": "https://develocity.example.com",
  "s3.instances.local-s3.region": "us-east-1",
  "s3.instances.local-s3.endpoint": "http://localstack:4566",
  "s3.instances.local-s3.bucket-name": "dpg-bucket",
  "s3.instances.local-s3.path-style-access": "true"
}}'
```

**Configure Secrets (Replace YOUR_DEVELOCITY_ACCESS_KEY with your actual key):**

```
kubectl patch secret secrets --namespace develocity-provenance-governor --type=merge -p '{"stringData":{
  "develocity.instances.main.access-key": "YOUR_DEVELOCITY_ACCESS_KEY",
  "s3.instances.local-s3.access-key-id": "test",
  "s3.instances.local-s3.secret-access-key": "test",
  "basic.identities.admin": "\{noop\}admin"
}}'
```

**Restart the deployment to apply configuration:**

```
kubectl rollout restart deployment/api --namespace develocity-provenance-governor
kubectl rollout status deployment/api --namespace develocity-provenance-governor --timeout=90s
```

<a id="step-12-test-attestation-publishing-and-build-gate-verification"></a>

## Step 12: Test Attestation Publishing and Build Gate Verification

Now, publish an attestation and run the `build` Policy Scan™. This simulates a "Build Gate" check. If the scan passes (meaning the `require-build-tool` policy is satisfied), a Verification Summary Attestation (VSA) will be automatically generated and published.

Replace `YOUR_BUILD_SCAN_ID` with a valid Build Scan ID from your Develocity instance (e.g., `3skbdg5fgcgha`). The `SHA256_DIGEST` can be any 64-character hex string for this test, but you must use the same value in both the attestation publishing and Policy Scan steps below.

**Publish an attestation:**

```
SHA256_DIGEST="73f482a2296dcc654c380979aae3916a1925ff906b1c43a0659f97fd56e44497" # Placeholder
BUILD_SCAN_ID="YOUR_BUILD_SCAN_ID" # Replace with a real ID like 3skbdg5fgcgha
DPG_URL="http://api.127.0.0.1.nip.io" # Update port if you used a different one

curl -v -u admin:admin \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "sha256=$SHA256_DIGEST" \
  -d "repositoryUrl=repo.example.com/maven2" \
  -d "buildScan.ids=$BUILD_SCAN_ID" \
  "$DPG_URL/packages/maven/com.example/acme-app/1.0.0/attestations"
```

Expected output: Look for `HTTP/1.1 200 OK` and a JSON response detailing `successes` for attestation storage.

**Run the 'build' Policy Scan:**

```
SHA256_DIGEST="73f482a2296dcc654c380979aae3916a1925ff906b1c43a0659f97fd56e44497" # Must match above
DPG_URL="http://api.127.0.0.1.nip.io" # Update port if you used a different one

# Run the 'build' policy scan.
# If successful, this will generate a VSA confirming the package passed the build gate.
POLICY_SCAN_RESULT=$(curl -v -u admin:admin \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "sha256=$SHA256_DIGEST" \
  -d "repositoryUrl=repo.example.com/maven2" \
  "$DPG_URL/packages/maven/com.example/acme-app/1.0.0/policy-scans/build")

echo "$POLICY_SCAN_RESULT" | jq .
```

Expected output: The JSON response will include a `PolicyScanDefinition` result. If the scan passed, it will contain an `attestationUri` pointing to the newly generated Verification Summary Attestation (VSA).

**Retrieve the generated VSA (optional):**

```
# Replace VSA_ATTESTATION_URI with the actual URI from the previous step's output (e.g., /packages/maven/.../attestations/s3:local-s3/uuid)
# Make sure to include the full path, e.g., /packages/maven/com.example/acme-app/1.0.0/sha256:73f482a2296dcc654c380979aae3916a1925ff906b1c43a0659f97fd56e44497/attestations/s3:local-s3/fe618e2e-eb39-5ae7-9ad7-da5343397858
VSA_ATTESTATION_URI="/packages/maven/com.example/acme-app/1.0.0/sha256:73f482a2296dcc654c380979aae3916a1925ff906b1c43a0659f97fd56e44497/attestations/s3:local-s3/fe618e2e-eb39-5ae7-9ad7-da5343397858"
DPG_URL="http://api.127.0.0.1.nip.io"

curl -v -u admin:admin \
  -H "Accept: application/json" \
  "$DPG_URL$VSA_ATTESTATION_URI" | jq .
```

Expected output: A JSON object representing the DSSE envelope of the VSA.

<a id="success"></a>

## 🎉 Success!

Your Develocity Provenance Governor instance is now running locally and configured with basic policies.

<a id="whats-next"></a>

## What’s Next?

<a id="essential-configuration"></a>

### Essential Configuration

To make your instance production-ready, configure these key features:

  
| Feature | Description | Guide |
| --- | --- | --- |
| 🔐 Authentication | Add Basic Auth or OIDC to secure your instance | Configure Auth |
| 🔑 Signing Keys | Enable cryptographic signing of attestations | Setup Keys |
| 📋 Policies | Define access control and verification rules | Create Policies |
| 🔗 Integrations | Connect to Develocity and Artifactory instances | Develocity / Artifactory |
| 🔒 HTTPS/TLS | Secure communication with TLS certificates | Setup TLS |

<a id="recommended-path"></a>

### Recommended Path

> [!TIP]
> New to Develocity Provenance Governor? Follow this order: Read the concepts - Understand how components work together Add authentication - Secure your instance before connecting other services Configure integrations - Connect to your Develocity and artifact repositories Set up signing - Enable attestation signatures for verification Define policies - Create rules for access control and compliance

<a id="need-help"></a>

### Need Help?

*   **Full Documentation**: [Complete Deployment Guide](https://docs.gradle.com/develocity/provenance-governor/1.5/setup-deploy/)
    
*   **Troubleshooting**: Check logs with `kubectl logs deployment/api -n develocity-provenance-governor`
    
*   **Clean Up**: Delete the cluster with `k3d cluster delete k3s-default`