Giter Club home page Giter Club logo

cerbos-sdk-java's Introduction

Cerbos Java SDK

Maven Central

Java client library for the Cerbos open source access control solution. This library includes RPC clients for accessing the Cerbos PDP and test utilities for testing your code locally using Testcontainers.

Find out more about Cerbos at https://cerbos.dev and read the documentation at https://docs.cerbos.dev.

Installation

Artifacts are available from Maven Central.

Example: Gradle (Kotlin DSL)

dependencies {
    implementation("dev.cerbos:cerbos-sdk-java:0.+")
    implementation("io.grpc:grpc-core:1.+")
}

repositories {
    mavenCentral()
}

Examples

Note

Connecting to Unix domain sockets using this SDK is only supported on Linux, which is a limitation inherited from the underlying grpc-java library.

Creating a client without TLS

CerbosBlockingClient client=new CerbosClientBuilder("localhost:3593").withPlaintext().buildBlockingClient();

Check a single principal and resource

CheckResult result=client.check(
    Principal.newInstance("john","employee")
        .withPolicyVersion("20210210")
        .withAttribute("department",stringValue("marketing"))
        .withAttribute("geography",stringValue("GB")),
    Resource.newInstance("leave_request","xx125")
        .withPolicyVersion("20210210")
        .withAttribute("department",stringValue("marketing"))
        .withAttribute("geography",stringValue("GB"))
        .withAttribute("owner",stringValue("john")),
    "view:public","approve");

if(result.isAllowed("approve")){ // returns true if `approve` action is allowed
    ...
}

Check a batch

CheckResourcesResult result=client.batch(
    Principal.newInstance("john","employee")
        .withPolicyVersion("20210210")
        .withAttribute("department",stringValue("marketing"))
        .withAttribute("geography",stringValue("GB"))
    )
    .addResources(
        ResourceAction.newInstance("leave_request","XX125")
            .withPolicyVersion("20210210")
            .withAttributes(
                Map.of(
                    "department", stringValue("marketing"),
                    "geography", stringValue("GB"),
                    "owner", stringValue("john")
                )
            )
            .withActions("view:public","approve","defer"),
        ResourceAction.newInstance("leave_request","XX225")
            .withPolicyVersion("20210210")
            .withAttributes(
                Map.of(
                    "department", stringValue("marketing"),
                    "geography", stringValue("GB"),
                    "owner", stringValue("martha")
                )
            )
            .withActions("view:public","approve"),
        ResourceAction.newInstance("leave_request","XX325")
            .withPolicyVersion("20210210")
            .withAttributes(
                Map.of(
                    "department", stringValue("marketing"),
                    "geography", stringValue("US"),
                    "owner", stringValue("peggy")
                )
            )
            .withActions("view:public","approve")
    )
    .check();

result.find("XX125").map(r->r.isAllowed("view:public")).orElse(false);

Create a query plan

PlanResourcesResult result = client.plan(
    Principal.newInstance("maggie","manager")
        .withAttribute("department",stringValue("marketing"))
        .withAttribute("geography",stringValue("GB"))
        .withAttribute("team",stringValue("design")),
    Resource.newInstance("leave_request").withPolicyVersion("20210210"),
    "approve"
);

if(result.isAlwaysAllowed()) {
    return true;
} else if(result.isAlwaysDenied()) {
    return false;
} else {
    return executeQuery(result.getCondition());
}

Test with Testcontainers

@Container
private static final CerbosContainer cerbosContainer=new CerbosContainer()
    .withClasspathResourceMapping("policies","/policies",BindMode.READ_ONLY)
    .withLogConsumer(new Slf4jLogConsumer(LOG));

@BeforeAll
private void initClient() throws CerbosClientBuilder.InvalidClientConfigurationException{
    String target=cerbosContainer.getTarget();
    this.client=new CerbosClientBuilder(target).withPlaintext().buildBlockingClient();
}

Accessing the Admin API

// Username and password can be specified using CERBOS_USER and CERBOS_PASSWORD environment variables as well
CerbosBlockingAdminClient  adminClient = new CerbosClientBuilder(target).withPlaintext().buildBlockingAdminClient("username", "password");

adminClient.addOrUpdatePolicy().with(new FileReader(fileObjectContainingPolicyJSON)).addOrUpdate();

See CerbosBlockingAdminClientTest test class for more examples of Admin API usage including how to convert YAML policies to the JSON format required by the API.

Common issues

java.lang.IllegalArgumentException: cannot find a NameResolver for ...: The gRPC library relies on Java SPI to register name resolvers and client-side load balancing strategies for clients. The defaults are defined in the io.grpc:grpc-core library. Some packaging methods could overwrite or strip out the META-INF/services directory, which would cause the above exception on Cerbos client initialisation. If that's the case, eithertry to recreate the default service bindings in your own jar OR explicitly register the services as follows:

