biscuit-servant: Servant support for the Biscuit security token

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

Please see the README on GitHub at

[Skip to Readme]


Change log
Dependencies base (>=4.7 && <5), biscuit-haskell (>= && <0.3), bytestring (>=0.10 && <0.11), mtl (>=2.2 && <2.3), servant-server (>=0.18 && <0.20), text (>=1.2 && <1.3), wai (>=3.2 && <3.3) [details]
License BSD-3-Clause
Copyright 2021 Clément Delafargue
Author Clément Delafargue
Category Security
Home page
Bug tracker
Source repo head: git clone
Uploaded by clementd at 2022-04-25T12:55:54Z


[Index] [Quick Jump]


Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Readme for biscuit-servant-

[back to package description]

biscuit-servant 🤖 Hackage

Servant combinators to enable biscuit validation in your API trees


type AppM = WithAuthorizer Handler
type API = RequireBiscuit :> ProtectedAPI

-- /users
-- /users/:userId
type ProtectedAPI =
  "users" :> ( Get '[JSON] [User]
             :<|> Capture "userId" Int :> Get '[JSON] User
app :: PublicKey -> Application
app pk = serveWithContext @API Proxy (genBiscuitCtx pk) server

server :: Server API
server biscuit =
  let handlers = userListHandler :<|> singleUserHandler
      handleAuth =
        handleBiscuit biscuit
        -- `allow if right("admin");` will be the first policy
        -- for every endpoint.
        -- Policies added by endpoints (or sub-apis) will tried after this one.
        . withPriorityAuthorizer [authorizer|allow if right("admin");|]
        -- `deny if true;` will be the last policy for every endpoint.
        -- Policies added by endpoints (or sub-apis) will tried before this one.
        . withFallbackAuthorizer [authorizer|deny if true;|]
  in hoistServer @ProtectedAPI Proxy handleAuth handlers

allUsers :: [User]
allUsers = [ User 1 "Danielle" "George"
           , User 2 "Albert" "Einstein"

userListHandler :: AppM [User]
userListHandler = withAuthorizer [authorizer|allow if right("userList")|]
  $ pure allUsers

singleUserHandler :: Int -> AppM User
singleUserHandler uid =
  withAuthorizer [authorizer|allow if right("getUser", ${uid})|] $
  let user = find (\user -> userId user == uid) allUsers
   in maybe (throwError error404) (\user -> pure user) user