Quarkus Topaz

Topaz is an open-source authorizer. It runs an OPA policy engine for Rego next to a Zanzibar-style directory of objects and relations. It serves both over gRPC.

This extension gives a Quarkus application these parts:

  • A reactive client for both services.

  • A Dev Service that starts a Topaz container seeded with your policies and data.

  • A readiness health check.

  • A Dev UI card.

An optional security extension enforces Topaz decisions on HTTP routes and CDI bean methods. An optional connector lets the Topaz directory answer the annotations of quarkus-zanzibar.

The client talks to Topaz through the Vert.x gRPC client and Mutiny stubs generated from the pinned Topaz protos. It does not depend on the Aserto Java SDK.

Installation

Artifact Contents

quarkus-topaz

The client, the Dev Service, the health check and the Dev UI card.

quarkus-topaz-security

Enforcement: the topaz HTTP security policy, @TopazAuthorize, @TopazCheck and the @PermissionsAllowed bridge. Includes quarkus-topaz. See Security.

quarkus-topaz-zanzibar

The quarkus-zanzibar RelationshipManager backed by the Topaz directory. Includes quarkus-topaz. See Zanzibar connector.

Add the runtime artifact. Quarkus resolves the deployment artifact.

<dependency>
    <groupId>io.quarkiverse.topaz</groupId>
    <artifactId>quarkus-topaz</artifactId>
    <version>0</version>
</dependency>

Quick start

This is the todo application from the integration-tests module of this repository, cut down to one endpoint. Put a policy, a directory manifest and seed data under src/main/resources/topaz/. Point the Dev Service at them:

quarkus.topaz.devservices.policy.directory=classpath:topaz/policies
quarkus.topaz.devservices.manifest-location=classpath:topaz/manifest.yaml
quarkus.topaz.devservices.data-location=classpath:topaz/data

The policy topaz/policies/todo_delete.rego allows a delete when the caller owns the todo:

package todoApp.DELETE.todos.__id

import future.keywords.if

default allowed = false

allowed if {
	ds.check({"object_type": "todo", "object_id": input.resource.id, "relation": "owner",
	          "subject_type": "user", "subject_id": input.user.id})
}

Inject TopazClient and ask for the decision:

@Inject
TopazClient topaz;

@GET
@Path("/todos/{id}/can-delete")
public Uni<Boolean> canDelete(@PathParam("id") String id, @QueryParam("user") String user) {
    return topaz.authorizer().isAllowed(IdentityContexts.subject(user), "todoApp.DELETE.todos.__id",
            "allowed", Map.of("id", id));
}

quarkus dev starts Topaz ghcr.io/aserto-dev/topaz:0.33.22, loads the manifest and data, and configures the client. The full manifest and data files are in integration-tests/src/main/resources/topaz/.

Where to go next