diff --git a/README.md b/README.md
index 8cca1e61e38cee63784198660804bb11156d29f0..715b2af240a76cdd8cc516bdb2121ed0e8e8155c 100644
--- a/README.md
+++ b/README.md
@@ -67,7 +67,11 @@ server:
  # make sure to share this across the different pods
  sessionKey: thisisasessionkeyreplacethisjetzt
  sessionEncryptionKey: thisisasessionkeyreplacethisnunu!
- # tries to set the receive / send buffer of the connections to the client
+  # where to store session details. This can be either file or cookie (default: cookie)
+  # if a file store is chosen, it is required to have clients 'keep state' to the rdpgw
+  # instance they are connected to.
+ sessionStore: cookie
+  # tries to set the receive / send buffer of the connections to the client
  # in case of high latency high bandwidth the defaults set by the OS might
  # be to low for a good experience
  # receiveBuf: 12582912
diff --git a/cmd/rdpgw/config/configuration.go b/cmd/rdpgw/config/configuration.go
index cb851e3c2680da9df67f24a06199f0f8365446c0..4974449f1e829ea567546351685cae2524f395e9 100644
--- a/cmd/rdpgw/config/configuration.go
+++ b/cmd/rdpgw/config/configuration.go
@@ -1,102 +1,147 @@
 package config
 
 import (
-	"github.com/spf13/viper"
+	"github.com/knadh/koanf"
+	"github.com/knadh/koanf/parsers/yaml"
+	"github.com/knadh/koanf/providers/confmap"
+	"github.com/knadh/koanf/providers/env"
+	"github.com/knadh/koanf/providers/file"
 	"log"
+	"strings"
 )
 
 type Configuration struct {
-	Server   ServerConfig
-	OpenId   OpenIDConfig
-	Caps     RDGCapsConfig
-	Security SecurityConfig
-	Client   ClientConfig
+	Server   ServerConfig   `koanf:"server"`
+	OpenId   OpenIDConfig   `koanf:"openid"`
+	Caps     RDGCapsConfig  `koanf:"caps"`
+	Security SecurityConfig `koanf:"security"`
+	Client   ClientConfig   `koanf:"client"`
 }
 
 type ServerConfig struct {
-	GatewayAddress       string
-	Port                 int
-	DisableTLS			 bool
-	CertFile             string
-	KeyFile              string
-	Hosts                []string
-	RoundRobin           bool
-	SessionKey           string
-	SessionEncryptionKey string
-	SessionStore         string
-	SendBuf				 int
-	ReceiveBuf			 int
+	GatewayAddress       string   `koanf:"gatewayaddress"`
+	Port                 int      `koanf:"port"`
+	CertFile             string   `koanf:"certfile"`
+	KeyFile              string   `koanf:"keyfile"`
+	Hosts                []string `koanf:"hosts"`
+	RoundRobin           bool     `koanf:"roundrobin"`
+	SessionKey           string   `koanf:"sessionkey"`
+	SessionEncryptionKey string   `koanf:"sessionencryptionkey"`
+	SessionStore         string   `koanf:"sessionstore"`
+	SendBuf              int      `koanf:"sendbuf"`
+	ReceiveBuf           int      `koanf:"recievebuf"`
+	DisableTLS			 bool	  `koanf:"disabletls"`
 }
 
 type OpenIDConfig struct {
-	ProviderUrl  string
-	ClientId     string
-	ClientSecret string
+	ProviderUrl  string `koanf:"providerurl"`
+	ClientId     string `koanf:"clientid"`
+	ClientSecret string `koanf:"clientsecret"`
 }
 
 type RDGCapsConfig struct {
-	SmartCardAuth   bool
-	TokenAuth       bool
-	IdleTimeout     int
-	RedirectAll     bool
-	DisableRedirect bool
-	EnableClipboard bool
-	EnablePrinter   bool
-	EnablePort      bool
-	EnablePnp       bool
-	EnableDrive     bool
+	SmartCardAuth   bool `koanf:"smartcardauth"`
+	TokenAuth       bool `koanf:"tokenauth"`
+	IdleTimeout     int  `koanf:"idletimeout"`
+	RedirectAll     bool `koanf:"redirectall"`
+	DisableRedirect bool `koanf:"disableredirect"`
+	EnableClipboard bool `koanf:"enableclipboard"`
+	EnablePrinter   bool `koanf:"enableprinter"`
+	EnablePort      bool `koanf:"enableport"`
+	EnablePnp       bool `koanf:"enablepnp"`
+	EnableDrive     bool `koanf:"enabledrive"`
 }
 
 type SecurityConfig struct {
-	PAATokenEncryptionKey  string
-	PAATokenSigningKey     string
-	UserTokenEncryptionKey string
-	UserTokenSigningKey    string
-	VerifyClientIp		   bool
-	EnableUserToken        bool
+	PAATokenEncryptionKey  string `koanf:"paatokenencryptionkey"`
+	PAATokenSigningKey     string `koanf:"paatokensigningkey"`
+	UserTokenEncryptionKey string `koanf:"usertokenencryptionkey"`
+	UserTokenSigningKey    string `koanf:"usertokensigningkey"`
+	VerifyClientIp         bool   `koanf:"verifyclientip"`
+	EnableUserToken        bool   `koanf:"enableusertoken"`
 }
 
 type ClientConfig struct {
-	NetworkAutoDetect   int
-	BandwidthAutoDetect int
-	ConnectionType      int
-	UsernameTemplate    string
-	SplitUserDomain     bool
-	DefaultDomain       string
+	NetworkAutoDetect   int    `koanf:"networkautodetect"`
+	BandwidthAutoDetect int    `koanf:"bandwidthautodetect"`
+	ConnectionType      int    `koanf:"connectiontype"`
+	UsernameTemplate    string `koanf:"usernametemplate"`
+	SplitUserDomain     bool   `koanf:"splituserdomain"`
+	DefaultDomain       string `koanf:"defaultdomain"`
 }
 
