Untrusted code

Safe Haskell

Safe vs. Trustworthy

What if untrusted code needs to do IO?

Example: hypothetical RIO monad

{-# LANGUAGE Trustworthy #-}
module RIO (RIO(), runRIO, RIO.readFile) where

-- Notice that symbol UnsafeRIO is not exported from this module!
newtype RIO a = UnsafeRIO { runRIO :: IO a }
instance Monad RIO where
return = UnsafeRIO . return
m >>= k = UnsafeRIO $ runRIO m >>= runRIO . k

-- Returns True iff access is allowed to file name
pathOK :: FilePath -> IO Bool
pathOK file = {- Implement some policy based on file name -}

readFile :: FilePath -> RIO String
readFile file = UnsafeRIO $ do
ok <- pathOK file
if ok then Prelude.readFile file else return ""

Example policies for RIO

Why RIO isn't enough

What is DIFC?

What is DIFC?

What is DIFC?

Labels are transitive

Labels are transitive

Labels are transitive

Labels are transitive

Labels form a lattice

DIFC is Decentralized

Example privileges

The Sec monad [Russo], [Russo]

The Sec monad (continued)

Applying the Sec monad

IO and Sec

IO and Sec

The SecIO monad

SecIO translator

LIO Monad [Stefan]

Need pure, side-effectful computations

Other LIO features