Skip to content

Simple implementation of Macaroon for learning purposes.

License

Notifications You must be signed in to change notification settings

Guilospanck/macaroon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Macaroon codecov

Simple implementation of macaroons as described in the paper "Macaroons: Cookies with Contextual Caveats for Decentralized Authorization in the Cloud".

How to use

  • Creating a macaroon
use macaroon::{Macaroon, Verifier};

let root_key = "potato";
let identifier = "test-id";
let location = Some("https://macaroon.location");
let mut original_macaroon = Macaroon::create(root_key, identifier, location);
  • Adding caveats
// Adds 1st party caveat to the original macaroon
let predicate_account_id = "account_id = 007";
original_macaroon.add_first_party_caveat(predicate_account_id);

// Adds 3rd party caveat to the original macaroon
let caveat_discharge_location = Some("https://auth.bank");
let caveat_identifier = "caveat-identifier";
let caveat_root_key = "caveat-root-key";

original_macaroon.add_third_party_caveat(
  caveat_root_key,
  caveat_identifier,
  caveat_discharge_location,
);
  • Create macaroon to discharge 3rd party caveat and bound it to the autorisation (original) macaroon
// Creates the discharge macaroon that will be responsible for
// handling the 3rd party caveat just created.
let mut discharge_macaroon = Macaroon::create(
  caveat_root_key,
  caveat_identifier,
  caveat_discharge_location,
);
let first_party_caveat_of_discharge_macaroon_identifier = "time < 2023-07-09T00:00:00Z";
discharge_macaroon.add_first_party_caveat(first_party_caveat_of_discharge_macaroon_identifier);

// Bind the discharge to the original macaroon
let mut bound_macaroon = discharge_macaroon.clone();
bound_macaroon.signature =
  original_macaroon.bind_for_request(discharge_macaroon.signature.clone());

let expected_bound_signature = Macaroon::get_bound_signature(
  discharge_macaroon.clone().signature,
  original_macaroon.clone().signature,
);

assert_eq!(bound_macaroon.signature, expected_bound_signature);
  • Verify macaroons
let mut verifier = Verifier::default();
// must satisfy first caveat from the original macaroon
verifier.satisfy_exact(predicate_account_id);
// must satisfy the first caveat from the discharge macaroon
verifier.satisfy_exact(first_party_caveat_of_discharge_macaroon_identifier);

// get verified result from discharge macaroon that DOES NOT have the signature bound to the authorisation macaroon
let discharge_macaroon_with_signature_not_bound_to_authorisation_macaroon_verifier = verifier
  .verify(
    original_macaroon.clone(),
    root_key,
    vec![discharge_macaroon],
    None,
  );

assert!(
  discharge_macaroon_with_signature_not_bound_to_authorisation_macaroon_verifier.is_err()
);
assert_eq!(
  discharge_macaroon_with_signature_not_bound_to_authorisation_macaroon_verifier
    .err()
    .unwrap(),
  VerifyError::SignaturesDoNotMatch
);

// get verified result from discharge macaroon that DOES have the signature bound to the authorisation macaroon
let discharge_macaroon_with_signature_bound_to_authorisation_macaroon_verifier =
  verifier.verify(original_macaroon, root_key, vec![bound_macaroon], None);

assert!(discharge_macaroon_with_signature_bound_to_authorisation_macaroon_verifier.is_ok());

About

Simple implementation of Macaroon for learning purposes.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages