diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -7,6 +7,18 @@
 
 ## Unreleased
 
+## [0.1.2] - 2018-09-27
+
+### Changed
+
+- #132 error handling for readProcess invocations @domenkozar
+- #130 only warn about not supporting groups if user is not trusted @domenkozar
+- #128 Generate https://cache.nixos.org when run as root on NixOS @yegortimoschenko
+- #121 bail out if narSize is 0 @domenkozar
+- #123 support passing --config @domenkozar
+- #123 no more spurious warning messages when using "cachix use" @domenkozar
+- #105 pass https://cache.nixos.org explicitly @domenkozar
+
 ## [0.1.1] - 2018-08-03
 
 ### Added
diff --git a/cachix.cabal b/cachix.cabal
--- a/cachix.cabal
+++ b/cachix.cabal
@@ -1,11 +1,13 @@
--- This file has been generated from package.yaml by hpack version 0.28.2.
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.31.0.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: ab3acbad7328ef095ad03032f8457a46c65d54e21216423686c3a91d85a7b79a
+-- hash: 098d91889f12eca7fc2fd5f1197c1ec823f43b19fd5be38a630ea965ce99dae8
 
 name:           cachix
-version:        0.1.1
+version:        0.1.2
 synopsis:       Command line client for Nix binary cache hosting https://cachix.org
 homepage:       https://github.com/cachix/cachix#readme
 bug-reports:    https://github.com/cachix/cachix/issues
@@ -15,10 +17,9 @@
 license:        Apache-2.0
 license-file:   LICENSE
 build-type:     Simple
-cabal-version:  >= 1.10
 extra-source-files:
-    ChangeLog.md
     README.md
+    ChangeLog.md
 
 source-repository head
   type: git
@@ -29,6 +30,7 @@
       Cachix.Client
       Cachix.Client.Commands
       Cachix.Client.Config
+      Cachix.Client.Env
       Cachix.Client.InstallationMode
       Cachix.Client.NixConf
       Cachix.Client.NixVersion
@@ -39,7 +41,7 @@
       Paths_cachix
   hs-source-dirs:
       src
-  default-extensions: OverloadedStrings NoImplicitPrelude RecordWildCards
+  default-extensions: OverloadedStrings NoImplicitPrelude RecordWildCards DeriveGeneric
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -fwarn-tabs -fwarn-unused-imports -fwarn-missing-signatures -fwarn-name-shadowing -fwarn-incomplete-patterns
   build-depends:
       async
@@ -56,6 +58,7 @@
     , dhall
     , directory
     , ed25519
+    , filepath
     , fsnotify
     , here
     , http-client
@@ -70,6 +73,7 @@
     , process
     , protolude
     , resourcet
+    , safe-exceptions
     , servant >=0.14.1
     , servant-auth
     , servant-auth-client >=0.3.3.0
@@ -89,7 +93,7 @@
       Paths_cachix
   hs-source-dirs:
       cachix
-  default-extensions: OverloadedStrings NoImplicitPrelude RecordWildCards
+  default-extensions: OverloadedStrings NoImplicitPrelude RecordWildCards DeriveGeneric
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -fwarn-tabs -fwarn-unused-imports -fwarn-missing-signatures -fwarn-name-shadowing -fwarn-incomplete-patterns -threaded -rtsopts -with-rtsopts=-N
   build-depends:
       async
@@ -107,6 +111,7 @@
     , dhall
     , directory
     , ed25519
+    , filepath
     , fsnotify
     , here
     , http-client
@@ -121,6 +126,7 @@
     , process
     , protolude
     , resourcet
+    , safe-exceptions
     , servant >=0.14.1
     , servant-auth
     , servant-auth-client >=0.3.3.0
@@ -146,7 +152,7 @@
       Paths_cachix
   hs-source-dirs:
       test
-  default-extensions: OverloadedStrings NoImplicitPrelude RecordWildCards
+  default-extensions: OverloadedStrings NoImplicitPrelude RecordWildCards DeriveGeneric
   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -fwarn-tabs -fwarn-unused-imports -fwarn-missing-signatures -fwarn-name-shadowing -fwarn-incomplete-patterns -threaded -rtsopts -with-rtsopts=-N
   build-depends:
       async
