diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,16 @@
 For differences with the original Sproxy scroll down.
 
+1.93.0
+======
+
+  * BREAKING: Allow `!include` in config file.
+    This changes semantics of options `key` and `oauth2.<provider>.client_secret`.
+    They are no longer files, but strings.  To read content from files, use
+    !include.  The point of being files or read from files is to segregate secrets
+    from non-sensitive easily discoverable settings.  With `!include` it is much more
+    simple and flexible.
+
+
 1.92.0
 ======
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -57,7 +57,7 @@
 ------------------
 Permissions are stored in internal SQLite3 database and imported
 from data sources, which can be a PostgreSQL database or a file.  See
-[sproxy.sql](./sproxy.sql) and [datafile.yml.example](./datafile.yml.example)
+[sproxy.sql](./sproxy.sql) and [datafile.example.yml](./datafile.example.yml)
 for details.
 
 Do note that Sproxy2 fetches only `group_member`, `group_privilege`
@@ -91,17 +91,6 @@
   surprising, please see the following example:
 
 
-Keep in mind that:
-
-- Domains are converted into lower case (coming from a data source or HTTP requests).
-- Emails are converted into lower case (coming from a data source or OAuth2 providers).
-- Groups are case-sensitive and treated as is.
-- HTTP methods are *case-sensitive*.
-- HTTP query parameters are ignored when matching a request against the rules.
-- Privileges are case-sensitive and treated as is.
-- SQL wildcards (`_` and `%`) are supported for emails, domains, paths.
-
-
 Privileges example
 ------------------
 
@@ -138,6 +127,17 @@
 Likewise `readers` have no access to e.g. `/wiki/edit/delete_everything.php`.
 
 
+Keep in mind that:
+
+- Domains are converted into lower case (coming from a data source or HTTP requests).
+- Emails are converted into lower case (coming from a data source or OAuth2 providers).
+- Groups are case-sensitive and treated as is.
+- HTTP methods are *case-sensitive*.
+- HTTP query parameters are ignored when matching a request against the rules.
+- Privileges are case-sensitive and treated as is.
+- SQL wildcards (`_` and `%`) are supported for emails, domains, paths.
+
+
 HTTP headers passed to the back-end server
 ------------------------------------------
 
@@ -198,7 +198,7 @@
 =============
 
 By default `sproxy2` will read its configuration from `sproxy.yml`.  There is
