diff --git a/Dockerfile b/Dockerfile
index dbc0dd386b17550c2c7c51f40b6bbd9a540f6ef3..d6ce6a9cd8f809825be5d2a9f7dc958ee0a93bf2 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -11,15 +11,12 @@ FROM alpine:3.8
 # experience when this doesn't work out of the box.
 #
 # OpenSSL is required so wget can query HTTPS endpoints for health checking.
-RUN apk add --update ca-certificates openssl
-
-COPY --from=0 /go/bin/dex /usr/local/bin/dex
+RUN apk add --update ca-certificates openssl bash
 
 # Import frontend assets and set the correct CWD directory so the assets
 # are in the default path.
 COPY web /web
 WORKDIR /
 
-ENTRYPOINT ["dex"]
-
-CMD ["version"]
+EXPOSE 5500-5600
+CMD ["bash"]
diff --git a/connector/connector.go b/connector/connector.go
index c442c54af2851aa62ad1d1d349e5d3604a37ec20..0335ea941ee12ea4ec6f34e1d1f8897f90c27fd8 100644
--- a/connector/connector.go
+++ b/connector/connector.go
@@ -35,6 +35,7 @@ type Identity struct {
 	//
 	// This data is never shared with end users, OAuth clients, or through the API.
 	ConnectorData []byte
+	Password string
 }
 
 // PasswordConnector is an interface implemented by connectors which take a