@@ -164,6 +170,7 @@
     , dhall
     , directory
     , ed25519
+    , filepath
     , fsnotify
     , here
     , hspec
@@ -179,6 +186,7 @@
     , process
     , protolude
     , resourcet
+    , safe-exceptions
     , servant >=0.14.1
     , servant-auth
     , servant-auth-client >=0.3.3.0
diff --git a/cachix/Main.hs b/cachix/Main.hs
--- a/cachix/Main.hs
+++ b/cachix/Main.hs
@@ -21,5 +21,6 @@
     handler :: SomeException -> IO a
     handler e = do
       hPutStrLn stderr ""
+      -- TODO: pretty print the record once fixed https://github.com/haskell-servant/servant/issues/807
       hPrint stderr e
       exitFailure
diff --git a/src/Cachix/Client.hs b/src/Cachix/Client.hs
--- a/src/Cachix/Client.hs
+++ b/src/Cachix/Client.hs
@@ -2,40 +2,20 @@
   ( main
   ) where
 
-import Data.Version                (showVersion)
-import Paths_cachix                (version)
 import Protolude
-import Network.HTTP.Simple         ( setRequestHeader )
-import Network.HTTP.Client.TLS     ( newTlsManagerWith, tlsManagerSettings )
-import Network.HTTP.Client         ( managerResponseTimeout, managerModifyRequest
-                                   , responseTimeoutNone, ManagerSettings)
-import Servant.Client              ( mkClientEnv)
 
-import Cachix.Client.OptionsParser ( CachixCommand(..), CachixOptions(..), getOpts )
-import Cachix.Client.Config        ( readConfig )
+import Cachix.Client.OptionsParser ( CachixCommand(..), getOpts )
 import Cachix.Client.Commands      as Commands
-import Cachix.Client.URI           ( getBaseUrl)
+import Cachix.Client.Env           ( mkEnv, cachixVersion )
 
 
 main :: IO ()
 main = do
-  (CachixOptions{..}, command) <- getOpts
-  config <- readConfig
-  manager <- newTlsManagerWith customManagerSettings
-  let env = mkClientEnv manager $ getBaseUrl host
-  case command of -- TODO: might want readerT here with client, config and env and opts
-    AuthToken token -> Commands.authtoken env config token
-    Create name -> Commands.create env config name
-    Push name paths watchStore -> Commands.push env config name paths watchStore
-    Use name shouldEchoNixOS -> Commands.use env config name shouldEchoNixOS
+  (cachixoptions, command) <- getOpts
+  env <- mkEnv cachixoptions
+  case command of
+    AuthToken token -> Commands.authtoken env token
+    Create name -> Commands.create env name
+    Push name paths watchStore -> Commands.push env name paths watchStore
+    Use name shouldEchoNixOS -> Commands.use env name shouldEchoNixOS
     Version -> putText cachixVersion
-
-customManagerSettings :: ManagerSettings
-customManagerSettings = tlsManagerSettings
-  { managerResponseTimeout = responseTimeoutNone
-  -- managerModifyRequest :: Request -> IO Request
-  , managerModifyRequest = return . setRequestHeader "User-Agent" [toS cachixVersion]
-  }
-
-cachixVersion :: Text
-cachixVersion = "cachix " <> toS (showVersion version)
diff --git a/src/Cachix/Client/Commands.hs b/src/Cachix/Client/Commands.hs
--- a/src/Cachix/Client/Commands.hs
+++ b/src/Cachix/Client/Commands.hs
@@ -14,6 +14,7 @@
 import qualified Control.Concurrent.QSem       as QSem
 import           Control.Concurrent.Async     (mapConcurrently)
 import           Control.Monad                (forever)
+import           Control.Exception.Safe       (MonadThrow, throwM)
 import           Control.Monad.Trans.Resource (ResourceT)
 import qualified Data.ByteString.Base64        as B64
 import           Data.Conduit
@@ -37,22 +38,23 @@
 import           System.Directory               ( doesFileExist )
 import           System.FSNotify
 import           System.IO                      ( stdin, hIsTerminalDevice )
