Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

biscuit v2 #19

Merged
merged 39 commits into from
Oct 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
08771b4
v2: add support for new crypto
divarvel Aug 30, 2021
afa8009
make running ghcid easier through the Makefile
divarvel Sep 1, 2021
b2bbf55
v2: introduce a scoped executor for Datalog
divarvel Sep 1, 2021
a21a344
v2: support provisional v2 pb encoding
divarvel Sep 2, 2021
755c8e7
v2: remove v1 support and expose v2 primitives
divarvel Sep 4, 2021
908f81c
biscuit(parser): allow empty blocks & verifiers
divarvel Sep 7, 2021
690172c
v2(biscuit): remove support for symbols and update tests accordingly
divarvel Sep 7, 2021
9ce5541
v2(biscuit): add compliance checks based on the published samples
divarvel Sep 7, 2021
f08c514
v2(servant): update library and examples for biscuit v2
divarvel Sep 7, 2021
594ff8a
v2(biscuit): cleanup modules and export lists
divarvel Sep 7, 2021
2b68fe5
biscuit(v2): make biscuit functions polymorphic on proof type
divarvel Sep 7, 2021
54008b0
v2(biscuit): expose polymorphic biscuit types and use them in servant
divarvel Sep 7, 2021
a8e107d
biscuit: update bench for v2
divarvel Sep 8, 2021
bb5deea
Bump libs version to 0.2.0.0
divarvel Sep 8, 2021
0473d0f
v2: rename Biscuit types and remove superfluous aliases
divarvel Sep 8, 2021
7eb9165
biscuit: rename `ID` to `Term`
divarvel Sep 19, 2021
ac86bf4
chore: add stylish-haskell to shell.nix
divarvel Sep 19, 2021
1fb512a
biscuit: remove now-unused samples
divarvel Sep 19, 2021
6dc1e8b
biscuit: store the public key when successfully checking a biscuit
divarvel Sep 19, 2021
4dd27f7
[WIP] biscuit: return all the generated facts when verifying a biscuit
divarvel Sep 19, 2021
b6891c2
doc: improve hackage docs
divarvel Sep 23, 2021
c49c907
remove unused deps and relax cryptonite and memory bounds
divarvel Sep 24, 2021
ca21ad6
bench: follow breaking changes from biscuit-haskell
divarvel Sep 24, 2021
a39b562
fix: properly seal tokens and verify sealed tokens
divarvel Sep 25, 2021
6277ff9
biscuit: carry the algorithm along public keys
divarvel Sep 25, 2021
66cd595
biscuit: remove high-level helpers for biscuit hex encoding
divarvel Sep 25, 2021
f94b957
biscuit: check revocation ids when parsing
divarvel Sep 25, 2021
4f2efef
servant: add ghcid make targets
divarvel Sep 25, 2021
bc5d168
biscuit: relax `getRevocationIds` constraints
divarvel Sep 25, 2021
e3f83e3
biscuit: describe parsing combinations with a record
divarvel Sep 27, 2021
24f6c63
biscuit: reorder exports in `Auth.Biscuit`
divarvel Oct 1, 2021
5bea736
biscuit: expose helpers to specialize a biscuit
divarvel Oct 1, 2021
dcc0ea4
biscuit: expose helpers for sealing biscuits
divarvel Oct 1, 2021
5cc9e34
biscuit: expose more functions from the top-level module
divarvel Oct 1, 2021
4d4018e
biscuit: make `verifyBlocks` take a forward list of blocks
divarvel Oct 1, 2021
49262b5
rename 'Verifier' into 'Authorizer'
divarvel Oct 1, 2021
cefa885
Checked biscuits are now Verified biscuits
divarvel Oct 1, 2021
65fcd31
biscuit: `verifyBiscuit` is now `authorizeBiscuit`
divarvel Oct 2, 2021
9e965c3
biscuit: update samples following the s/verifier/authorizer/ change
divarvel Oct 6, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This is the repository for a collection of haskell libraries providing support f

You will find below the main lib and its companions:

* [biscuit](./biscuit/) — Main library, providing minting and signature checking of biscuit tokens, as well as a datalog engine allowing to compute the validity of a token in a given context
* [biscuit](./biscuit/) — Main library, providing minting and signature verification of biscuit tokens, as well as a datalog engine allowing to compute the validity of a token in a given context
* [biscuit-servant](./biscuit-servant) — Servant combinators, for a smooth integration in your API