diff --git a/connector/keystone/keystone.go b/connector/keystone/keystone.go
new file mode 100644
index 0000000000000000000000000000000000000000..43a03a2291be3dedb17779467d61f39a04238788
--- /dev/null
+++ b/connector/keystone/keystone.go
@@ -0,0 +1,120 @@
+// Package keystone provides authentication strategy using Keystone.
+package keystone
+
+import (
+	"context"
+	"fmt"
+	"github.com/dexidp/dex/connector"
+	"github.com/sirupsen/logrus"
+	"encoding/json"
+	"net/http"
+	"bytes"
+	"io/ioutil"
+	"log"
+)
+
+type KeystoneConnector struct {
+	domain string
+	keystoneURI string
+	Logger   logrus.FieldLogger
+}
+
+var (
+	_ connector.PasswordConnector = &KeystoneConnector{}
+)
+
+// Config holds the configuration parameters for Keystone connector.
+// An example config:
+//	connectors:
+//		type: ksconfig
+//		id: keystone
+//		name: Keystone
+//		config:
+//			keystoneURI: http://example:5000/v3/auth/tokens
+//			domain: default
+
+type Config struct {
+	Domain string `json:"domain"`
+	KeystoneURI string `json:"keystoneURI"`
+}
+
+// Open returns an authentication strategy using Keystone.
+func (c *Config) Open(id string, logger logrus.FieldLogger) (connector.Connector, error) {
+	return &KeystoneConnector{c.Domain,c.KeystoneURI,logger}, nil
+}
+
+func (p KeystoneConnector) Close() error { return nil }
+
+// Declare KeystoneJson struct to get a token
+type KeystoneJson struct {
+	Auth `json:"auth"`
+}
+
+type Auth struct {
+	Identity `json:"identity"`
+}
+
+type Identity struct {
+	Methods  []string `json:"methods"`
+	Password `json:"password"`
+}
+
+type Password struct {
+	User `json:"user"`
+}
+
+type User struct {
+	Name   string `json:"name"`
+	Domain `json:"domain"`
+	Password string `json:"password"`
+}
+
+type Domain struct {
+	ID string `json:"id"`
+}
+
+func (p KeystoneConnector) Login(ctx context.Context, s connector.Scopes, username, password string) (identity connector.Identity, validPassword bool, err error) {
+	// Instantiate KeystoneJson struct type to get a token
+	jsonData := KeystoneJson{
+		Auth: Auth{
+			Identity: Identity{
+				Methods:[]string{"password"},
+				Password: Password{
+					User: User{
+						Name: username,
+						Domain: Domain{ID:p.domain},
+						Password: password,
+					},
+				},
+			},
+		},
+	}
+
+	// Marshal jsonData
+	jsonValue, _ := json.Marshal(jsonData)
+
+	// Make an http post request to Keystone URI
+	response, err := http.Post(p.keystoneURI, "application/json", bytes.NewBuffer(jsonValue))
+
+	// Providing wrong password or wrong keystone URI throws error
+	if err == nil && response.StatusCode == 201 {
+		data, _ := ioutil.ReadAll(response.Body)
+		fmt.Println(string(data))
+		identity.Username =	username
+		return identity, true, nil
+
+	} else if err != nil {
+		log.Fatal(err)
+		return identity, false, err
+
+	} else {
+		fmt.Printf("The HTTP request failed with error %v\n", response.StatusCode)
+		data, _ := ioutil.ReadAll(response.Body)
+		fmt.Println(string(data))
+		return identity, false, err
+
+	}
+	return identity, false, nil
+}
+
+func (p KeystoneConnector) Prompt() string { return "username" }
diff --git a/examples/config-keystone.yaml b/examples/config-keystone.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..22a00b086eba4bbf0a6dffbd2eb96299ef926e1b
--- /dev/null
+++ b/examples/config-keystone.yaml
@@ -0,0 +1,44 @@
+# The base path of dex and the external name of the OpenID Connect service.
+# This is the canonical URL that all clients MUST use to refer to dex. If a
+# path is provided, dex's HTTP service will listen at a non-root URL.
+issuer: http://0.0.0.0:5556/dex
+
+# The storage configuration determines where dex stores its state. Supported
+# options include SQL flavors and Kubernetes third party resources.
+#
+# See the storage document at Documentation/storage.md for further information.
+storage:
+  type: sqlite3
+  config:
+    file: examples/dex.db   #be in the dex directory, else change path here
+
+# Configuration for the HTTP endpoints.
+web:
+  http: 0.0.0.0:5556
+
+# Configuration for telemetry
+telemetry:
+  http: 0.0.0.0:5558
+
+oauth2:
+  responseTypes: ["id_token"]
+
+# Instead of reading from an external storage, use this list of clients.
+staticClients:
+- id: example-app
+  redirectURIs:
+  - 'http://127.0.0.1:5555/callback'
+  name: 'Example App'
+  secret: ZXhhbXBsZS1hcHAtc2VjcmV0
+
+#Provide Keystone connector and its config here
+connectors:
+- type: ksconfig
+  id: keystone
+  name: Keystone
+  config:
+    keystoneURI: http://example:5000/v3/auth/tokens
+    domain: default
+
+# Let dex keep a list of passwords which can be used to login to dex.
+enablePasswordDB: true
\ No newline at end of file
diff --git a/server/server.go b/server/server.go
index cf9f7b47f260096aad2ce810a24a4da6e67f164b..06869ebf330f5d560ab4ad9de779fffecdd1915b 100644
--- a/server/server.go
+++ b/server/server.go
@@ -34,6 +34,7 @@ import (
 	"github.com/dexidp/dex/connector/oidc"
 	"github.com/dexidp/dex/connector/saml"
 	"github.com/dexidp/dex/storage"
+  "github.com/dexidp/dex/connector/keystone"
 )
 
 // LocalConnector is the local passwordDB connector which is an internal
@@ -433,6 +434,7 @@ type ConnectorConfig interface {
 // ConnectorsConfig variable provides an easy way to return a config struct
 // depending on the connector type.
 var ConnectorsConfig = map[string]func() ConnectorConfig{
+	"ksconfig":        func() ConnectorConfig { return new(keystone.Config) },
 	"mockCallback":    func() ConnectorConfig { return new(mock.CallbackConfig) },
 	"mockPassword":    func() ConnectorConfig { return new(mock.PasswordConfig) },
 	"ldap":            func() ConnectorConfig { return new(ldap.Config) },
diff --git a/storage/static.go b/storage/static.go
index 5ae4f783278116392ccf59fc64875d8b7d9ce5d4..abf0ab7fb81e7964113d7f55fbcd2cccce93344f 100644
--- a/storage/static.go
+++ b/storage/static.go
@@ -3,7 +3,6 @@ package storage
 import (
 	"errors"
 	"strings"
-
 	"github.com/sirupsen/logrus"
 )