Deployment (Docker)


Develocity Provenance Governor is provided as a container image that can be run directly with Docker. Make sure you have the prerequisites detailed in Prerequisites before proceeding.

Looking for Kubernetes deployment? See the Kubernetes Deployment Guide.

Audience

This guide is written for a Platform / Infrastructure Engineer. It assumes:

  • Basic familiarity with Docker (containers, volumes, networks)

  • Ability to obtain a Develocity license file (develocity.license)

  • Access to a Develocity instance and an attestation storage backend (Artifactory or Amazon S3)

  • (Optional) Ability to configure a reverse proxy for TLS termination

Quickstart

Want to get started quickly with a local Docker deployment?

See the Docker Quickstart Guide for condensed setup instructions.

The quickstart will guide you through:

  • Authenticating with the container registry

  • Running Develocity Provenance Governor with Docker

  • Configuring a local S3 store and Develocity integration

  • Verifying the deployment

After completing the quickstart, return to the sections below to configure additional features like signing keys, OIDC authentication, and policies.

Deployment Flow Overview

The recommended order is:

Estimated setup time:

  • Local Docker (Quickstart): 15-30 minutes

  • Production setup with all integrations: 1-3 hours (depending on external service coordination and TLS setup)

Authenticate with the Container Registry

Log in to registry.gradle.com to pull the product image. Your Develocity license file is used for authentication.

cat ./develocity.license | docker login registry.gradle.com -u user --password-stdin

--password-stdin avoids Docker’s insecure-password warning and keeps the license out of shell history.

Create the Configuration Directory Structure

Develocity Provenance Governor reads configuration from four directories mounted into the container:

Directory Purpose Required

license/

Develocity product license file

Yes

secrets/

Sensitive values (access tokens, private keys)

Yes

properties/

Non-sensitive configuration (URIs, public keys)

Yes

policies/

Policy manifests (YAML)

No

Create the directory structure:

mkdir -p ./dpg-config/license ./dpg-config/secrets ./dpg-config/properties ./dpg-config/policies

Each directory is mounted into the container at /workspace/config/<directory-name>. Configuration files placed in these directories use the same property key formats described in the Application Configuration section.

Add the License File

Copy your Develocity license into the license directory.

cp ./develocity.license ./dpg-config/license/develocity.license

Run the Container

Start Develocity Provenance Governor with the configuration directories mounted as read-only volumes.

docker run -d \
  --name provenance-governor \
  -p 8080:8080 \
  -p 9090:9090 \
  -v "$(pwd)/dpg-config/license:/workspace/config/license:ro" \
  -v "$(pwd)/dpg-config/secrets:/workspace/config/secrets:ro" \
  -v "$(pwd)/dpg-config/properties:/workspace/config/properties:ro" \
  -v "$(pwd)/dpg-config/policies:/workspace/config/policies:ro" \
  registry.gradle.com/develocity/provenance-governor:1.6.0

Port mappings:

  • 8080 - Main API port (application traffic)

  • 9090 - Monitoring port (actuator health, readiness, liveness, and Prometheus metrics)

Verify Startup
docker logs provenance-governor 2>&1 | grep -i license
Expected log lines
Develocity license enabled, with license [...]
Started ProvenanceGovernor in ...

If startup fails:

  • Verify the license file exists at ./dpg-config/license/develocity.license

  • Check docker logs provenance-governor for detailed error messages

Verify the Deployment

Check container status
docker ps --filter name=provenance-governor

You should see the container in a Up state.

Check application logs
docker logs provenance-governor --tail=50

Look for messages indicating:

  • License loaded successfully

  • Integrations enabled (e.g., "Develocity support enabled", "Artifactory support enabled")

  • Policies loaded (if configured)

  • No error messages

Test API accessibility
curl -i http://localhost:8080

You should receive a 401 Unauthorized response, which confirms the application is running and authentication is required.

The actuator endpoints (health, readiness, liveness, prometheus) are exposed on port 9090. Develocity Provenance Governor also exposes /livez and /readyz endpoints on the main application port (8080) for health checking.

Configure Develocity Instances

Develocity Provenance Governor uses Develocity Build Scan data to generate attestations. At least one Develocity instance must be configured.

Add Develocity configuration to your properties and secrets files.

Add Develocity URI to ./dpg-config/properties/application.yml
develocity:
  instances:
    MY_INSTANCE: (1)
      uri: "https://develocity.example.com"
1 MY_INSTANCE is an identifier you choose. Use alphanumeric characters, dashes, or underscores.
Add Develocity access key to ./dpg-config/secrets/application.yml
develocity:
  instances:
    MY_INSTANCE:
      access-key: "my-access-key-for-develocity"
Restart to apply configuration
docker restart provenance-governor
Verify
docker logs provenance-governor 2>&1 | grep -i "Develocity support enabled"

Expected log:

Develocity support enabled, for instance [MY_INSTANCE:https://develocity.example.com]

Troubleshooting: Repeated Retrying [n/10] request …​ indicates connectivity or credential issues.

See Develocity Instance Configuration for advanced options.

Configure Attestation Storage

Develocity Provenance Governor requires at least one attestation storage backend. You can use Amazon S3, JFrog Artifactory, or both simultaneously.

Amazon S3

Add S3 configuration to your properties and secrets files.

Add S3 properties to ./dpg-config/properties/application.yml
s3:
  instances:
    MY_S3: (1)
      region: "us-east-1"
      bucket-name: "my-attestation-bucket"
1 MY_S3 is an identifier you choose for this S3 instance.
Add S3 credentials to ./dpg-config/secrets/application.yml
s3:
  instances:
    MY_S3:
      access-key-id: "AKIA..."
      secret-access-key: "..."

Static credentials are shown for simplicity. For production use, you can also configure IAM role assumption or use environment-based credentials by passing AWS environment variables to the container (e.g., -e AWS_ROLE_ARN=…​). See S3 Configuration for all authentication options.

JFrog Artifactory

Add Artifactory configuration to your properties and secrets files.

Add Artifactory URI to ./dpg-config/properties/application.yml
artifactory:
  instances:
    MY_ARTIFACTORY: (1)
      uri: "https://artifactory.example.com"
1 MY_ARTIFACTORY is an identifier you choose for this Artifactory instance.
Add Artifactory token to ./dpg-config/secrets/application.yml
artifactory:
  instances:
    MY_ARTIFACTORY:
      access-token: "my-access-token-for-artifactory"
Restart and verify
docker restart provenance-governor
docker logs provenance-governor 2>&1 | grep -i "support enabled"

Expected log lines (depending on which backends are configured):

Develocity support enabled, for instance [MY_INSTANCE:https://develocity.example.com]
S3 support enabled, for instance [MY_S3:...]
Artifactory support enabled, for instance [MY_ARTIFACTORY:https://artifactory.example.com]

See Attestation Storage Configuration for advanced options.

Authentication

Supported schemes:

Enable Basic Authentication

Add identities to the secrets configuration file.

Add a Basic Identity to ./dpg-config/secrets/application.yml
basic:
  identities:
    some-user: "{noop}some-pass"

Recommendation: Replace {noop} with {bcrypt} and supply a bcrypt-hashed password for production.

Restart and verify
docker restart provenance-governor
docker logs provenance-governor 2>&1 | grep -i "Basic Identity support"
Expected log line
Basic Identity support enabled, for identity [some-user]

Enable OIDC Authentication

OIDC Providers are dynamically discovered based on token issuers specified in policies. See the Policies section for examples.

Configure Signing Keys

Attestations are wrapped in a Dead Simple Signing Envelope (DSSE) signed by a key pair.

Create Ed25519 Key Pair

Recommended (128-bit security, small key sizes/signatures).

openssl genpkey -algorithm Ed25519 -out private-key.pem
openssl pkey -in private-key.pem -pubout -out public-key.pem

Add Keys to Configuration

The private key goes in secrets and the public key goes in properties.

You can add signing keys as individual files (one file per key) using the property key naming convention.

Add private key to secrets
cp private-key.pem ./dpg-config/secrets/signing.key.FRIENDLY_KEY_NAME.private-pem
Add public key to properties
cp public-key.pem ./dpg-config/properties/signing.key.FRIENDLY_KEY_NAME.public-pem

Choose a naming convention like <ORG_OR_PRODUCT>_YYYY-MM-DD for rotation clarity.

Restart and verify
docker restart provenance-governor
docker logs provenance-governor 2>&1 | grep -i "Signature support enabled"
Expected log
Signature support enabled, for key pair [name:FRIENDLY_KEY_NAME:keyid:XXXXXX:signing-algorithm:ed25519]

Key ID is a 6-character abbreviation of the SHA-256 digest of the public key.

Other Supported Algorithms

Elliptic Curve (ECDSA) and RSA are also supported. Substitute commands below; follow the same secrets/properties procedure.

Elliptic Curve (prime256v1)

openssl ecparam -name prime256v1 -genkey -noout -out ec_private.key
openssl pkcs8 -topk8 -inform PEM -in ec_private.key -outform PEM -nocrypt -out private-key.pem
openssl ec -in ec_private.key -pubout -out public-key.pem

Expected log algorithm: SHA256withECDSA.

RSA (2048)

openssl genrsa -out private-key.pem 2048
openssl rsa -in private-key.pem -pubout -out public-key.pem

Expected log algorithm: SHA256withRSA.

Policies

Policies are YAML documents stored as files in the policies directory. Each file should end with .yaml.

Access Control Policies

Define who can do what on which resources.

identityMatchingStrategy supported:

  • withBasicIdentity — must match a key under basic.identities.<NAME> in secrets

  • withOidc — relies on issuer discovery; ensure network accessibility

canPerform supported actions:

  • publish-attestations - publish DSSE-wrapped attestations to an Attestation Store (e.g., Artifactory)

  • publish-policy-scans - publish Policy Scan™ results to an Attestation Store

withResources supported patterns:

  • pkg:pkg-type/pkg-namespace/pkg-name@pkg-version - specific Package URL pattern to match or use wildcards:

    • pkg:maven// - all Maven packages (both namespace and artifact name wildcarded)

    • pkg:oci// - all OCI packages (container images)

    • pkg:maven/org.example/@ - all Maven packages in org.example namespace and any version

    • pkg:maven/org.example/my-app@1.0.0 - specific Maven package

    • pkg:oci/image-name@v1* - specific OCI image with wildcard version

  • dv:REPLACE_WITH_DV_INSTANCE_NAME/* - allow reading build scans from the Develocity instance to source data for attestations.

  • af:REPLACE_WITH_ARTIFACTORY_INSTANCE_NAME/ - allow publishing attestations to the Artifactory instance. Replace the trailing with a repository name to restrict access further.

  • s3:REPLACE_WITH_S3_INSTANCE_NAME/* - allow publishing attestations to the S3 instance.

To grant an identity access to every configured resource (not recommended for production), enumerate all four resource types explicitly:

withResources:
  - "pkg:*/*/*"
  - "dv:*/*"
  - "af:*/*"
  - "s3:*/*"

Basic Identity Policy Example

Create ./dpg-config/policies/basic-identity-some-user-full-access.yaml
apiVersion: policy.gradle.com/v1
kind: AccessControl
metadata:
  name: basic-identity-some-user-full-access
spec:
  identityMatchingStrategy:
    withBasicIdentity:
      - withName: "some-user"
  canPerform:
    - publish-attestations
    - publish-policy-scans
  withResources:
    - "pkg:*/*/*"
    - "dv:*/*"
    - "af:*/*"
    - "s3:*/*"

OIDC Policy Example (GitHub Actions)

Create ./dpg-config/policies/oidc-github-action-full-access.yaml
apiVersion: policy.gradle.com/v1
kind: AccessControl
metadata:
  name: oidc-github-action-full-access
spec:
  identityMatchingStrategy:
    withOidc:
      - fromIssuerUri: https://token.actions.githubusercontent.com
        withClaims:
          job_workflow_ref: org/automation-repo/.github/workflows/build-image.yml@*
  canPerform:
    - publish-attestations
    - publish-policy-scans
  withResources:
    - "pkg:*/*/*"
    - "dv:*/*"
    - "af:*/*"
    - "s3:*/*"

Public Key Verification Policy Example

Create ./dpg-config/policies/public-key-verification-policy.yaml
apiVersion: policy.gradle.com/v1
kind: TrustedPublicKeys
metadata:
  name: public-keys
spec:
  resultsLabels: []
  description: Public keys trusted for attestations.
  remediation: Update the list of trusted public keys to ensure only verified attestations are accepted.
  keys:
    DEPLOYMENT_KEY_2025_10_01:
      pem: |
        -----BEGIN PUBLIC KEY-----
        ....
        -----END PUBLIC KEY-----

Replace DEPLOYMENT_KEY_2025_10_01 and the PEM block with your actual trusted public keys, for example the ones used to sign attestations.

Restart and verify
docker restart provenance-governor
docker logs provenance-governor 2>&1 | grep -i "Loading Policy Resource from file"
Expected log lines
Loading Policy Resource from file [/workspace/config/policies/public-key-verification-policy.yaml]

TLS with a Reverse Proxy

For production environments, place a TLS-terminating reverse proxy in front of the Develocity Provenance Governor container. Common options include:

  • nginx or Caddy as a reverse proxy

  • A cloud load balancer (e.g., AWS ALB, GCP Cloud Load Balancing)

Example: nginx reverse proxy configuration
server {
    listen 443 ssl;
    server_name provenance-governor.example.com;

    ssl_certificate     /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Troubleshooting

Container Fails to Start

Check logs for startup errors
docker logs provenance-governor

Common issues:

  • Missing license: Ensure ./dpg-config/license/develocity.license exists and is mounted correctly.

  • Invalid configuration: Check for YAML syntax errors in your configuration files.

  • Port conflicts: If port 8080 or 9090 is already in use, map to different host ports (e.g., -p 9080:8080).

Configuration Changes Not Taking Effect

Configuration files are read at startup. After modifying any files in ./dpg-config/, restart the container:

docker restart provenance-governor
Verify the restart
docker logs provenance-governor --tail=20

Container Cannot Reach External Services

If the container cannot connect to Develocity, Artifactory, or S3:

  • Verify the URIs in your properties configuration

  • If using Docker networks, ensure the container is on the correct network

  • Check DNS resolution inside the container:

    docker exec provenance-governor nslookup develocity.example.com

Configuration Error Example

***************************
APPLICATION FAILED TO START
***************************

Failed to bind properties under 'artifactory.instances.INSTANCE_NAME_GOES_HERE' ... Reason: java.lang.IllegalArgumentException: uri must not be null

Remediation:

  • Missing URI — add the URI to ./dpg-config/properties/application.yml

  • Missing token — add the token to ./dpg-config/secrets/application.yml

After fixing, restart:

docker restart provenance-governor

Verification and Next Steps

After completing the deployment, verify that Develocity Provenance Governor is running correctly:

  1. Check Container Status

    docker ps --filter name=provenance-governor

    You should see the container in Up state.

  2. Check Application Logs

    docker logs provenance-governor --tail=50

    Look for messages indicating: License loaded successfully Integrations enabled (e.g., "Develocity support enabled", "Artifactory support enabled") Policies loaded (if configured) No error messages

  3. Test API Accessibility

    curl -i http://localhost:8080

    You should receive a 401 Unauthorized response, which confirms the application is running and authentication is required.

  4. Verify Integration Configuration

    Check that your configured integrations were loaded:

    docker logs provenance-governor 2>&1 | grep "support enabled"

Successfully deployed? If all verification steps passed and you’re ready to start using Develocity Provenance Governor, proceed to Publishing Attestations to learn how to publish attestations and evaluate policies.

What to Do Next:

  • Configure Signing Keys — If you haven’t already, set up signing keys for attestation integrity. See Configure Signing Keys.

  • Write Your First Policy — Define policies for your software supply chain governance. See Writing Policies.

  • Publish Test Attestations — Try publishing attestations for a test package. See Publishing Attestations.

  • Integrate with CI/CD — Add Develocity Provenance Governor to your build and deployment pipelines. See GitHub Actions or CI/CD Integration.

If you encounter issues, consult the Troubleshooting section.

Summary Cheat Sheet

Integration Secrets File Key Properties File Key Required Notes

License

(file) develocity.license

n/a

Yes

Placed in license/ directory

Develocity Instance

develocity.instances.<NAME>.access-key

develocity.instances.<NAME>.uri

Yes

Multiple supported

Attestation Storage (S3)

s3.instances.<NAME>.access-key-id + s3.instances.<NAME>.secret-access-key

s3.instances.<NAME>.region + s3.instances.<NAME>.bucket-name

At least one storage backend required

Or use IAM/env credentials

Attestation Storage (Artifactory)

artifactory.instances.<NAME>.access-token

artifactory.instances.<NAME>.uri

At least one storage backend required

Token preferred

Signing Key (Private)

signing.key.<KEY>.private-pem

n/a

Recommended

PEM file

Signing Key (Public)

n/a

signing.key.<KEY>.public-pem

Recommended

PEM file

Basic Identity

basic.identities.<NAME>

n/a

Yes (for API access)

{bcrypt} recommended

Policies

n/a

n/a (files in policies/ directory)

Recommended

YAML files