macaroons4K   Kotlin

Project Status: Active Coverage

A Kotlin library for Macaroons. The aim of this library is to provide an easy-to-use, yet versatile (e.g., support for structural caveats) library for developers.

NOTE: this library is a port of the following library: macaroons4J. Besides the translation, the code is exactly the same. Therefore, the following examples are also written in Java.

How to add this dependency to your project

Replace VERSION with a tag from the releases.



Also, add the following dependency:



allprojects {
    repositories {
        maven { url '' }

Also, add the following dependency:

dependencies {
    implementation 'com.github.pvriel:macaroons4K:VERSION'

Basic usage example

Working with Macaroons in general

String hintTargetLocation = "";
byte[] macaroonIdentifier = UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8);
String macaroonSecret = "A secret, only known to the target location";

Macaroon macaroon = new SimpleMacaroon(macaroonSecret, macaroonIdentifier, hintTargetLocation);
VerificationContext context = new VerificationContext();
macaroon.verify(macaroonSecret, context); // No exceptions thrown.

Working with first-party caveats

byte[] firstPartyCaveatIdentifier = UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8);
// Create a custom FirstPartyCaveat subclass and define its verification process.
FirstPartyCaveat timeConstraint = new FirstPartyCaveat(firstPartyCaveatIdentifier) {
    protected void verify(@NotNull Macaroon macaroon, @NotNull VerificationContext context) throws IllegalStateException {
            macaroon: the Macaroon instance that is being verified.
            context: the context in which the caveat should hold.
        context.addRangeConstraint("time", Pair.of(5, 10));
macaroon.verify(macaroonSecret, context); // No exceptions thrown.

context = new VerificationContext();
context.addRangeConstraint("time", Pair.of(11, 15));
    Exception thrown: context only valid in 'time' range 11 - 15, while the constraint is only valid between 5 - 10.
    There is no overlapping between the two ranges.
macaroon.verify(macaroonSecret, context);

Working with third-party caveats

String thirdPartyCaveatRootKey = "Another secret, shared with the third-party";
byte[] thirdPartyCaveatIdentifier = "user is Alice";
String hintDischargeLocation = "";
ThirdPartyCaveat thirdPartyCaveat = new ThirdPartyCaveat(thirdPartyCaveatRootKey, thirdPartyCaveatIdentifier, hintDischargeLocation);

macaroon.verify(macaroonSecret, new VerificationContext()); // Exception thrown: no discharge Macaroon bound.
// You can add additional caveats to the discharge Macaroons, but we are not doing that here.
Macaroon dischargeMacaroon = new SimpleMacaroon(thirdPartyCaveatRootKey, thirdPartyCaveatIdentifier, hintDischargeLocation);
macaroon.verify(macaroonSecret, new VerificationContext()); // No exceptions thrown.


Found a bug, problem, … or do you have a question about this library? Do not hesitate to contact me as soon as possible!


View Github