3 unstable releases

0.2.0 Aug 31, 2023
0.1.1 Jun 14, 2023
0.1.0 Jun 14, 2023

#625 in Web programming

Download history 40/week @ 2023-08-08 13/week @ 2023-08-15 15/week @ 2023-08-22 37/week @ 2023-08-29 7/week @ 2023-09-05 23/week @ 2023-09-12 33/week @ 2023-09-19 23/week @ 2023-09-26 4/week @ 2023-10-03 7/week @ 2023-10-17 15/week @ 2023-10-24 33/week @ 2023-10-31 18/week @ 2023-11-07 33/week @ 2023-11-14 59/week @ 2023-11-21

149 downloads per month


285 lines

Biscuit actix middleware

This middleware allows service-wide extraction and parsing of biscuit tokens.

Authorization itself still need to be handled from within endpoint handlers.

The middleware expects a base64-encoded token through the bearer token HTTP authorization scheme (an Authorization: Bearer <token> HTTP header). This token is deserialized and its cryptographic signatures verified with the provided public key.

  • Requests without a bearer token are rejected with a HTTP 401 Unauthorized error;
  • Requests with tokens that fail parsing or cryptographic verification are rejected with a HTTP 403 Forbidden error.

Token extraction logic and error handling are configurable (see Configuration example).

Working example

Here is a web server exposing GET /hello, only to tokens containing the role("admin") fact. The public key used for verifying tokens is provided through the BISCUIT_PUBLIC_KEY environment variable.

A complete, runnable example can be found in examples/readme.rs, and can be run with BISCUIT_PUBLIC_KEY=<public key> cargo run --example readme.

Optionally, you can enable tracing by running BISCUIT_PUBLIC_KEY=<public key> cargo run --example readme --features tracing to observe middleware traces as logs in the console.

use actix_web::{get, web, App, HttpResponse, HttpServer};
use biscuit_actix_middleware::BiscuitMiddleware;
use biscuit_auth::{macros::*, Biscuit, PublicKey};

async fn main() -> std::io::Result<()> {
    let public_key = PublicKey::from_bytes_hex(
            .expect("Missing BISCUIT_PUBLIC_KEY environment variable"),
    .expect("Couldn't parse public key");

    HttpServer::new(move || {
    .bind(("", 8080))?

async fn hello(biscuit: web::ReqData<Biscuit>) -> HttpResponse {
    let mut authorizer = authorizer!(
      allow if role("admin");

    if authorizer.authorize().is_err() {
        return HttpResponse::Forbidden().finish();

    HttpResponse::Ok().body("Hello admin!")


~613K SLoC