import io.grpc.LoadBalancerRegistry;
import io.grpc.NameResolverRegistry;

public class Cerbos {
  public static void main(String[] args) throws CerbosClientBuilder.InvalidClientConfigurationException {
    LoadBalancerRegistry.getDefaultRegistry().register(new io.grpc.internal.PickFirstLoadBalancerProvider());
    NameResolverRegistry.getDefaultRegistry().register(new io.grpc.internal.DnsNameResolverProvider());
    CerbosBlockingClient client = new CerbosClientBuilder("dns:///cerbos.my-ns.svc.cluster.local:3593").withInsecure().buildBlockingClient();
    ...
  }
}

cerbos-sdk-java's People

Contributors

charithe avatar haines avatar oguzhand95 avatar renovate[bot] avatar thinhtpt-dev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cerbos-sdk-java's Issues

Add `scope` to `ResourceAction` when checking batch

Hi Cerbos team,
I created this ticket to request adding a method to setScope for Resource when performing check policies in batch.
I had a PR at #93. Please help me to review if it can be merged or not.
Thank you,
Thinh Tran.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): update all non-major dependencies (gradle, org.junit.jupiter:junit-jupiter-api)

Detected dependencies

github-actions
.github/workflows/publish.yaml
  • actions/checkout v4
  • actions/setup-java v4
  • gradle/wrapper-validation-action v3
.github/workflows/test.yaml
  • actions/checkout v4
  • actions/setup-java v4
  • gradle/wrapper-validation-action v3
gradle
settings.gradle.kts
build.gradle.kts
  • com.google.protobuf 0.9.4
  • com.palantir.git-version 3.1.0
  • io.github.gradle-nexus.publish-plugin 2.0.0
  • com.google.protobuf:protoc 4.27.3
  • io.grpc:protoc-gen-grpc-java 1.66.0
  • com.google.protobuf:protobuf-java 4.27.3
  • com.google.protobuf:protobuf-java-util 4.27.3
  • io.grpc:grpc-protobuf 1.66.0
  • io.grpc:grpc-stub 1.66.0
  • io.grpc:grpc-netty-shaded 1.66.0
  • io.netty:netty-tcnative-boringssl-static 2.0.65.Final
  • org.testcontainers:testcontainers 1.20.1
  • build.buf.protoc-gen-validate:pgv-java-stub 1.0.4
  • commons-io:commons-io 2.16.1
  • javax.annotation:javax.annotation-api 1.3.2
  • org.junit.jupiter:junit-jupiter-api 5.10.3
  • org.testcontainers:junit-jupiter 1.20.1
  • ch.qos.logback:logback-core 1.5.6
  • ch.qos.logback:logback-classic 1.5.6
  • com.fasterxml.jackson.core:jackson-core 2.17.2
  • com.fasterxml.jackson.dataformat:jackson-dataformat-yaml 2.17.2
gradle-wrapper
gradle/wrapper/gradle-wrapper.properties
  • gradle 8.9

  • Check this box to trigger a request for Renovate to run again on this repository

Stumbling blocks

  • Test Containers do not work with Scratch/Distroless containers when ports need to be exposed (testcontainers/testcontainers-java#3317). This is problematic because:
    • Writing tests for the SDK itself becomes tricky because there's no automated way to run Cerbos
    • Providing unit/integration test helpers as part of the SDK becomes impossible
  • Java does not support Unix domain sockets natively so that precludes UDS support and a potential workaround for the problem above. (There is a convoluted way to handle UDS using Netty epoll: grpc/grpc-java#1539 (comment))

Maven version format is non standard?

Had a bit of trouble adding this to my dependencies because of the leading "v" which seems to be pretty non-standard in java land. Or maybe I just don't know what I'm doing :)

Consider adding this to the setup instructions or publish your versions as "0.5.1" with no v?

implementation("dev.cerbos:cerbos-sdk-java:v0.5.1")

Dependabot updates to 47d60e3

It seems that dependabot is taking the first entry as the newest.
https://mvnrepository.com/artifact/dev.cerbos/cerbos-sdk-java
So it suggests 47d60e3 as an update.

It does not make a difference if the tag is like

implementation("dev.cerbos:cerbos-sdk-java:0.+")

or like

implementation("dev.cerbos:cerbos-sdk-java:0.7.0")

I would say getting rid of 47d60e3 would be a solution but I don't know if anyone is still using it.

To avoid the update issue I ignore the dependency in dependabot.yml for now like

version: 2
updates:
  - package-ecosystem: "gradle"
    directory: "/java"
    schedule:
      interval: "daily"
    ignore:
      - dependency-name: "dev.cerbos:cerbos-sdk-java"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.