## Supported biscuit versions
Expand Down
8 changes: 8 additions & 0 deletions biscuit-servant/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
.PHONY: ghcid
ghcid:
ghcid -l -c 'cabal repl'

.PHONY: ghcid-tests
ghcid-tests:
ghcid -l -c 'cabal repl biscuit-servant-test' -T main

.PHONY: configure
configure:
cabal configure --enable-tests --test-show-details=direct --disable-optimization
Expand Down
6 changes: 3 additions & 3 deletions biscuit-servant/biscuit-servant.cabal
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cabal-version: 2.0

name: biscuit-servant
version: 0.1.1.0
version: 0.2.0.0
category: Security
synopsis: Servant support for the Biscuit security token
description: Please see the README on GitHub at <https://github.com/divarvel/biscuit-haskell#readme>
Expand Down Expand Up @@ -33,7 +33,7 @@ library
ghc-options: -Wall
build-depends:
base >= 4.7 && <5,
biscuit-haskell ^>= 0.1,
biscuit-haskell ^>= 0.2,
bytestring ^>= 0.10,
mtl ^>= 2.2,
text ^>= 1.2,
Expand All @@ -45,7 +45,7 @@ test-suite biscuit-servant-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
AppWithVerifier
AppWithAuthorizer
ClientHelpers
hs-source-dirs:
test
Expand Down
466 changes: 249 additions & 217 deletions biscuit-servant/src/Auth/Biscuit/Servant.hs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module AppWithVerifier where
module AppWithAuthorizer where

import Auth.Biscuit
import Auth.Biscuit.Servant
Expand All @@ -31,7 +31,7 @@ call3 b =
let (_ :<|> _ :<|> e3) = client @API Proxy (protect b)
in e3