-import           System.Process                 ( readProcessWithExitCode, readProcess )
+import           System.Process                 ( readProcess )
 import           System.Environment             ( lookupEnv )
 import qualified Streaming.Prelude             as S
 
 import qualified Cachix.Api                    as Api
 import           Cachix.Api.Signing             (fingerprint, passthroughSizeSink, passthroughHashSink)
+import qualified Cachix.Types.NarInfoCreate    as Api
 import           Cachix.Client.Config           ( Config(..)
                                                 , BinaryCacheConfig(..)
                                                 , writeConfig
                                                 , mkConfig
                                                 )
 import qualified Cachix.Client.Config          as Config
+import           Cachix.Client.Env              ( Env(..) )
+import           Cachix.Client.OptionsParser    ( CachixOptions(..) )
 import           Cachix.Client.InstallationMode
-import           Cachix.Client.NixVersion       ( getNixVersion
-                                                , NixVersion
-                                                )
+import           Cachix.Client.NixVersion       ( getNixVersion )
 import qualified Cachix.Client.NixConf         as NixConf
 import           Cachix.Client.Servant
 
@@ -63,10 +65,10 @@
 cachixBCClient :: Text -> Api.BinaryCacheAPI (AsClientT ClientM)
 cachixBCClient name = fromServant $ Api.cache cachixClient name
 
-authtoken :: ClientEnv -> Maybe Config -> Text -> IO ()
-authtoken _ maybeConfig token = do
+authtoken :: Env -> Text -> IO ()
+authtoken env token = do
   -- TODO: check that token actually authenticates!
-  writeConfig $ case maybeConfig of
+  writeConfig (configPath (cachixoptions env)) $ case config env of
     Just config -> config { authToken = token }
     Nothing -> mkConfig token
   putStrLn ([hereLit|
@@ -77,13 +79,13 @@
 and share it with others over https://<name>.cachix.org
   |] :: Text)
 
-create :: ClientEnv -> Maybe Config -> Text -> IO ()
-create _ Nothing _ = throwIO $ NoConfig "start with: $ cachix authtoken <token>"
-create env (Just config@Config{..}) name = do
+create :: Env -> Text -> IO ()
+create Env { config = Nothing } _ = throwIO $ NoConfig "start with: $ cachix authtoken <token>"
+create env@Env { config = Just config } name = do
   (PublicKey pk, SecretKey sk) <- createKeypair
 
   let bc = Api.BinaryCacheCreate $ toS $ B64.encode pk
-  res <- (`runClientM` env) $ Api.create (cachixBCClient name) (Token (toS authToken)) bc
+  res <- (`runClientM` clientenv env) $ Api.create (cachixBCClient name) (Token (toS (authToken config))) bc
   case res of
     -- TODO: handle all kinds of errors
     Left err -> panic $ show err
@@ -91,8 +93,10 @@
       -- write signing key to config
       let signingKey = toS $ B64.encode sk
           bcc = BinaryCacheConfig name signingKey
-      writeConfig $ config { binaryCaches = binaryCaches <> [bcc] }
 
+      writeConfig (configPath (cachixoptions env)) $
+        config { binaryCaches = binaryCaches config <> [bcc] }
+
       putStrLn ([iTrim|
 Signing key has been saved on your local machine. To populate
 your binary cache:
@@ -110,10 +114,10 @@
 
       |] :: Text)
 
-use :: ClientEnv -> Maybe Config -> Text -> Bool -> IO ()
-use env _ name shouldEchoNixOS = do
+use :: Env -> Text -> Bool -> IO ()
+use env name shouldEchoNixOS = do
   -- 1. get cache public key
-  res <- (`runClientM` env) $ Api.get (cachixBCClient name)
+  res <- (`runClientM` clientenv env) $ Api.get (cachixBCClient name)
   case res of
     -- TODO: handle 404
     Left err -> panic $ show err
@@ -139,8 +143,8 @@
 
 
 -- TODO: lots of room for perfomance improvements
-push :: ClientEnv -> Maybe Config -> Text -> [Text] -> Bool -> IO ()
-push env config name rawPaths False = do
+push :: Env -> Text -> [Text] -> Bool -> IO ()
+push env name rawPaths False = do
   hasNoStdin <- hIsTerminalDevice stdin
   when (not hasNoStdin && not (null rawPaths)) $ throwIO $ AmbiguousInput "You provided both stdin and store path arguments, pick only one to proceed."
   inputStorePaths <-
