Skip to main content

OPA Java Tutorial: Hello World

This Hello World style tutorial explains how to set up a basic Java project which is able to import the OPA Java SDK and use it to evaluate a policy decision.


In a new directory, run gradle init. The prompts should be responded to as follows:

  • Select type of build to generate: Application
  • Select implementation language: Java
  • Enter target Java version: 21
  • Project name: docsample
  • Select application structure: Single application project
  • Select build script DSL: Groovy
  • Select test framework: JUnit Jupiter
  • Generate build using new APIs and behavior: no

Gradle should print a message like the one below if everything went right.

1 actionable task: 1 executed

Before proceeding, verify that the project Gradle created for us is able to build and run. The output should look similar to the below.

./gradlew run

> Task :app:run
Hello World!

2 actionable tasks: 2 executed

Adding the OPA Java SDK

Next, modify the Java code to utilize the OPA Java SDK in app/src/main/java/org/example/

* This source file was generated by the Gradle 'init' task
package org.example;

import com.styra.opa.OPAClient;
import com.styra.opa.OPAException;

import java.util.Map;
import java.util.List;

import static java.util.Map.entry;

public class App {
public String getGreeting() {
return "Hello World!";

public static void main(String[] args) throws OPAException {
System.out.println(new App().getGreeting());

// Create an OPA instance, this handles any state needed for interacting
// with OPA, and can be re-used for multiple requests if needed.
String opaURL = "http://localhost:8181";
OPAClient opa = new OPAClient(opaURL);

// This will be the input to our policy.
java.util.Map<String,Object> input = java.util.Map.ofEntries(
entry("subject", "alice"),
entry("action", "read"),
entry("resource", "/finance/reports/fy2038_budget.csv")

boolean allowed = false;

// Perform the request against OPA.
try {
allowed = opa.check("authz/allow", input);
} catch (OPAException e ) {
// Note that OPAException usually wraps other exception types, in
// case you need to do more complex error handling.
System.out.println("exception while making request against OPA: " + e);
throw e; // crash the program

System.out.println("allowed: " + allowed);

The app/build.gradle file must also be updated to pull in the OPA-Java SDK. Under the dependencies section, ad the following:

    implementation group: 'com.styra', name: 'opa', version: '+'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '+'

Using the version string + causes Gradle to pull in the latest version of that dependency. In a production environment, it may be preferable to pin a specific version of your dependencies instead.

Creating policies and running OPA

The sample application is almost ready to run, but first an OPA instance is needed for the SDK to communicate with.

Create a policy/ folder and the following two files:


package authz

import rego.v1

default allow := false

allow if input.subject == "alice"


"roles": {
"admin": ["read", "write"]

OPA can be launched using this folder as its bundle using the command opa run --server --bundle ./policy/.


Consider running OPA in a separate background terminal, as it will be necessary to run more shell commands.

Verify that the data was loaded into OPA correctly:

curl -Ss http://localhost:8181/v1/data/roles

Verify that the policy is working as expected:

curl -Ss http://localhost:8181/v1/data/authz/allow -X POST -d '{"input": {"subject": "alice"} }'
curl -Ss http://localhost:8181/v1/data/authz/allow -X POST -d '{"input": {"subject": "bob"} }'

Running the application

Finally, run the Java program:

./gradlew run

> Task :app:run
Hello World!
allowed: true

2 actionable tasks: 2 executed

The project is now prepared for experimenting with the OPA Java SDK locally. Try modifying or the OPA policy and see how the behavior changes.