-func init() {
-	viper.SetDefault("server.certFile", "server.pem")
-	viper.SetDefault("server.keyFile", "key.pem")
-	viper.SetDefault("server.port", 443)
-	viper.SetDefault("client.networkAutoDetect", 1)
-	viper.SetDefault("client.bandwidthAutoDetect", 1)
-	viper.SetDefault("security.verifyClientIp", true)
-	viper.SetDefault("server.tlsDisabled",  false)
-	viper.SetDefault("server.sessionStore", "cookie")
-	viper.SetDefault("caps.tokenAuth", true)
+func ToCamel(s string) string {
+	s = strings.TrimSpace(s)
+	n := strings.Builder{}
+	n.Grow(len(s))
+	var capNext bool = true
+	for i, v := range []byte(s) {
+		vIsCap := v >= 'A' && v <= 'Z'
+		vIsLow := v >= 'a' && v <= 'z'
+		if capNext {
+			if vIsLow {
+				v += 'A'
+				v -= 'a'
+			}
+		} else if i == 0 {
+			if vIsCap {
+				v += 'a'
+				v -= 'A'
+			}
+		}
+		if vIsCap || vIsLow {
+			n.WriteByte(v)
+			capNext = false
+		} else if vIsNum := v >= '0' && v <= '9'; vIsNum {
+			n.WriteByte(v)
+			capNext = true
+		} else {
+			capNext = v == '_' || v == ' ' || v == '-' || v == '.'
+			if v == '.' {
+				n.WriteByte(v)
+			}
+		}
+	}
+	return n.String()
 }
 
+var Conf Configuration
+
 func Load(configFile string) Configuration {
-	var conf Configuration
 
-	viper.SetConfigName("rdpgw")
-	viper.SetConfigFile(configFile)
-	viper.AddConfigPath(".")
-	viper.SetEnvPrefix("RDPGW")
-	viper.AutomaticEnv()
+	var k = koanf.New(".")
 
-	if err := viper.ReadInConfig(); err != nil {
-		log.Fatalf("No config file found (%s)", err)
-	}
+	k.Load(confmap.Provider(map[string]interface{}{
+		"Server.CertFile":            "server.pem",
+		"Server.KeyFile":             "key.pem",
+		"Server.TlsDisabled":		  false,
+		"Server.Port":                443,
+		"Server.SessionStore":		  "cookie",
+		"Client.NetworkAutoDetect":   1,
+		"Client.BandwidthAutoDetect": 1,
+		"Security.VerifyClientIp":    true,
+		"Caps.TokenAuth":			  true,
+	}, "."), nil)
 
-	if err := viper.Unmarshal(&conf); err != nil {
-		log.Fatalf("Cannot unmarshal the config file; %s", err)
+	if err := k.Load(file.Provider(configFile), yaml.Parser()); err != nil {
+		log.Fatalf("Error loading config from file: %v", err)
 	}
 
-	if len(conf.Security.PAATokenSigningKey) < 32 {
-		log.Fatalf("Token signing key not long enough")
+	if err := k.Load(env.ProviderWithValue("RDPGW_", ".", func(s string, v string) (string, interface{}) {
+		key := strings.Replace(strings.ToLower(strings.TrimPrefix(s, "RDPGW_")), "__", ".", -1)
+		key = ToCamel(key)
+		return key, v
+	}), nil); err != nil {
+		log.Fatalf("Error loading config from file: %v", err)
 	}
 
-	return conf
-}
+	koanfTag := koanf.UnmarshalConf{Tag: "koanf"}
+	k.UnmarshalWithConf("Server", &Conf.Server, koanfTag)
+	k.UnmarshalWithConf("OpenId", &Conf.OpenId, koanfTag)
+	k.UnmarshalWithConf("Caps", &Conf.Caps, koanfTag)
+	k.UnmarshalWithConf("Security", &Conf.Security, koanfTag)
+	k.UnmarshalWithConf("Client", &Conf.Client, koanfTag)
+
+	return Conf
+
+}
\ No newline at end of file
diff --git a/go.mod b/go.mod
index e6800722a84c3d2cf3351e6ff73910faff681d04..939e2bd5a918d283bf178323e7e15d41ba056655 100644
--- a/go.mod
+++ b/go.mod
@@ -7,10 +7,10 @@ require (
 	github.com/go-jose/go-jose/v3 v3.0.0
 	github.com/gorilla/sessions v1.2.1
 	github.com/gorilla/websocket v1.5.0
+	github.com/knadh/koanf v1.4.2
 	github.com/patrickmn/go-cache v2.1.0+incompatible
 	github.com/prometheus/client_golang v1.12.1
 	github.com/spf13/cobra v1.5.0
-	github.com/spf13/viper v1.12.0
 	golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c
 )
 
@@ -20,29 +20,21 @@ require (
 	github.com/fsnotify/fsnotify v1.5.4 // indirect
 	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/gorilla/securecookie v1.1.1 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/inconshreveable/mousetrap v1.0.0 // indirect
-	github.com/magiconair/properties v1.8.6 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
+	github.com/mitchellh/copystructure v1.2.0 // indirect
 	github.com/mitchellh/mapstructure v1.5.0 // indirect
+	github.com/mitchellh/reflectwalk v1.0.2 // indirect
 	github.com/pelletier/go-toml v1.9.5 // indirect
-	github.com/pelletier/go-toml/v2 v2.0.1 // indirect
 	github.com/prometheus/client_model v0.2.0 // indirect
 	github.com/prometheus/common v0.32.1 // indirect
 	github.com/prometheus/procfs v0.7.3 // indirect
-	github.com/spf13/afero v1.8.2 // indirect
-	github.com/spf13/cast v1.5.0 // indirect
-	github.com/spf13/jwalterweatherman v1.1.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
-	github.com/subosito/gotenv v1.3.0 // indirect
+	github.com/stretchr/testify v1.7.1 // indirect
 	golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect
 	golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect
 	golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
-	golang.org/x/text v0.3.7 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/protobuf v1.28.0 // indirect
-	gopkg.in/ini.v1 v1.66.4 // indirect
 	gopkg.in/square/go-jose.v2 v2.6.0 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
-	gopkg.in/yaml.v3 v3.0.0 // indirect
 )