@@ -153,12 +157,12 @@
 
   -- Query list of paths
   -- TODO: split args if too big
-  (exitcode, out, err) <- readProcessWithExitCode "nix-store" (fmap toS (["-qR"] <> inputStorePaths)) mempty
+  paths <- T.lines . toS <$> readProcess "nix-store" (fmap toS (["-qR"] <> inputStorePaths)) mempty
 
   -- TODO: make pool size configurable, on beefier machines this could be doubled
-  _ <- mapConcurrentlyBounded 4 (pushStorePath env config name) (T.lines (toS out))
+  _ <- mapConcurrentlyBounded 4 (pushStorePath env name) paths
   putText "All done."
-push env config name _ True = withManager $ \mgr -> do
+push env name _ True = withManager $ \mgr -> do
   _ <- watchDir mgr "/nix/store" filterF action
   putText "Watching /nix/store for new builds ..."
   forever $ threadDelay 1000000
@@ -169,7 +173,7 @@
 #else
     action (Removed fp _) =
 #endif
-      pushStorePath env config name $ toS $ dropEnd 5 fp
+      pushStorePath env name $ toS $ dropEnd 5 fp
     action _ = return ()
 
     filterF :: ActionPredicate
@@ -184,12 +188,12 @@
     dropEnd :: Int -> [a] -> [a]
     dropEnd index xs = take (length xs - index) xs
 
-pushStorePath :: ClientEnv -> Maybe Config -> Text -> Text -> IO ()
-pushStorePath env config name storePath = do
+pushStorePath :: Env -> Text -> Text -> IO ()
+pushStorePath env name storePath = do
   -- use secret key from config or env
   maybeEnvSK <- lookupEnv "CACHIX_SIGNING_KEY"
   let matches Config{..} = filter (\bc -> Config.name bc == name) binaryCaches
-      maybeBCSK = case config of
+      maybeBCSK = case config env of
         Nothing -> Nothing
         Just c -> Config.secretKey <$> head (matches c)
       -- TODO: better error msg
@@ -197,7 +201,7 @@
       (storeHash, _) = splitStorePath $ toS storePath
   -- Check if narinfo already exists
   -- TODO: query also cache.nixos.org? server-side?
-  res <- (`runClientM` env) $ Api.narinfoHead
+  res <- (`runClientM` clientenv env) $ Api.narinfoHead
     (cachixBCClient name)
     (Api.NarInfoC storeHash)
   case res of
@@ -215,9 +219,10 @@
         fileHashRef <- liftIO $ newIORef ("" :: Text)
 
         -- stream store path as xz compressed nar file
-        (ClosedStream, (source, close), ClosedStream, cph) <- streamingProcess $ shell ("nix-store --dump " <> toS storePath)
+        let cmd = proc "nix-store" ["--dump", toS storePath]
+        (ClosedStream, (stdoutStream, closeStdout), ClosedStream, cph) <- streamingProcess cmd
         let stream'
-              = source
+              = stdoutStream
              .| passthroughSizeSink narSizeRef
              .| passthroughHashSink narHashRef
              .| compress Nothing
