Expand description
Implementation of Macaroons for Rust, which are flexible authorization tokens for distributed systems. They are similar to cookies, but allow for more narrowly-focused authorization based on contextual caveats.
§What Are Macaroons?
Macaroons are bearer tokens (similar to cookies) which encode within them criteria within which the authorization is allowed to take place (referred to as “caveats”). For instance, authorization could be restricted to a particular user, account, time of day, really anything. These criteria can be either evaluated locally (a “first-party caveat”), or using special macaroons (“discharge macaroons”) generated by a third party (a “third-party caveat”).
A first-party caveat consists simply of a predicate which, when evaluated as true, authorizes the caveat.
The predicate is a string which is either evaluated using strict string comparison (satisfy_exact),
or interpreted using a provided function (satisfy_general).
A third-party caveat consists of a location string, an identifier, and a specially-generated signing key to authenticate the generated discharge macaroons. The key and identifier is passed to the third-party who generates the discharge macaroons. The receiver then binds each discharge macaroon to the original macaroon.
During verification of a third-party caveat, a discharge macaroon is found from those received whose identifier matches that of the caveat. The binding signature is verified, and the discharge macaroon’s caveats are verified using the same process as the original macaroon.
The macaroon is considered authorized only if all its caveats are authorized by the above process.
§Example
use libmacaroon::{Macaroon, Verifier, MacaroonKey};
// Create our key.
let key = MacaroonKey::generate(b"key");
// Create our macaroon. A location is optional.
let mut macaroon = Macaroon::create(Some("location"), &key, "id")?;
// Add a first-party caveat: only someone identified as account 12345678
// is authorized to use this macaroon. Multiple caveats with different
// predicates can be layered on.
macaroon.add_first_party_caveat("account = 12345678")?;
// Build a verifier with the predicates we're willing to accept.
let mut verifier = Verifier::default();
verifier.satisfy_exact("account = 12345678");
// Verify. Returns Ok(()) on success.
verifier.verify(&macaroon, &key, &[])?;
// Now a third-party caveat: verification requires a discharge macaroon
// issued by a third party under a separate key.
let other_key = MacaroonKey::generate(b"different key");
macaroon.add_third_party_caveat("https://auth.mybank", &other_key, "caveat id")?;
// The third party creates the discharge using the same caveat id and key.
let mut discharge = Macaroon::create(
Some("http://auth.mybank/"),
&other_key,
"caveat id",
)?;
discharge.add_first_party_caveat("account = 12345678")?;
// Bind the discharge to the original macaroon so it cannot be reused
// against a different authorizing macaroon.
macaroon.bind(&mut discharge);
// Same verifier, now with the discharge supplied.
verifier.verify(&macaroon, &key, &[discharge])?;§Supported Features
This crate supports all the following features:
- verification of first-party caveats either via exact string match or passed-in function
- verification of third-party caveats using discharge macaroons (including ones that themselves have embedded third-party caveats)
- serialization and deserialization of caveats via version 1, 2 or 2J serialization formats (fully compatible with libmacaroons)
Structs§
- First
Party - Macaroon
- Macaroon
Key - Secret cryptographic key used to sign and verify Macaroons.
- Third
Party - Verifier
Enums§
- Caveat
- Format
- Macaroon
Error - Represents all of the errors that can arise when creating, deserializing, or verifying macaroons.
Constants§
- MAX_
CAVEATS - Maximum number of caveats allowed on a single macaroon. Applied on both
construction (
add_first_party_caveat,add_third_party_caveat) and deserialization to bound memory and verification work. - MAX_
FIELD_ SIZE_ BYTES - Maximum byte length accepted for any single field (identifier, location, predicate, VID, signature) during construction and deserialization.