Skip to main content
Version: 0.3.1

Gradle Plugin

The jGuard Gradle plugin integrates policy compilation and agent execution into your build.

Installation​

Add the plugin to your build.gradle:

plugins {
id "java"
id "application"
id "io.jguard.policy" version "0.3.0"
}

Or using the plugins DSL in build.gradle.kts:

plugins {
java
application
id("io.jguard.policy") version "0.3.0"
}

Configuration​

Basic Configuration​

jguardPolicy {
// Policy source file
sourceFile = file("src/main/java/module-info.jguard")

// Output directory for compiled policies
outputDir = layout.buildDirectory.dir("generated/jguard")

// Also generate JSON for inspection
includeJson = true

// Path inside JAR for policy
jarPath = "META-INF/jguard"

// Enforcement mode: strict, permissive, or audit
mode = "strict"

// Log level: error, warn, info, debug, trace
logLevel = "info"
}

Multi-Module Configuration​

jguardPolicy {
// Enable auto-discovery of policies from signed JARs
discoveryMode = true

// Allow unsigned policies (development only!)
allowUnsignedPolicies = true
}

External Policies​

jguardPolicy {
// Source directory for external .jguard files
externalPoliciesSourceDir = file("policies-src")

// Output directory for compiled .bin files
externalPoliciesOutputDir = file("policies")
}

Hot Reload​

jguardPolicy {
// Enable runtime policy hot reload
hotReload = true

// Poll interval in seconds
hotReloadInterval = 5

// External policies directory
externalPoliciesSourceDir = file("policies-src")
externalPoliciesOutputDir = file("policies")
}

Trusted Modules​

jguardPolicy {
// Allow trusted modules (for native libraries like PyTorch)
allowTrusted = true

// External policies with trusted declarations
externalPoliciesSourceDir = file("policies-src")
externalPoliciesOutputDir = file("policies")
}
warning

Only enable allowTrusted when you have modules that genuinely require unrestricted access, such as native ML libraries. Trusted modules bypass all capability checks.

Configuration Reference​

PropertyTypeDefaultDescription
sourceFileFilesrc/main/java/module-info.jguardPolicy source file
outputDirDirectorybuild/generated/jguardOutput directory
includeJsonbooleanfalseAlso output JSON
jarPathStringMETA-INF/jguardPath inside JAR
modeStringstrictEnforcement mode
logLevelStringinfoLog verbosity
discoveryModebooleantrueAuto-discover policies
allowUnsignedPoliciesbooleanfalseAllow unsigned (dev only)
allowTrustedbooleanfalseAllow trusted modules
hotReloadbooleanfalseEnable hot reload
hotReloadIntervalint5Reload interval (seconds)
externalPoliciesSourceDirFile—External policy sources
externalPoliciesOutputDirFile—External policy output

Tasks​

compileJGuardPolicy​

Compiles module-info.jguard to binary format.

./gradlew compileJGuardPolicy

Inputs:

  • sourceFile (default: src/main/java/module-info.jguard)

Outputs:

  • policy.bin in outputDir
  • policy.json if includeJson = true

compileExternalPolicies​

Compiles all .jguard files in externalPoliciesSourceDir.

./gradlew compileExternalPolicies

Inputs:

  • All *.jguard files in externalPoliciesSourceDir

Outputs:

  • Corresponding .bin files in externalPoliciesOutputDir

Incremental Builds

The task uses content-based change detection. It only recompiles when .jguard file contents actually change, not just timestamps.

Automatic Test Dependency

When externalPoliciesSourceDir is configured, all Test tasks automatically depend on compileExternalPolicies. This ensures tests always run with up-to-date compiled policies.

runWithAgent​

Runs the application with the jGuard agent attached.

# Run with default settings
./gradlew runWithAgent

# Override enforcement mode
./gradlew runWithAgent -Pjguard.mode=audit

# Override log level
./gradlew runWithAgent -Pjguard.logLevel=debug

Properties:

PropertyDescription
-Pjguard.mode=<mode>Override enforcement mode
-Pjguard.logLevel=<level>Override log level

JAR Packaging​

The plugin automatically packages compiled policies into your JAR:

your-app.jar
├── META-INF/
│ └── jguard/
│ ├── policy.bin # Binary policy
│ └── policy.json # JSON (if includeJson = true)
├── module-info.class
└── com/
└── example/
└── ...

JAR Signing​

For production, sign your JARs to enable policy verification:

// build.gradle
jar {
doLast {
ant.signjar(
jar: archiveFile.get().asFile,
keystore: "keystore.jks",
storepass: "changeit",
alias: "mykey"
)
}
}

Or using the signing plugin:

plugins {
id 'signing'
}

signing {
sign jar
}

Multi-Project Setup​

For multi-module Gradle projects:

root/
├── build.gradle
├── settings.gradle
├── core/
│ ├── build.gradle
│ └── src/main/java/
│ ├── module-info.java
│ └── module-info.jguard
├── network/
│ ├── build.gradle
│ └── src/main/java/
│ ├── module-info.java
│ └── module-info.jguard
└── app/
├── build.gradle
└── src/main/java/
├── module-info.java
└── module-info.jguard

Each subproject applies the plugin independently:

// core/build.gradle
plugins {
id "java-library"
id "io.jguard.policy" version "0.3.0"
}

Run the app with all policies:

// app/build.gradle
plugins {
id "application"
id "io.jguard.policy" version "0.3.0"
}

jguardPolicy {
discoveryMode = true
allowUnsignedPolicies = true // dev only
}

dependencies {
implementation project(':core')
implementation project(':network')
}

Integration with CI/CD​

GitHub Actions​

name: Build and Test

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'

- name: Build and compile policies
run: ./gradlew build compileJGuardPolicy

- name: Run with enforcement
run: ./gradlew runWithAgent -Pjguard.mode=strict

Strict Mode for CI​

Use strict mode in CI to catch policy violations:

// build.gradle
jguardPolicy {
mode = System.getenv('CI') ? 'strict' : 'permissive'
}

Troubleshooting​

Policy Not Found​

Error: No policy found for module com.example.app

Solution: Ensure module-info.jguard exists and the module name matches module-info.java.

Unsigned Policy Rejected​

Error: Policy rejected - JAR is not signed

Solution: Either sign your JARs or set allowUnsignedPolicies = true for development.

Capability Denied at Runtime​

SecurityException: Capability denied
Module: com.example.app
Attempted: network.outbound

Solution: Add the required entitlement to your policy or run in audit mode to discover needs:

./gradlew runWithAgent -Pjguard.mode=audit

Next Steps​