diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
 # flipper
 
+[![CircleCI](https://circleci.com/gh/toddmohney/flipper/tree/master.svg?style=svg)](https://circleci.com/gh/toddmohney/flipper/tree/master)
+
 A light-weight library providing an interface for minimally obtrusive feature
 toggles.
 
@@ -21,9 +23,7 @@
 
 - [Configuring feature flags from environment variables](https://github.com/toddmohney/flipper/tree/master/examples/environment-config)
 
-## Roadmap
-
-### Add storage adapters
+### Persistent storage adapters
 
-- TODO: Create Postgres adapter
-- TODO: Create Redis adapter
+If persisting your feature flags in Postgres is more your cup of tea, check
+out [Flipper Postgres](https://github.com/toddmohney/flipper-postgres)
diff --git a/feature-flipper.cabal b/feature-flipper.cabal
--- a/feature-flipper.cabal
+++ b/feature-flipper.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:                feature-flipper
-version:             0.2.0.1
+version:             0.2.1.2
 synopsis:            A minimally obtrusive feature flag library
 description:         A minimally obtrusive feature flag library
 homepage:            https://github.com/toddmohney/flipper#readme
@@ -28,7 +28,7 @@
   hs-source-dirs:
       src
   default-extensions: OverloadedStrings
-  ghc-options: -Wall -fwarn-unused-matches -fwarn-unused-binds -fwarn-unused-imports
+  ghc-options: -Wall -freverse-errors -fwarn-unused-binds -fwarn-unused-imports -fwarn-unused-matches
   exposed-modules:
       Control.Flipper
       Control.Flipper.Types
@@ -37,7 +37,9 @@
       Paths_feature_flipper
   build-depends:
       base >=4.8 && <5
+    , bytestring
     , containers
+    , digest
     , mtl
     , text
   default-language: Haskell2010
@@ -49,11 +51,14 @@
   default-extensions: OverloadedStrings
   main-is: Spec.hs
   build-depends:
-      base
+      base >=4.8 && <5
+    , bytestring
     , containers
+    , digest
+    , mtl
+    , text
     , feature-flipper
     , hspec
-    , mtl
   other-modules:
       Control.FlipperSpec
   ghc-options: -threaded -rtsopts -with-rtsopts=-N
diff --git a/src/Control/Flipper.hs b/src/Control/Flipper.hs
--- a/src/Control/Flipper.hs
+++ b/src/Control/Flipper.hs
@@ -4,14 +4,20 @@
 -}
 module Control.Flipper
     ( enabled
+    , enabledFor
     , enable
+    , enableFor
+    , enableForPercentage
     , disable
     , toggle
     , whenEnabled
+    , whenEnabledFor
     , module Control.Flipper.Types
     ) where
 
 import           Control.Monad         (when)
+import           Data.Monoid           ((<>))
+import qualified Data.Set as S
 
 import           Control.Flipper.Types
 
@@ -25,51 +31,103 @@
 whenEnabled :: (HasFeatureFlags m)
             => FeatureName -> m () -> m ()
 whenEnabled fName f = do
-    isEnabled <- enabled fName
-    when isEnabled f
+    featureEnabled <- enabled fName
+    when featureEnabled f
 
 {- |
+The 'whenEnabledFor' function calls the supplied function, 'm ()', when the given
+'FeatureName' is enabled for the given actor.
+
+When the feature specified by 'FeatureName' is disabled for the given actor,
+'m ()' is not evaluated.
+-}
+whenEnabledFor :: (HasFeatureFlags m, HasActorId a)
+               => FeatureName -> a -> m () -> m ()
+whenEnabledFor fName actor f = do
+    featureEnabled <- enabledFor fName actor
+    when featureEnabled f
+
+{- |
 The 'enabled' function returns a Bool indicating if the queried feature is
 active.
 
-When the queried FeatureName exists, the active state is returned.
-
 When the queried FeatureName does not exists, 'enabled' returns False.
 -}
 enabled :: HasFeatureFlags m
         => FeatureName -> m Bool
 enabled fName = do
-    feature <- getFeature fName
-    if feature == Just True
-        then return True
-        else return False
+    mFeature <- getFeature fName
+    case mFeature of
+        (Just feature) -> return $ isEnabled feature
+        Nothing        -> return False
 
 {- |
-The 'enable' function activates a feature.
+The 'enabledFor' function returns a Bool indicating if the queried feature is
+active for the given enitty.
 
-When the FeatureName exists in the store, it is set to active.
+If the queried FeatureName does not exists, 'enabledFor' returns False.
+-}
+enabledFor :: (HasFeatureFlags m, HasActorId a)
+           => FeatureName -> a -> m Bool
+enabledFor fName actor = do
+    mFeature <- getFeature fName
+    case mFeature of
+        Nothing        -> return False
+        (Just feature) -> return $ isEnabledFor feature actor
 
+{- |
+The 'enable' function activates a feature globally.
+
 When the FeatureName does not exist, it is created and set to active.
 -}
 enable :: ModifiesFeatureFlags m
        => FeatureName -> m ()
-enable fName = updateFeature fName True
+enable fName = upsertFeature fName True
 
 {- |
-The 'disable' function deactivates a feature.
+The 'enableFor' function activates a feature for a single actor.
 
-When the FeatureName exists in the store, it is set to inactive.
+If the FeatureName does not exist in the store, it is created and set to active
+only for the given actor.
+-}
+enableFor :: (ModifiesFeatureFlags m, HasActorId a)
+          => FeatureName -> a -> m ()
+enableFor fName actor = update fName (enableFor' actor fName)
 
+enableFor' :: HasActorId a => a -> FeatureName -> Maybe Feature -> Maybe Feature
+enableFor' actor _ (Just feature) = Just $ feature { enabledActors = S.insert (actorId actor) (enabledActors feature) }
+enableFor' actor fname Nothing = Just $ (mkFeature fname) { enabledActors = S.singleton (actorId actor) }
+
+{- |
+The 'enableForPercentage' function activates a feature for a percentage of actors.
+
+If the FeatureName does not exist in the store, it is created and set to active
+only for the specified percentage.
+-}
+enableForPercentage :: (ModifiesFeatureFlags m)
+          => FeatureName -> Percentage -> m ()
+enableForPercentage fName pct
+    | pct < 0   = raiseOutOfRangeError
+    | pct > 100 = raiseOutOfRangeError
+    | otherwise = update fName (enableForPercentage' pct fName)
+    where
+        raiseOutOfRangeError = error ("Invalid percentage: " <> show pct <> " Expected a value between 0 - 100")
+
+enableForPercentage' :: Percentage -> FeatureName -> Maybe Feature -> Maybe Feature
+enableForPercentage' pct _ (Just feature) = Just $ feature { enabledPercentage = pct }
+enableForPercentage' pct fname Nothing = Just (mkFeature fname) { enabledPercentage = pct }
+
+{- |
+The 'disable' function deactivates a feature globally.
+
 When the FeatureName does not exist, it is created and set to inactive.
 -}
 disable :: ModifiesFeatureFlags m
         => FeatureName -> m ()
-disable fName = updateFeature fName False
+disable fName = upsertFeature fName False
 
 {- |
-The 'toggle' function flips the current state of a feature.
-
-When the FeatureName exists in the store, it flips the feature state.
+The 'toggle' function flips the current state of a feature globally.
 
 When the FeatureName does not exist, it is created and set to True.
 -}
@@ -77,6 +135,20 @@
             => FeatureName -> m ()
 toggle fName = update fName flipIt'
     where
-        flipIt' :: Maybe Bool -> Maybe Bool
-        flipIt' (Just a) = Just (not a)
-        flipIt' Nothing  = Just True
+        flipIt' :: Maybe Feature -> Maybe Feature
+        flipIt' (Just feature) = Just (feature { isEnabled = not (isEnabled feature) })
+        flipIt' Nothing  = Just $ (mkFeature fName) { isEnabled = True }
+
+{- |
+When the FeatureName exists in the store, it is set to the specified `isEnabled` state.
+
+When the FeatureName does not exist, it is created and set to the specified `isEnabled` state.
+-}
+upsertFeature :: ModifiesFeatureFlags m
+              => FeatureName -> Bool -> m ()
+upsertFeature fName featureEnabled =
+    update fName upsertFeature'
+    where
+        upsertFeature' :: (Maybe Feature -> Maybe Feature)
+        upsertFeature' Nothing        = Just $ (mkFeature fName) { isEnabled = featureEnabled }
+        upsertFeature' (Just feature) = Just (feature { isEnabled = featureEnabled })
diff --git a/src/Control/Flipper/Adapters/Memory.hs b/src/Control/Flipper/Adapters/Memory.hs
--- a/src/Control/Flipper/Adapters/Memory.hs
+++ b/src/Control/Flipper/Adapters/Memory.hs
@@ -27,15 +27,14 @@
 instance (Monad m) => HasFeatureFlags (FlipperT m) where
     getFeatures = get
 
-    getFeature featureName = do
+    getFeature fname = do
         features <- unFeatures <$> getFeatures
-        return (Map.lookup featureName features)
+        return (Map.lookup fname features)
 
 instance (Monad m) => ModifiesFeatureFlags (FlipperT m) where
     updateFeatures = put
 
-    updateFeature featureName True  = update featureName (\_ -> Just True)
-    updateFeature featureName False = update featureName (\_ -> Just False)
+    updateFeature fname feature  = update fname (\_ -> Just feature)
 
 {- |
 Evaluates a feature-switched computation, returning the final value and
diff --git a/src/Control/Flipper/Types.hs b/src/Control/Flipper/Types.hs
--- a/src/Control/Flipper/Types.hs
+++ b/src/Control/Flipper/Types.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE DefaultSignatures #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE TypeFamilies      #-}
 
 {-|
@@ -7,23 +8,35 @@
 Description : Datatype and Typeclass definitions
 -}
 module Control.Flipper.Types
-    ( Features(..)
+    ( ActorId(..)
+    , Feature(..)
+    , Features(..)
     , FeatureName(..)
+    , HasActorId(..)
     , HasFeatureFlags(..)
     , ModifiesFeatureFlags(..)
+    , Percentage(..)
     , update
+    , upsert
+    , isEnabledFor
+    , mkFeature
     , mkFeatures
     ) where
 
-import           Control.Monad   (void)
+import           Control.Monad        (void)
 import           Control.Monad.Reader
 import           Control.Monad.State
-import           Data.Map.Strict (Map)
-import qualified Data.Map.Strict as Map
+import           Data.ByteString (ByteString)
+import qualified Data.Digest.CRC32    as D
+import qualified Data.List            as L
+import           Data.Map.Strict      (Map)
+import qualified Data.Map.Strict      as Map
 import           Data.Monoid
-import           Data.String     (IsString (..))
-import           Data.Text       (Text)
-import qualified Data.Text       as T
+import           Data.Set             (Set)
+import qualified Data.Set             as S
+import           Data.String          (IsString (..))
+import           Data.Text            (Text)
+import qualified Data.Text            as T
 
 {- |
 The 'HasFeatureFlags' typeclass describes how to access the Features store
@@ -33,13 +46,15 @@
     -- | 'getFeatures' access the Features store within the current monad
     getFeatures :: m Features
 
+    -- | default implementation provided to reduce boilerplate
     default getFeatures :: (MonadTrans t, HasFeatureFlags m1, m ~ t m1) => m Features
     getFeatures = lift getFeatures
 
     -- | 'getFeature' access a single Feature within the current monad
-    getFeature :: FeatureName -> m (Maybe Bool)
+    getFeature :: FeatureName -> m (Maybe Feature)
 
-    default getFeature :: (MonadTrans t, HasFeatureFlags m1, m ~ t m1) => FeatureName -> m (Maybe Bool)
+    -- | default implementation provided to reduce boilerplate
+    default getFeature :: (MonadTrans t, HasFeatureFlags m1, m ~ t m1) => FeatureName -> m (Maybe Feature)
     getFeature = lift . getFeature
 
 instance (MonadIO m, HasFeatureFlags m) => HasFeatureFlags (StateT s m)
@@ -53,28 +68,104 @@
     -- | 'updateFeatures' modifies the Features store within the current monad
     updateFeatures :: Features -> m ()
 
+    -- | default implementation provided to reduce boilerplate
     default updateFeatures :: (MonadTrans t, ModifiesFeatureFlags m1, m ~ t m1) => Features -> m ()
     updateFeatures = lift . updateFeatures
 
     -- | 'updateFeature' modifies a single Feature within the current monad
-    updateFeature :: FeatureName -> Bool -> m ()
+    updateFeature :: FeatureName -> Feature -> m ()
 
-    default updateFeature :: (MonadTrans t, ModifiesFeatureFlags m1, m ~ t m1) => FeatureName -> Bool -> m ()
-    updateFeature fName isEnabled = lift $ updateFeature fName isEnabled
+    -- | default implementation provided to reduce boilerplate
+    default updateFeature :: (MonadTrans t, ModifiesFeatureFlags m1, m ~ t m1) => FeatureName -> Feature -> m ()
+    updateFeature fName feature = lift $ updateFeature fName feature
 
 instance (MonadIO m, ModifiesFeatureFlags m) => ModifiesFeatureFlags (StateT s m)
 instance (MonadIO m, ModifiesFeatureFlags m) => ModifiesFeatureFlags (ReaderT s m)
 
 {- |
+A standardization of feature-enableable IDs.
+-}
+newtype ActorId = ActorId ByteString
+    deriving (Show, Eq, Ord, D.CRC32)
+
+{- |
+Typeclass describing how to derive an ActorId from a datatype.
+
+The resulting ActorId produced must be unique within the set of actors
+permitted to a given feature.
+
+To clarify, let's say the actor is a User and User is defined as
+@
+data User = User { id :: Int }
+@
+It's sufficient to use the `id` alone if it is unique among Users and User types
+are the only actor type using a given Feature. However, if a Feature is used by
+both `User` types and `data Admin = Admin { id :: Int }` types where IDs are _not_
+unique between types, it is recommended to avoid collisions by combining the
+type name and the ID unique to that type.
+
+For example, the implementation for `User` and Admin could be
+@
+instance HasActorId User where
+    actorId user = "User:" <> show (user id)
+
+instance HasActorId Admin where
+    actorId user = "Admin:" <> show (user id)
+@
+-}
+class HasActorId a where
+    actorId :: a -> ActorId
+
+{- |
+A type describing an access-controlled feature.
+-}
+data Feature = Feature
+    {
+    -- | the name of the feature
+      featureName     :: FeatureName
+
+    -- | flag indicating if the Feautre is globally enabled
+    , isEnabled       :: Bool
+
+    -- | a list of ActorIDs for which to enable the Feature.
+    , enabledActors :: Set ActorId
+
+    -- | the percentage of total actors for which to enable the Feature.
+    -- | 0 <= enabledPercentage <= 100
+    , enabledPercentage :: Percentage
+    } deriving (Show, Eq)
+
+{- |
+Smart constructor
+-}
+mkFeature :: FeatureName -> Feature
+mkFeature fname = Feature
+    { featureName = fname
+    , isEnabled = False
+    , enabledActors = S.empty
+    , enabledPercentage = Percentage 0
+    }
+
+newtype Percentage = Percentage Int
+    deriving (Show, Read, Eq, Ord, Num)
+
+instance Bounded Percentage where
+    minBound = Percentage 0
+    maxBound = Percentage 100
+
+{- |
 An abstraction representing the current state of the features store.
 -}
-newtype Features = Features { unFeatures :: Map FeatureName Bool }
-    deriving (Show, Eq)
+newtype Features = Features { unFeatures :: Map FeatureName Feature }
+    deriving (Show)
 
 instance Monoid Features where
     mempty = Features mempty
     mappend a b = Features (unFeatures a <> unFeatures b)
 
+mkFeatures :: Features
+mkFeatures = Features Map.empty
+
 {- |
 The main identifier of a feature
 -}
@@ -84,17 +175,37 @@
 instance IsString FeatureName where
     fromString s = FeatureName (T.pack s)
 
-{- |
-Convienience constructor
--}
-mkFeatures :: Map FeatureName Bool -> Features
-mkFeatures = Features
+upsert :: ModifiesFeatureFlags m
+       => Feature -> m ()
+upsert f = do
+    features <- unFeatures <$> getFeatures
+    void . updateFeatures . Features $ Map.insertWith mergeFeatures (featureName f) f  features
 
+mergeFeatures :: Feature -> Feature -> Feature
+mergeFeatures new old = Feature
+    { featureName = featureName new
+    , isEnabled = isEnabled new
+    , enabledActors = enabledActors old <> enabledActors new
+    , enabledPercentage = enabledPercentage new
+    }
+
 {- |
 Updates a single Feature within the current monad
 -}
 update :: ModifiesFeatureFlags m
-       => FeatureName -> (Maybe Bool -> Maybe Bool) -> m ()
+       => FeatureName -> (Maybe Feature -> Maybe Feature) -> m ()
 update fName updateFn = do
     features <- unFeatures <$> getFeatures
     void . updateFeatures . Features $ Map.alter updateFn fName features
+
+isEnabledFor :: (HasActorId a) => Feature -> a -> Bool
+isEnabledFor (Feature _ globallyEnabled actors (Percentage pct)) actor =
+    globallyEnabled
+        || inActivePercentageGroup
+        || inActiveActorsGroup
+    where
+        inActivePercentageGroup = mod (actorHash actor) 100 < pct
+        inActiveActorsGroup = actorId actor `L.elem` actors
+
+actorHash :: HasActorId a => a -> Int
+actorHash a = fromIntegral . D.crc32 $ actorId a
diff --git a/test/Control/FlipperSpec.hs b/test/Control/FlipperSpec.hs
--- a/test/Control/FlipperSpec.hs
+++ b/test/Control/FlipperSpec.hs
@@ -1,10 +1,18 @@
 module Control.FlipperSpec (main, spec) where
 
+import qualified Data.ByteString.Char8           as C8
 import qualified Data.Map.Strict                 as M
+import qualified Data.Set as S
 import           Test.Hspec
 
-import           Control.Flipper
-import           Control.Flipper.Adapters.Memory
+import Control.Flipper
+    ( ActorId(..)
+    , Features(..)
+    , Feature(..)
+    , HasActorId(..)
+    )
+import qualified Control.Flipper as F
+import qualified Control.Flipper.Adapters.Memory as FM
 
 main :: IO ()
 main = hspec spec
@@ -14,43 +22,111 @@
     describe "whenEnabled" $ do
         context "the feature is enabled" $
             it "evaluates the given monad" $ do
-              let featureState = mkFeatures $ M.insert "ADD_ANOTHER_FEATURE" True mempty
-              store <- execFlipperT featureState (whenEnabled "ADD_ANOTHER_FEATURE" (enable "ANOTHER_FEATURE"))
-              M.lookup "ANOTHER_FEATURE" (unFeatures store) `shouldBe` Just True
+                let feature = (F.mkFeature "ADD_ANOTHER_FEATURE") { isEnabled = True }
+                let featureState = Features $ M.singleton (featureName feature) feature
+                store <- FM.execFlipperT featureState (F.whenEnabled "ADD_ANOTHER_FEATURE" (F.enable "ANOTHER_FEATURE"))
+                M.lookup "ANOTHER_FEATURE" (unFeatures store) `shouldBe` Just (F.mkFeature "ANOTHER_FEATURE") { isEnabled = True }
 
         context "the feature is disabled" $
             it "does not evaluate the given monad" $ do
-                let featureState = mkFeatures $ M.insert "ADD_ANOTHER_FEATURE" False mempty
-                store <- execFlipperT featureState (whenEnabled "ADD_ANOTHER_FEATURE" (enable "ANOTHER_FEATURE"))
+                let feature = (F.mkFeature "ADD_ANOTHER_FEATURE") { isEnabled = False }
+                let featureState = Features $ M.singleton (featureName feature) feature
+                store <- FM.execFlipperT featureState (F.whenEnabled "ADD_ANOTHER_FEATURE" (F.enable "ANOTHER_FEATURE"))
                 M.lookup "ANOTHER_FEATURE" (unFeatures store) `shouldBe` Nothing
 
+    describe "whenEnabledFor" $ do
+        context "the feature is enabled globally" $
+            it "evaluates the given monad" $ do
+                let feature = (F.mkFeature "ADD_ANOTHER_FEATURE") { isEnabled = True }
+                let featureState = Features $ M.singleton (featureName feature) feature
+                store <- FM.execFlipperT featureState (F.whenEnabledFor "ADD_ANOTHER_FEATURE" myActor (F.enable "ANOTHER_FEATURE"))
+                M.lookup "ANOTHER_FEATURE" (unFeatures store) `shouldBe` Just (F.mkFeature "ANOTHER_FEATURE") { isEnabled = True }
+
+        context "the feature is enabled for the given actor" $
+            it "evaluates the given monad" $ do
+                let feature = (F.mkFeature "ADD_ANOTHER_FEATURE") { enabledActors = S.singleton (actorId myActor), isEnabled = False }
+                let featureState = Features $ M.singleton (featureName feature) feature
+                store <- FM.execFlipperT featureState (F.whenEnabledFor "ADD_ANOTHER_FEATURE" myActor (F.enable "ANOTHER_FEATURE"))
+                M.lookup "ANOTHER_FEATURE" (unFeatures store) `shouldBe` Just (F.mkFeature "ANOTHER_FEATURE") { isEnabled = True }
+
+        context "the feature is not enabled for the given actor" $
+            it "does not evaluate the given monad" $ do
+                let feature = F.mkFeature "ADD_ANOTHER_FEATURE"
+                let featureState = Features $ M.singleton (featureName feature) feature
+                store <- FM.execFlipperT featureState (F.whenEnabledFor "ADD_ANOTHER_FEATURE" myActor (F.enable "ANOTHER_FEATURE"))
+                M.lookup "ANOTHER_FEATURE" (unFeatures store) `shouldBe` Nothing
+
     describe "enable" $ do
         it "enables a new feature key" $
             let
                 featureState = mempty :: Features
-                result = evalFlipperT featureState (enable "NEW_FEATURE" >> enabled "NEW_FEATURE")
+                result = FM.evalFlipperT featureState (F.enable "NEW_FEATURE" >> F.enabled "NEW_FEATURE")
             in
                 result `shouldReturn` True
 
         it "enables a existing feature key" $
             let
-                featureState = mkFeatures $ M.insert "FEATURE" False mempty
-                result = evalFlipperT featureState (enable "FEATURE" >> enabled "FEATURE")
+                feature = (F.mkFeature "FEATURE") { isEnabled = False }
+                featureState = Features $ M.singleton (featureName feature) feature
+                result = FM.evalFlipperT featureState (F.enable "FEATURE" >> F.enabled "FEATURE")
             in
                 result `shouldReturn` True
 
+    describe "enableFor" $ do
+        describe "with an existing feature" $ do
+            it "enables the feature only for the given actor" $ do
+                let feature = F.mkFeature "FEATURE"
+                let featureState = Features $ M.singleton (featureName feature) feature
+                let result1 = FM.evalFlipperT featureState (F.enableFor "FEATURE" myActor >> F.enabledFor "FEATURE" myActor)
+                let result2 = FM.evalFlipperT featureState (F.enableFor "FEATURE" myActor >> F.enabledFor "FEATURE" myOtherActor)
+
+                result1 `shouldReturn` True
+                result2 `shouldReturn` False
+
+        describe "with a non-existant feature" $ do
+            it "enables the feature only for the given actor" $ do
+                let featureState = mempty :: Features
+                let result1 = FM.evalFlipperT featureState (F.enableFor "FEATURE" myActor >> F.enabledFor "FEATURE" myActor)
+                let result2 = FM.evalFlipperT featureState (F.enableFor "FEATURE" myActor >> F.enabledFor "FEATURE" myOtherActor)
+
+                result1 `shouldReturn` True
+                result2 `shouldReturn` False
+
+    describe "enabledFor" $ do
+        it "returns True if the feature is enabled globally" $ do
+            let feature = (F.mkFeature "FEATURE") { isEnabled = True }
+            let featureState = Features $ M.singleton (featureName feature) feature
+            let result = FM.evalFlipperT featureState (F.enabledFor "FEATURE" myActor)
+
+            result `shouldReturn` True
+
+        it "returns True if the feature is enabled for the actor" $ do
+            let feature = (F.mkFeature "FEATURE") { enabledActors = S.singleton (actorId myActor), isEnabled = False }
+            let featureState = Features $ M.singleton (featureName feature) feature
+            let result = FM.evalFlipperT featureState (F.enabledFor "FEATURE" myActor)
+
+            result `shouldReturn` True
+
+        it "returns False if the feature is not enabled for this actor" $ do
+            let feature = F.mkFeature "FEATURE"
+            let featureState = Features $ M.singleton (featureName feature) feature
+            let result = FM.evalFlipperT featureState (F.enabledFor "FEATURE" myActor)
+
+            result `shouldReturn` False
+
     describe "disable" $ do
         it "disables a new feature key" $
             let
                 featureState = mempty :: Features
-                result = evalFlipperT featureState (disable "NEW_FEATURE" >> enabled "NEW_FEATURE")
+                result = FM.evalFlipperT featureState (F.disable "NEW_FEATURE" >> F.enabled "NEW_FEATURE")
             in
                 result `shouldReturn` False
 
         it "disables a existing feature key" $
             let
-                featureState = mkFeatures $ M.insert "FEATURE" True mempty
-                result = evalFlipperT featureState (disable "FEATURE" >> enabled "FEATURE")
+                feature = (F.mkFeature "FEATURE") { isEnabled = True }
+                featureState = Features $ M.singleton (featureName feature) feature
+                result = FM.evalFlipperT featureState (F.disable "FEATURE" >> F.enabled "FEATURE")
             in
                 result `shouldReturn` False
 
@@ -58,42 +134,59 @@
         it "enables a new feature key" $
             let
                 featureState = mempty :: Features
-                result = evalFlipperT featureState (toggle "NEW_FEATURE" >> enabled "NEW_FEATURE")
+                result = FM.evalFlipperT featureState (F.toggle "NEW_FEATURE" >> F.enabled "NEW_FEATURE")
             in
                 result `shouldReturn` True
 
         it "enables a disabled feature key" $
             let
-                featureState = mkFeatures $ M.insert "FEATURE" False mempty
-                result = evalFlipperT featureState (toggle "FEATURE" >> enabled "FEATURE")
+                feature = (F.mkFeature "FEATURE") { isEnabled = False }
+                featureState = Features $ M.singleton (featureName feature) feature
+                result = FM.evalFlipperT featureState (F.toggle "FEATURE" >> F.enabled "FEATURE")
             in
                 result `shouldReturn` True
 
         it "disables a enabled feature key" $
             let
-                featureState = mkFeatures $ M.insert "FEATURE" True mempty
-                result = evalFlipperT featureState (toggle "FEATURE" >> enabled "FEATURE")
+                feature = (F.mkFeature "FEATURE") { isEnabled = True }
+                featureState = Features $ M.singleton (featureName feature) feature
+                result = FM.evalFlipperT featureState (F.toggle "FEATURE" >> F.enabled "FEATURE")
             in
                 result `shouldReturn` False
 
     describe "enabled" $ do
         it "returns True when the feature is enabled" $
             let
-                featureState = mkFeatures $ M.insert "ENABLED_FEATURE" True mempty
-                result = evalFlipperT featureState (enabled "ENABLED_FEATURE")
+                feature = (F.mkFeature "ENABLED_FEATURE") { isEnabled = True }
+                featureState = Features $ M.singleton (featureName feature) feature
+                result = FM.evalFlipperT featureState (F.enabled "ENABLED_FEATURE")
             in
                 result `shouldReturn` True
 
         it "returns False when the feature is not enabled" $
             let
-                featureState = mkFeatures $ M.insert "DISABLED_FEATURE" False mempty
-                result = evalFlipperT featureState (enabled "DISABLED_FEATURE")
+                feature = (F.mkFeature "DISABLED_FEATURE") { isEnabled = False }
+                featureState = Features $ M.singleton (featureName feature) feature
+                result = FM.evalFlipperT featureState (F.enabled "DISABLED_FEATURE")
             in
                 result `shouldReturn` False
 
         it "returns False when the feature key is not found" $
             let
                 featureState = mempty :: Features
-                result = evalFlipperT featureState (enabled "NON_EXISTANT_FEATURE")
+                result = FM.evalFlipperT featureState (F.enabled "NON_EXISTANT_FEATURE")
             in
                 result `shouldReturn` False
+
+newtype TestActor = TestActor
+    { myId :: Int
+    } deriving (Show, Eq)
+
+instance HasActorId TestActor where
+    actorId actor = ActorId . C8.pack . show $ myId actor
+
+myActor :: TestActor
+myActor = TestActor 1
+
+myOtherActor :: TestActor
+myOtherActor = TestActor 2