type H = WithVerifier Handler
type H = WithAuthorizer Handler
type API = RequireBiscuit :> ProtectedAPI
type ProtectedAPI =
"endpoint1" :> Get '[JSON] Int
Expand All @@ -46,21 +46,21 @@ server :: Server API
server b =
let nowFact = do
now <- liftIO getCurrentTime
pure [verifier|now(#ambient, ${now});|]
handleAuth :: WithVerifier Handler x -> Handler x
pure [authorizer|time(${now});|]
handleAuth :: WithAuthorizer Handler x -> Handler x
handleAuth =
handleBiscuit b
. withPriorityVerifierM nowFact
. withPriorityVerifier [verifier|allow if right(#authority, #admin);|]
. withFallbackVerifier [verifier|allow if right(#authority, #anon);|]
. withPriorityAuthorizerM nowFact
. withPriorityAuthorizer [authorizer|allow if right("admin");|]
. withFallbackAuthorizer [authorizer|allow if right("anon");|]
handlers = handler1 :<|> handler2 :<|> handler3
in hoistServer @ProtectedAPI Proxy handleAuth handlers

handler1 :: H Int
handler1 = withVerifier [verifier|allow if right(#authority, #one);|] $ pure 1
handler1 = withAuthorizer [authorizer|allow if right("one");|] $ pure 1

handler2 :: Int -> H Int
handler2 v = withVerifier [verifier|allow if right(#authority, #two, ${v});|] $ pure 2
handler2 v = withAuthorizer [authorizer|allow if right("two", ${v});|] $ pure 2

handler3 :: H Int
handler3 = withVerifier [verifier|deny if true;|] $ pure 3
handler3 = withAuthorizer [authorizer|deny if true;|] $ pure 3
45 changes: 22 additions & 23 deletions biscuit-servant/test/Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,21 @@ import Data.Text.Encoding (decodeUtf8)
import Data.Time (UTCTime, addUTCTime, getCurrentTime)
import Test.Hspec

import AppWithVerifier (app, call1, call2, call3)
import AppWithAuthorizer (app, call1, call2, call3)
import ClientHelpers (runC, withApp)

main :: IO ()
main = do
keypair <- fromPrivateKey appPrivateKey
let appPk = toPublic appSecretKey
later <- addUTCTime (60*5) <$> getCurrentTime
earlier <- addUTCTime (-60) <$> getCurrentTime
let appPk = publicKey keypair
adminB <- toText <$> mkAdminBiscuit keypair
anonB <- toText <$> mkAnonBiscuit keypair
e1 <- toText <$> mkE1Biscuit keypair
e21 <- toText <$> mkE2Biscuit 1 keypair
e22 <- toText <$> mkE2Biscuit 2 keypair
ttld <- toText <$> (addTtl later =<< mkAdminBiscuit keypair)
expd <- toText <$> (addTtl earlier =<< mkAdminBiscuit keypair)
adminB <- toText <$> mkAdminBiscuit appSecretKey
anonB <- toText <$> mkAnonBiscuit appSecretKey
e1 <- toText <$> mkE1Biscuit appSecretKey
e21 <- toText <$> mkE2Biscuit 1 appSecretKey
e22 <- toText <$> mkE2Biscuit 2 appSecretKey
ttld <- toText <$> (addTtl later =<< mkAdminBiscuit appSecretKey)
expd <- toText <$> (addTtl earlier =<< mkAdminBiscuit appSecretKey)
print adminB
hspec $
around (withApp $ app appPk) $
Expand All @@ -50,24 +49,24 @@ main = do
runC port (call1 ttld) `shouldReturn` Right 1
runC port (call1 expd) `shouldReturn` Left (Just "Biscuit failed checks")

appPrivateKey :: PrivateKey
appPrivateKey = fromJust . parsePrivateKeyHex $ "c2b7507af4f849fd028d0f7e90b04a4e74d9727b358fca18b65beffd86c47209"
appSecretKey :: SecretKey
appSecretKey = fromJust . parseSecretKeyHex $ "c2b7507af4f849fd028d0f7e90b04a4e74d9727b358fca18b65beffd86c47209"

toText :: Biscuit -> Text
toText :: BiscuitProof p => Biscuit p Verified -> Text
toText = decodeUtf8 . serializeB64

mkAdminBiscuit :: Keypair -> IO Biscuit
mkAdminBiscuit kp = mkBiscuit kp [block|right(#authority, #admin);|]
mkAdminBiscuit :: SecretKey -> IO (Biscuit Open Verified)
mkAdminBiscuit sk = mkBiscuit sk [block|right("admin");|]

mkAnonBiscuit :: Keypair -> IO Biscuit
mkAnonBiscuit kp = mkBiscuit kp [block|right(#authority, #anon);|]
mkAnonBiscuit :: SecretKey -> IO (Biscuit Open Verified)
mkAnonBiscuit sk = mkBiscuit sk [block|right("anon");|]

mkE1Biscuit :: Keypair -> IO Biscuit
mkE1Biscuit kp = mkBiscuit kp [block|right(#authority, #one);|]
mkE1Biscuit :: SecretKey -> IO (Biscuit Open Verified)
mkE1Biscuit sk = mkBiscuit sk [block|right("one");|]

mkE2Biscuit :: Int -> Keypair -> IO Biscuit
mkE2Biscuit v kp = mkBiscuit kp [block|right(#authority, #two, ${v});|]
mkE2Biscuit :: Int -> SecretKey -> IO (Biscuit Open Verified)
mkE2Biscuit v sk = mkBiscuit sk [block|right("two", ${v});|]

addTtl :: UTCTime -> Biscuit -> IO Biscuit
addTtl :: UTCTime -> Biscuit Open Verified -> IO (Biscuit Open Verified)
addTtl expiration =
addBlock [block|check if now(#ambient,$now), $now < ${expiration};|]
addBlock [block|check if time($now), $now < ${expiration};|]
6 changes: 5 additions & 1 deletion biscuit/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
.PHONY: ghcid
ghcid:
ghcid -l -c 'stack ghci biscuit-haskell:lib biscuit-haskell:biscuit-haskell-test' -T main
ghcid -l -c 'cabal repl'

.PHONY: ghcid-tests
ghcid-tests:
ghcid -l -c 'cabal repl biscuit-haskell-test' -T main

.PHONY: configure
configure:
Expand Down
2 changes: 1 addition & 1 deletion biscuit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<img src="https://raw.githubusercontent.com/divarvel/biscuit-haskell/main/assets/biscuit-logo.png" align=right>

Main library for biscuit tokens support, providing minting and signature checking of biscuit tokens, as well as a datalog engine allowing to compute the validity of a token in a given context.
Main library for biscuit tokens support, providing minting and signature verification of biscuit tokens, as well as a datalog engine allowing to compute the validity of a token in a given context.

## Supported biscuit versions

Expand Down
19 changes: 9 additions & 10 deletions biscuit/benchmarks/Bench.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@ import Criterion.Main
import Auth.Biscuit
import Data.Maybe (fromJust)

buildToken :: Keypair -> IO Biscuit
buildToken keypair = do
mkBiscuit keypair [block|user_id(#authority, "user_1234");|]
buildToken :: SecretKey -> IO (Biscuit Open Verified)
buildToken sk = do
mkBiscuit sk [block|user_id("user_1234");|]

-- Our benchmark harness.
main = do
keypair <- newKeypair
biscuit <- buildToken keypair
let pubkey = publicKey keypair
sk <- newSecret
biscuit <- buildToken sk
let pk = toPublic sk
let biscuitBs = serialize biscuit
defaultMain [
bgroup "biscuit" [ bench "mkBiscuit" $ whnfIO (buildToken keypair)
, bench "parse" $ whnf parse biscuitBs
bgroup "biscuit" [ bench "mkBiscuit" $ whnfIO (buildToken sk)
, bench "parse" $ whnf (parse pk) biscuitBs
, bench "serialize" $ whnf serialize biscuit
, bench "checkSig" $ whnfIO (checkBiscuitSignature biscuit pubkey)
, bench "verify" $ whnfIO (verifyBiscuit biscuit [verifier|allow if user_id(#authority, "user_1234");|] pubkey)
, bench "verify" $ whnfIO (authorizeBiscuit biscuit [authorizer|allow if user_id("user_1234");|])
]
]
22 changes: 11 additions & 11 deletions biscuit/biscuit-haskell.cabal
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cabal-version: 2.0

name: biscuit-haskell
version: 0.1.1.0
version: 0.2.0.0
category: Security
synopsis: Library support for the Biscuit security token
description: Please see the README on GitHub at <https://github.com/divarvel/biscuit-haskell#readme>
Expand All @@ -25,13 +25,14 @@ library
exposed-modules:
Auth.Biscuit
Auth.Biscuit.Utils
Auth.Biscuit.Crypto
Auth.Biscuit.Datalog.AST
Auth.Biscuit.Datalog.Executor
Auth.Biscuit.Datalog.Parser
Auth.Biscuit.Datalog.ScopedExecutor
Auth.Biscuit.Example
Auth.Biscuit.Proto
Auth.Biscuit.ProtoBufAdapter
Auth.Biscuit.Sel
Auth.Biscuit.Timer
Auth.Biscuit.Token
other-modules:
Expand All @@ -48,12 +49,12 @@ library
bytestring ^>= 0.10,
text ^>= 1.2,
containers ^>= 0.6,
cryptonite ^>= 0.27,
memory ^>= 0.15,
template-haskell ^>= 2.16,
attoparsec ^>= 0.13,
primitive ^>= 0.7,
base64 ^>= 0.4,
cereal ^>= 0.5,
libsodium ^>= 1.0,
mtl ^>= 2.2,
parser-combinators ^>= 1.2,
protobuf ^>= 0.2,
Expand Down Expand Up @@ -81,10 +82,8 @@ executable biscuit-haskell-exe
, bytestring
, cereal
, containers
, libsodium
, mtl
, parser-combinators
, primitive
, protobuf
, random
, template-haskell
Expand All @@ -98,20 +97,22 @@ test-suite biscuit-haskell-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
Spec.Crypto
Spec.NewCrypto
Spec.Executor
Spec.Parser
Spec.Quasiquoter
Spec.RevocationIds
Spec.Roundtrip
Spec.Samples
Spec.SampleReader
Spec.ScopedExecutor
Spec.Verification
Paths_biscuit_haskell
hs-source-dirs:
test
ghc-options: -threaded -rtsopts -with-rtsopts=-N
build-depends:
async
, aeson
, attoparsec
, base >=4.7 && <5
, base16-bytestring ^>=0.1
Expand All @@ -120,10 +121,9 @@ test-suite biscuit-haskell-test
, bytestring
, cereal
, containers
, libsodium
, cryptonite
, mtl
, parser-combinators
, primitive
, protobuf
, random
, tasty
Expand All @@ -140,7 +140,7 @@ benchmark biscuit-bench
main-is: Bench.hs
hs-source-dirs: benchmarks
default-language: Haskell2010
ghc-options: -O -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T
ghc-options: -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T
build-depends: base
, criterion
, biscuit-haskell
Loading