Rust

The Rust version of Biscuit can be found on Github, crates.io and on docs.rs.

Install

In Cargo.toml:

biscuit-auth = "3.1"

Create a root key

use biscuit_auth::KeyPair;

let root_keypair = KeyPair::new();

Create a token


use biscuit_auth::{error, macros::*, Biscuit, KeyPair};

fn create_token(root: &KeyPair) -> Result<Biscuit, error::Token> {
    let user_id = "1234";
    // the authority block can be built from a datalog snippet
    // the snippet is parsed at compile-time, efficient building
    // code is generated
    let mut authority = biscuit!(
      r#"
      // parameters can directly reference in-scope variables
      user({user_id});

      // parameters can be manually supplied as well
      right({user_id}, "file1", {operation});
      "#,
      operation = "read",
    );

    // it is possible to modify a builder by adding a datalog snippet
    biscuit_merge!(
      &mut authority,
      r#"check if operation("read");"#
    );

    authority.build(&root)
}

Create an authorizer

use biscuit_auth::{builder_ext::AuthorizerExt, error, macros::*, Biscuit};

fn authorize(token: &Biscuit) -> Result<(), error::Token> {
    let operation = "read";

    // same as the `biscuit!` macro. There is also a `authorizer_merge!`
    // macro for dynamic authorizer construction
    let mut authorizer = authorizer!(
      r#"operation({operation});"#
    );

    // register a fact containing the current time for TTL checks
    authorizer.set_time();

    // add a `allow if true;` policy
    // meaning that we are relying entirely on checks carried in the token itself
    authorizer.add_allow_all();

    // link the token to the authorizer
    authorizer.add_token(token)?;

    let result = authorizer.authorize();

    // store the authorization context
    println!("{}", authorizer.to_base64_snapshot()?);

    let _ = result?;
    Ok(())
}

Restore an authorizer from a snasphot

use biscuit_auth::Authorizer;

fn display(snapshot: &str) {
  let authorizer = Authorizer::from_base64_snapshot(snapshot).unwrap();
  println!("{authorizer}");
}

Attenuate a token

use biscuit_auth::{builder_ext::BuilderExt, error, macros::*, Biscuit};
use std::time::{Duration, SystemTime};

fn attenuate(token: &Biscuit) -> Result<Biscuit, error::Token> {
    let res = "file1";
    // same as `biscuit!` and `authorizer!`, a `block_merge!` macro is available
    let mut builder = block!(r#"check if resource({res});"#);

    builder.check_expiration_date(SystemTime::now() + Duration::from_secs(60));

    token.append(builder)
}

Seal a token

let sealed_token = token.seal()?;

Reject revoked tokens

The Biscuit::revocation_identifiers method returns the list of revocation identifiers as byte arrays. Don't forget to parse them from a textual representation (for instance hexadecimal) if you store them as text values.

let identifiers: Vec<Vec<u8>> = token.revocation_identifiers();

Query data from the authorizer

The Authorizer::query method takes a rule as argument and extract the data from generated facts as tuples.

let res: Vec<(String, i64)> =
    authorizer.query("data($name, $id) <- user($name, $id)").unwrap();