@@ -227,61 +232,67 @@
             conduitToStreaming :: S.Stream (S.Of ByteString) (ResourceT IO) ()
             conduitToStreaming = runConduit (transPipe lift stream' .| CL.mapM_ S.yield)
         -- for now we need to use letsencrypt domain instead of cloudflare due to its upload limits
-        let newEnv = env {
-              baseUrl = (baseUrl env) { baseUrlHost = toS name <> "." <> baseUrlHost (baseUrl env)}
+        let newClientEnv = (clientenv env) {
+              baseUrl = (baseUrl (clientenv env)) { baseUrlHost = toS name <> "." <> baseUrlHost (baseUrl (clientenv env))}
             }
         -- TODO: http retry: retry package?
-        res <- (`runClientM` newEnv) $ Api.createNar
+        NoContent <- escalate <=< (`runClientM` newClientEnv) $ Api.createNar
           (cachixBCClient name)
           (contentType (Proxy :: Proxy Api.XNixNar), conduitToStreaming)
-        close
+        closeStdout
         exitcode <- waitForStreamingProcess cph
-        case res of
-          Left err -> panic $ show err
-          Right NoContent -> do
-            narSize <- readIORef narSizeRef
-            narHashB16 <- readIORef narHashRef
-            fileHash <- readIORef fileHashRef
-            fileSize <- readIORef fileSizeRef
+        -- TODO: print process stderr?
+        when (exitcode /= ExitSuccess) $
+          panic $ "Failed with " <> show exitcode <> ": " <> show cmd
 
-            -- TODO: #3: implement using pure haskell
-            narHash <- ("sha256:" <>) . T.strip . toS <$> readProcess "nix-hash" ["--type", "sha256", "--to-base32", toS narHashB16] mempty
+        narSize <- readIORef narSizeRef
+        narHashB16 <- readIORef narHashRef
+        fileHash <- readIORef fileHashRef
+        fileSize <- readIORef fileSizeRef
 
-            (exitcode, out, err) <- readProcessWithExitCode "nix-store" ["-q", "--deriver", toS storePath] mempty
-            let deriverRaw = T.strip $ toS out
-                deriver = if deriverRaw == "unknown-deriver"
-                          then deriverRaw
-                          else T.drop 11 deriverRaw
+        -- TODO: #3: implement using pure haskell
+        narHash <- ("sha256:" <>) . T.strip . toS <$> readProcess "nix-hash" ["--type", "sha256", "--to-base32", toS narHashB16] mempty
 
-            (exitcode, out, err) <- readProcessWithExitCode "nix-store" ["-q", "--references", toS storePath] mempty
+        deriverRaw <- T.strip . toS <$> readProcess "nix-store" ["-q", "--deriver", toS storePath] mempty
+        let deriver = if deriverRaw == "unknown-deriver"
+                      then deriverRaw
+                      else T.drop 11 deriverRaw
 
-            let
-                references = sort $ T.lines $ T.strip $ toS out
-                fp = fingerprint storePath narHash narSize references
-                sig = dsign sk fp
-                nic = Api.NarInfoCreate
-                  { cStoreHash = storeHash
-                  , cStoreSuffix = storeSuffix
-                  , cNarHash = narHash
-                  , cNarSize = narSize
-                  , cFileSize = fileSize
-                  , cFileHash = fileHash
-                  , cReferences = fmap (T.drop 11) references
-                  , cDeriver = deriver
-                  , cSig = toS $ B64.encode $ unSignature sig
-                  }
-            -- Upload narinfo with signature
-            res <- (`runClientM` env) $ Api.createNarinfo
-              (cachixBCClient name)
-              (Api.NarInfoC storeHash)
-              nic
-            case res of
-              Left err -> panic $ show err -- TODO: handle json errors
-              Right NoContent -> return ()
+        references <- sort . T.lines . T.strip . toS <$> readProcess "nix-store" ["-q", "--references", toS storePath] mempty
 
+        let
+            fp = fingerprint storePath narHash narSize references
+            sig = dsign sk fp
+            nic = Api.NarInfoCreate
+              { cStoreHash = storeHash
+              , cStoreSuffix = storeSuffix
+              , cNarHash = narHash
+              , cNarSize = narSize
+              , cFileSize = fileSize
+              , cFileHash = fileHash
+              , cReferences = fmap (T.drop 11) references
+              , cDeriver = deriver
+              , cSig = toS $ B64.encode $ unSignature sig
+              }
 
+        escalate $ Api.isNarInfoCreateValid nic
+
+        -- Upload narinfo with signature
+        NoContent <- escalate <=< (`runClientM` clientenv env) $ Api.createNarinfo
+          (cachixBCClient name)
+          (Api.NarInfoC storeHash)
+          nic
+        return ()
+
+
 -- Utils
 
+-- TODO: should one error abort the whole pushing process? Or do a retry? Or keep going and then fail?
+escalate :: (Exception exc, MonadThrow m) => Either exc a -> m a
+escalate = escalateAs identity
+
+escalateAs :: (Exception exc, MonadThrow m) => (l -> exc) -> Either l a -> m a
+escalateAs f = either (throwM . f) pure
 
 mapConcurrentlyBounded :: Traversable t => Int -> (a -> IO b) -> t a -> IO (t b)
 mapConcurrentlyBounded bound action items = do
diff --git a/src/Cachix/Client/Config.hs b/src/Cachix/Client/Config.hs
--- a/src/Cachix/Client/Config.hs
+++ b/src/Cachix/Client/Config.hs
@@ -1,10 +1,11 @@
-{-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE DeriveAnyClass #-}
 module Cachix.Client.Config
   ( Config(..)
   , BinaryCacheConfig(..)
   , readConfig
   , writeConfig
+  , getDefaultFilename
+  , ConfigPath
   , mkConfig
   ) where
 
@@ -16,6 +17,7 @@
                         )
 import System.Posix.Files ( setFileMode, unionFileModes, ownerReadMode
                           , ownerWriteMode )
+import System.FilePath.Posix ( takeDirectory )
 import Protolude
 
 
@@ -35,30 +37,29 @@
   , binaryCaches = []
   }
 
-readConfig :: IO (Maybe Config)
-readConfig = do
-  filename <- getFilename
+type ConfigPath = FilePath
+
+readConfig :: ConfigPath -> IO (Maybe Config)
+readConfig filename = do
   doesExist <- doesFileExist filename
   if doesExist
   then Just <$> input auto (toS filename)
   else return Nothing
 
-
-getFilename :: IO FilePath
-getFilename = do
+getDefaultFilename :: IO FilePath
+getDefaultFilename = do
   dir <- getXdgDirectory XdgConfig "cachix"
-  createDirectoryIfMissing True dir
   return $ dir <> "/cachix.dhall"
 
-writeConfig :: Config -> IO ()
-writeConfig config = do
-  filename <- getFilename
+writeConfig :: ConfigPath -> Config -> IO ()
+writeConfig filename config = do
   let doc = prettyExpr $ embed inject config
+  createDirectoryIfMissing True (takeDirectory filename)
   writeFile filename $ show doc
   assureFilePermissions filename
   putStrLn $ "Written to " <> filename
 
--- Does: chmod rw file
+-- chmod rw filepath
 assureFilePermissions :: FilePath -> IO ()
 assureFilePermissions fp =
   setFileMode fp $ unionFileModes ownerReadMode ownerWriteMode
diff --git a/src/Cachix/Client/Env.hs b/src/Cachix/Client/Env.hs
new file mode 100644
--- /dev/null
+++ b/src/Cachix/Client/Env.hs
@@ -0,0 +1,53 @@
+module Cachix.Client.Env
+  ( Env(..)
+  , mkEnv
+  , cachixVersion
+  ) where
+
+import Protolude
+
+import Data.Version                (showVersion)
+import Paths_cachix                (version)
+
+import Network.HTTP.Simple         ( setRequestHeader )
+import Network.HTTP.Client.TLS     ( newTlsManagerWith, tlsManagerSettings )
+import Network.HTTP.Client         ( managerResponseTimeout, managerModifyRequest
+                                   , responseTimeoutNone, ManagerSettings)
+import Servant.Client              ( mkClientEnv, ClientEnv )
+import System.Directory            ( canonicalizePath )
+
+import Cachix.Client.Config        ( readConfig, Config )
+import Cachix.Client.OptionsParser ( CachixOptions(..) )
+import Cachix.Client.URI           ( getBaseUrl )
+
+
+data Env = Env
+  { config :: Maybe Config
+  , clientenv :: ClientEnv
+  , cachixoptions :: CachixOptions
+  }
+
+
+mkEnv :: CachixOptions -> IO Env
+mkEnv rawcachixoptions = do
+  -- make sure path to the config is passed as absolute to dhall logic
+  canonicalConfigPath <- canonicalizePath (configPath rawcachixoptions)
+  let cachixoptions = rawcachixoptions { configPath = canonicalConfigPath }
+  config <- readConfig $ configPath cachixoptions
+  manager <- newTlsManagerWith customManagerSettings
+  let clientenv = mkClientEnv manager $ getBaseUrl (host cachixoptions)
+  return Env
+    { config = config
+    , clientenv = clientenv
+    , cachixoptions = cachixoptions
+    }
+
+customManagerSettings :: ManagerSettings
+customManagerSettings = tlsManagerSettings
+  { managerResponseTimeout = responseTimeoutNone
+  -- managerModifyRequest :: Request -> IO Request
+  , managerModifyRequest = return . setRequestHeader "User-Agent" [toS cachixVersion]
+  }
+
+cachixVersion :: Text
+cachixVersion = "cachix " <> toS (showVersion version)
diff --git a/src/Cachix/Client/InstallationMode.hs b/src/Cachix/Client/InstallationMode.hs
--- a/src/Cachix/Client/InstallationMode.hs
+++ b/src/Cachix/Client/InstallationMode.hs
@@ -52,7 +52,7 @@
   | not isNixOS && isRoot = Install nixVersion NixConf.Global
   | nixVersion /= Nix201 = Nix20RequiresSudo
   | isTrusted = Install nixVersion NixConf.Local
-  | not isTrusted = UntrustedRequiresSudo
+  | otherwise = UntrustedRequiresSudo
 
 
 -- | Add a Binary cache to nix.conf, print nixos config or fail
@@ -61,6 +61,7 @@
   putText [iTrim|
 nix = {
   binaryCaches = [
+    "https://cache.nixos.org/"
     "${uri}"
   ];
   binaryCachePublicKeys = [
@@ -104,11 +105,12 @@
   user <- getUser
   -- to detect single user installations
   permissions <- getPermissions "/nix/store"
-  unless (null groups) $ do
+  let isTrusted = writable permissions || user `elem` users
+  when (not (null groups) && not isTrusted) $ do
     -- TODO: support Nix group syntax
     putText "Warn: cachix doesn't yet support checking if user is trusted via groups, so it will recommend sudo"
     putStrLn $ "Warn: groups found " <> T.intercalate "," groups
-  return $ writable permissions || user `elem` users
+  return isTrusted
   where
     groups = filter (\u -> T.head u == '@') users
 
diff --git a/src/Cachix/Client/OptionsParser.hs b/src/Cachix/Client/OptionsParser.hs
--- a/src/Cachix/Client/OptionsParser.hs
+++ b/src/Cachix/Client/OptionsParser.hs
@@ -13,14 +13,16 @@
 import URI.ByteString.QQ
 import Options.Applicative
 
+import qualified Cachix.Client.Config as Config
 
 data CachixOptions = CachixOptions
   { host :: URIRef Absolute
+  , configPath :: Config.ConfigPath
   , verbose :: Bool
   } deriving Show
 
-parserCachixOptions :: Parser CachixOptions
-parserCachixOptions = CachixOptions
+parserCachixOptions :: Config.ConfigPath -> Parser CachixOptions
+parserCachixOptions defaultConfigPath = CachixOptions
   <$> option uriOption ( long "host"
                        <> short 'h'
                        <> value [uri|https://cachix.org|]
@@ -28,6 +30,13 @@
                        <> showDefaultWith (toS . serializeURIRef')
                        <> help "Host to connect to"
                        )
+ <*> strOption ( long "config"
+              <> short 'c'
+              <> value defaultConfigPath
+              <> metavar "CONFIGPATH"
+              <> showDefault
+              <> help "Cachix configuration file"
+              )
   <*> switch ( long "verbose"
              <> short 'v'
              <> help "Verbose mode"
@@ -64,11 +73,13 @@
               <*> switch (long "nixos" <> short 'n' <> help "Output NixOS configuration lines")
 
 getOpts :: IO (CachixOptions, CachixCommand)
-getOpts = customExecParser (prefs showHelpOnEmpty) opts
+getOpts = do
+  configpath <- Config.getDefaultFilename
+  customExecParser (prefs showHelpOnEmpty) (opts configpath)
 
-opts :: ParserInfo (CachixOptions, CachixCommand)
-opts = infoH parser desc
-  where parser = (,) <$> parserCachixOptions <*> (parserCachixCommand <|> versionParser)
+opts :: Config.ConfigPath -> ParserInfo (CachixOptions, CachixCommand)
+opts configpath = infoH parser desc
+  where parser = (,) <$> parserCachixOptions configpath <*> (parserCachixCommand <|> versionParser)
         versionParser :: Parser CachixCommand
         versionParser = flag' Version ( long "version"
                      <> short 'V'
