Skip to content

pvriel/macaroons4J

Repository files navigation

macaroons4J   Java

Project Status: Active Coverage

A Java 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.


How to add this dependency to your project

We now use GitHub packages instead of JitPack.


Basic usage example

Working with Macaroons in general

String hintTargetLocation = "https://google.com";
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();
HashSet<VerificationContext> validContexts = macaroon.verify(macaroonSecret, context);
assert(validContexts.size() >= 1);

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) {
    @Override
    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.addCaveat(timeConstraint);
validContexts = macaroon.verify(macaroonSecret, context);
assert(validContexts.size() >= 1);

context = new VerificationContext();
context.addRangeConstraint("time", Pair.of(11, 15));
/*
    No possible solutions here: 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.
 */
validContexts = macaroon.verify(macaroonSecret, context);
assert(validContexts.size() == 0);

Working with third-party caveats

String thirdPartyCaveatRootKey = "Another secret, shared with the third-party";
byte[] thirdPartyCaveatIdentifier = "user is Alice";
String hintDischargeLocation = "https://oauthprovider.com";
ThirdPartyCaveat thirdPartyCaveat = new ThirdPartyCaveat(thirdPartyCaveatRootKey, thirdPartyCaveatIdentifier, hintDischargeLocation);
macaroon.addCaveat(thirdPartyCaveat);

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.bindMacaroonForRequest(dischargeMacaroon);
validContexts = macaroon.verify(macaroonSecret, new VerificationContext());
assert(validContexts.size() >= 1);

Contact

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