-example file with documentation [sproxy.yml.example](sproxy.yml.example). You
+example file with documentation [sproxy.example.yml](sproxy.example.yml). You
 can specify a custom path with:
 
 ```
diff --git a/datafile.example.yml b/datafile.example.yml
new file mode 100644
--- /dev/null
+++ b/datafile.example.yml
@@ -0,0 +1,29 @@
+group_member:
+  - group: "devops"
+    email: "%"
+
+  - group: "foo"
+    email: "%"
+
+
+group_privilege:
+  - group: "foo"
+    domain: "example.com"
+    privilege: "full"
+
+  - group: "devops"
+    domain: "example.com"
+    privilege: "full"
+
+
+privilege_rule:
+  - domain: "example.com"
+    privilege: "full"
+    path: "%"
+    method: "GET"
+
+  - domain: "example.com"
+    privilege: "full"
+    path: "%"
+    method: "POST"
+
diff --git a/datafile.yml.example b/datafile.yml.example
deleted file mode 100644
--- a/datafile.yml.example
+++ /dev/null
@@ -1,34 +0,0 @@
---- # Data file. Don't remove this line. This is YAML: https://en.wikipedia.org/wiki/YAML
-
-group_member:
-  - group: "devops"
-    email: "%"
-
-  - group: "foo"
-    email: "%"
-
-
-group_privilege:
-  - group: "foo"
-    domain: "example.com"
-    privilege: "full"
-
-  - group: "devops"
-    domain: "example.com"
-    privilege: "full"
-
-
-privilege_rule:
-  - domain: "example.com"
-    privilege: "full"
-    path: "%"
-    method: "GET"
-
-  - domain: "example.com"
-    privilege: "full"
-    path: "%"
-    method: "POST"
-
-
-... # End of data file. Don't remove this line. This is YAML: https://en.wikipedia.org/wiki/YAML
-
diff --git a/sproxy.example.yml b/sproxy.example.yml
new file mode 100644
--- /dev/null
+++ b/sproxy.example.yml
@@ -0,0 +1,172 @@
+# NOTE: You can use the !include directive to import parts of this file.
+
+# Logging level: debug, info, warn, error.
+# Optional. Default is debug.
+#
+# log_level: debug
+
+# The port Sproxy listens on (HTTPS).
+# Optional. Default is 443.
+#
+# listen: 443
+
+# Whether SSL is used on port defined by `listen`.
+# You should only set it to false iff you intent to do SSL-termination
+# somewhere else, e. g. at a load-balancer in a local network.
+# If true, you also have to specify `ssl_key` and `ssl_cert`.
+# Note that there is no way Sproxy can be usable without HTTPS/SSL at the user side,
+# because Sproxy sets cookie for HTTPS only.
+# Optional. Default is true.
+# ssl: true
+
+# Listen on port 80 and redirect HTTP requests to HTTPS (see `https_port`).
+# Optional. Default is true when `listen` == 443, otherwise false.
+#
+# listen80: true
+
+# Port used in redirection of HTTP requests to HTTPS.
+# I. e., http://example.com -> https://example.com[:https_port],
+# If `http_port` == 443, the port part if omitted.
+# This is useful when behind a dumb proxy or load-balancer, like Amazon ELB,
+# (and`ssl` == false). It's unlikely that something other than 443
+# is exposed to users, but if you are behind a proxy
+# you can't really know the correct https port.
+# Optional. Default is as `listen`.
+#
+# Example:
+# https_port: 4040
+#
+# https_port:
+
+# Whether HTTP2 is enabled. Optional. Default is true.
+#
+# http2: true
+
+# The system user Sproxy switches to if launched as root (after opening the ports).
+# Optional. Default is sproxy.
+#
+# user: sproxy
+
+# Home directory for various files including SQLite3 authorization database.
+# Optional. Default is current directory.
+#
+# home: "."
+
+
+# File with SSL certificate. Required if `ssl` == true.
+# It can be a bundle with the server certificate coming first:
+# cat me-cert.pem CA-cert.pem > cert.pem
+# Once again: most wanted certs go first ;-)
+# Or you can opt in using of `ssl_cert_chain`
+ssl_cert: /path/cert.pem
+
+# File with SSL key (secret!). Required if `ssl` = true.
+ssl_key: /path/key.pem
+
+# Chain SSL certificate files.
+# Optional. Default is an empty list
+# Example:
+# ssl_cert_chain:
+#   - /path/foo.pem
+#   - /path/bar.pem
+#
+# ssl_cert_chain: []
+
+
+# PostgreSQL database connection string.
+# Optional. If specified, sproxy will periodically pull the data from this
+# database into internal SQLite3 database. Define password in a file
+# referenced by the PGPASSFILE environment variable. Or use the `pgpassfile` option.
+# Cannot be used with the `datafile` option.
+# Example:
+# database: "user=sproxy-readonly dbname=sproxy port=6001"
+#
+# database:
+
+# PostgreSQL password file.
+# Optional. If specified, sproxy will set PGPASSFILE environment variable pointing to this file
+# Example:
+# pgpassfile: /run/keys/sproxy.pgpass
+#
+# pgpassfile:
+
+
+# YAML file used to fill internal SQLite3 database.
+# Optional. If specified, Sproxy will import it on start overwriting
+# and existing data in the internal database.
+# Useful for development or some simple deployments.
+# Cannot be used with the `database` option.
+# For example see the datafile.yml.example
+#
+# datafile: /path/data.yml
+
+
+# Arbitrary string used to sign sproxy cookie and other things (secret!).
+# Optional. If not specified, a random key is generated on startup, and
+# as a consequence, restaring sproxy will invalidate existing user sessions.
+# This option could be useful for load-balancing with multiple sproxy instances,
+# when all instances must understand cookies created by each other.
+# This should not be very large, a few random bytes are fine.
+# 
+# key: !include /run/keys/sproxy.secret
+
+
+# Credentials for supported OAuth2 providers.
+# Currently supported: "google", "linkedin"
+# At least one provider is required.
+# Attributes:
+#   client_id     - OAuth2 client ID.
+#   client_secret - OAuth2 client secret.
+#
+# Example:
+# oauth2:
+#   google:
+#     client_id: "XXXXXXXXXXXX-YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY.apps.googleusercontent.com"
+#     client_secret: !include /run/keys/XXXXXXXXXXXX-YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY.apps.googleusercontent.com
+#
+#   linkedin:
+#     client_id: "xxxxxxxxxxxxxx"
+#     client_secret: !include "/run/keys/xxxxxxxxxxxxxx"
+#
+#
+# oauth2:
+#   google:
+#     client_id:
+#     client_secret:
+
+
+# Backend servers. At least one is required.
+# NOTE: backends at TCP port are not secure, even on localhost,
+# because any local user can connect to the backend bypassing sproxy
+# authentication and authorization.
+#
+# It is recommended to communicate with backends via unix sockets only.
+# Unix sockets should be secured with proper unix file permissions.
+#
+# Backend attributes:
+#   name      - the host name as in the Host HTTP header.
+#               May include wildcards * and ?. The first matching
+#               backend will be used. Examples: "*.example.com", "wiki.corp.com".
+#               Optional. Default is "*". Note, that the name must include
+#               port number if non-standard.
+#   address   - backend IP address. Optional. Default is 127.0.0.1.
+#   port      - backend TCP port. Required unless unix socket is defined.
+#   socket    - unix socket. Highly recommended for security reasons.
+#               If defined, IP address and TCP port are ignored.
+#
+#   cookie_name    - sproxy cookie name. Optional. Default is "sproxy".
+#   cookie_domain  - sproxy cookie domain. Optional. Default is the request host name as per RFC2109.
+#   cookie_max_age - sproxy cookie shelflife in seconds. Optional. Default is 604800 (7 days).
+#   conn_count     - number of connections to keep alive. Optional. Default is 32.
+#                    This is specific to Haskell HTTP Client library, and is per host name,
+#                    not per backend. HTTP Client's default is 10.
+#
+# backends:
+#   - name: wiki.example.com
+#     port: 9090
+#     cookie_name: sproxy_example
+#     cookie_max_age: 86400
+#
+backends:
+  - port: 8080
+
diff --git a/sproxy.yml.example b/sproxy.yml.example
deleted file mode 100644
--- a/sproxy.yml.example
+++ /dev/null
@@ -1,176 +0,0 @@
---- # Sproxy configuration. Don't remove this line. This is YAML: https://en.wikipedia.org/wiki/YAML
-
-# Logging level: debug, info, warn, error.
-# Optional. Default is debug.
-#
-# log_level: debug
-
-# The port Sproxy listens on (HTTPS).
-# Optional. Default is 443.
-#
-# listen: 443
-
-# Whether SSL is used on port defined by `listen`.
-# You should only set it to false iff you intent to do SSL-termination
-# somewhere else, e. g. at a load-balancer in a local network.
-# If true, you also have to specify `ssl_key` and `ssl_cert`.
-# Note that there is no way Sproxy can be usable without HTTPS/SSL at the user side,
-# because Sproxy sets cookie for HTTPS only.
-# Optional. Default is true.
-# ssl: true
-
-# Listen on port 80 and redirect HTTP requests to HTTPS (see `https_port`).
-# Optional. Default is true when `listen` == 443, otherwise false.
-#
-# listen80: true
-
-# Port used in redirection of HTTP requests to HTTPS.
-# I. e., http://example.com -> https://example.com[:https_port],
-# If `http_port` == 443, the port part if omitted.
-# This is useful when behind a dump proxy or load-balancer, like Amazon ELB,
-# (and`ssl` == false). It's unlikely that something other than 443
-# is exposed to users, but if you are behind a proxy
-# you can't really know the correct https port.
-# Optional. Default is as `listen`.
-#
-# Example:
-# https_port: 4040
-#
-# https_port:
-
-# Whether HTTP2 is enabled. Optional. Default is true.
-#
-# http2: true
-
-# The system user Sproxy switches to if launched as root (after opening the ports).
-# Optional. Default is sproxy.
-#
-# user: sproxy
-
-# Home directory for various files including SQLite3 authorization database.
-# Optional. Default is current directory.
-#
-# home: "."
-
-
-# File with SSL certificate. Required if `ssl` == true.
-# It can be a bundle with the server certificate coming first:
-# cat me-cert.pem CA-cert.pem > cert.pem
-# Once again: most wanted certs go first ;-)
-# Or you can opt in using of `ssl_cert_chain`
-ssl_cert: /path/cert.pem
-
-# File with SSL key (secret!). Required if `ssl` = true.
-ssl_key: /path/key.pem
-
-# Chain SSL certificate files.
-# Optional. Default is an empty list
-# Example:
-# ssl_cert_chain:
-#   - /path/foo.pem
-#   - /path/bar.pem
-#
-# ssl_cert_chain: []
-
-
-# PostgreSQL database connection string.
-# Optional. If specified, sproxy will periodically pull the data from this
-# database into internal SQLite3 database. Define password in a file
-# referenced by the PGPASSFILE environment variable. Or use the `pgpassfile` option.
-# Cannot be used with the `datafile` option.
-# Example:
-# database: "user=sproxy-readonly dbname=sproxy port=6001"
-#
-# database:
-
-# PostgreSQL password file.
-# Optional. If specified, sproxy will set PGPASSFILE environment variable pointing to this file
-# Example:
-# pgpassfile: /run/keys/sproxy.pgpass
-#
-# pgpassfile:
-
-
-# YAML file used to fill internal SQLite3 database.
-# Optional. If specified, Sproxy will import it on start overwriting
-# and existing data in the internal database.
-# Useful for development or some simple deployments.
-# Cannot be used with the `database` option.
-# For example see the datafile.yml.example
-#
-# datafile: /path/data.yml
-
-
-# A file with arbitrary content used to sign sproxy cookie and other things (secret!).
-# Optional. If not specified, a random key is generated on startup, and
-# as a consequence, restaring sproxy will invalidate existing user sessions.
-# This option could be useful for load-balancing with multiple sproxy instances,
-# when all instances must understand cookies created by each other.
-# This should not be very large, a few random bytes are fine.
-# 
-# key: /run/keys/sproxy.secret
-
-
-# Credentials for supported OAuth2 providers.
-# Currently supported: "google", "linkedin"
-# At least one provider is required.
-# Attributes:
-#   client_id     - OAuth2 client ID (string)
-#   client_secret - OAuth2 client secret. Regardless of its name, this is a file.
-#                   The secret is read from the file which you should keep secret.
-#                   Only the first line of this file is read.
-#
-# Example:
-# oauth2:
-#   google:
-#     client_id: "XXXXXXXXXXXX-YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY.apps.googleusercontent.com"
-#     client_secret: "/run/keys/XXXXXXXXXXXX-YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY.apps.googleusercontent.com"
-#
-#   linkedin:
-#     client_id: "xxxxxxxxxxxxxx"
-#     client_secret: "/run/keys/xxxxxxxxxxxxxx"
-#
-#
-# oauth2:
-#   google:
-#     client_id:
-#     client_secret:
-
-
-# Backend servers. At least one is required.
-# NOTE: backends at TCP port are not secure, even on localhost,
-# because any local user can connect to the backend bypassing sproxy
-# authentication and authorization.
-#
-# It is recommended to communicate with backends via unix sockets only.
-# Unix sockets should be secured with proper unix file permissions.
-#
-# Backend attributes:
-#   name      - the host name as in the Host HTTP header.
-#               May include wildcards * and ?. The first matching
-#               backend will be used. Examples: "*.example.com", "wiki.corp.com".
-#               Optional. Default is "*". Note, that the name must include
-#               port number if non-standard.
-#   address   - backend IP address. Optional. Default is 127.0.0.1.
-#   port      - backend TCP port. Required unless unix socket is defined.
-#   socket    - unix socket. Highly recommended for security reasons.
-#               If defined, IP address and TCP port are ignored.
-#
-#   cookie_name    - sproxy cookie name. Optional. Default is "sproxy".
-#   cookie_domain  - sproxy cookie domain. Optional. Default is the request host name as per RFC2109.
-#   cookie_max_age - sproxy cookie shelflife in seconds. Optional. Default is 604800 (7 days).
-#   conn_count     - number of connections to keep alive. Optional. Default is 32.
-#                    This is specific to Haskell HTTP Client library, and is per host name,
-#                    not per backend. HTTP Client's default is 10.
-#
-# backends:
-#   - name: wiki.example.com
-#     port: 9090
-#     cookie_name: sproxy_example
-#     cookie_max_age: 86400
-#
-backends:
-  - port: 8080
-
-... # End of configuration. Don't remove this line. This is YAML: https://en.wikipedia.org/wiki/YAML
-
diff --git a/sproxy2.cabal b/sproxy2.cabal
--- a/sproxy2.cabal
+++ b/sproxy2.cabal
@@ -1,5 +1,5 @@
 name: sproxy2
-version: 1.92.0
+version: 1.93.0
 synopsis: Secure HTTP proxy for authenticating users via OAuth2
 description:
   Sproxy is secure by default. No requests makes it to the backend
@@ -17,9 +17,9 @@
 extra-source-files:
   ChangeLog.md
   README.md
-  datafile.yml.example
+  datafile.example.yml
+  sproxy.example.yml
   sproxy.sql
-  sproxy.yml.example
 
 source-repository head
   type: git
diff --git a/src/Sproxy/Config.hs b/src/Sproxy/Config.hs
--- a/src/Sproxy/Config.hs
+++ b/src/Sproxy/Config.hs
@@ -24,7 +24,7 @@
 , cfSslCert      :: Maybe FilePath
 , cfSslKey       :: Maybe FilePath
 , cfSslCertChain :: [FilePath]
-, cfKey          :: Maybe FilePath
+, cfKey          :: Maybe String
 , cfListen80     :: Maybe Bool
 , cfHttpsPort    :: Maybe Word16
 , cfBackends     :: [BackendConf]
@@ -83,7 +83,7 @@
 
 data OAuth2Conf = OAuth2Conf {
   oa2ClientId     :: String
-, oa2ClientSecret :: FilePath
+, oa2ClientSecret :: String
 } deriving (Show)
 
 instance FromJSON OAuth2Conf where
diff --git a/src/Sproxy/Server.hs b/src/Sproxy/Server.hs
--- a/src/Sproxy/Server.hs
+++ b/src/Sproxy/Server.hs
@@ -5,13 +5,12 @@
 import Control.Concurrent (forkIO)
 import Control.Exception (bracketOnError)
 import Control.Monad (void, when)
-import Data.ByteString as BS (hGetLine, readFile)
 import Data.ByteString.Char8 (pack)
 import Data.HashMap.Strict as HM (fromList, lookup, toList)
 import Data.Maybe (fromMaybe)
 import Data.Text (Text)
 import Data.Word (Word16)
-import Data.Yaml (decodeFileEither)
+import Data.Yaml.Include (decodeFileEither)
 import Network.HTTP.Client (Manager, ManagerSettings(..), defaultManagerSettings, newManager, socketConnection)
 import Network.HTTP.Client.Internal (Connection)
 import Network.Socket ( Socket, Family(AF_INET, AF_UNIX), SockAddr(SockAddrInet, SockAddrUnix),
@@ -25,7 +24,7 @@
 import System.Environment (setEnv)
 import System.Exit (exitFailure)
 import System.FilePath.Glob (compile)
-import System.IO (IOMode(ReadMode), hIsEOF, hPutStrLn, stderr, withFile)
+import System.IO (hPutStrLn, stderr)
 import System.Posix.User ( GroupEntry(..), UserEntry(..),
   getAllGroupEntries, getRealUserID,
   getUserEntryForName, setGroupID, setGroups, setUserID )
@@ -47,7 +46,6 @@
 server configFile = do
   cf <- readConfigFile configFile
   Log.start $ cfLogLevel cf
-  Log.debug $ show cf
 
   sock <- socket AF_INET Stream 0
   setSocketOption sock ReuseAddr 1
@@ -78,7 +76,7 @@
 
   key <- maybe
            (Log.info "using new random key" >> getEntropy 32)
-           (\f -> Log.info ("reading key from " ++ f) >> BS.readFile f)
+           (return . pack)
            (cfKey cf)
 
   let
@@ -139,16 +137,9 @@
                   exitFailure
     Just provider -> do
       Log.info $ "oauth2: adding " ++ show name
-      client_secret <- withFile secret_file ReadMode $ \h -> do
-        empty <- hIsEOF h
-        if empty then do
-          Log.error $ "oauth2: empty secret file for "
-                    ++ show name ++ ": " ++ show secret_file
-          return $ pack ""
-        else BS.hGetLine h
-      return (name, provider (pack client_id, client_secret))
-  where client_id = oa2ClientId cfg
-        secret_file = oa2ClientSecret cfg
+      return (name, provider (client_id, client_secret))
+  where client_id = pack $ oa2ClientId cfg
+        client_secret = pack $ oa2ClientSecret cfg
 
 
 newBackendManager :: BackendConf -> IO Manager
