diff --git a/cmd/dex/serve.go b/cmd/dex/serve.go
index 86f02c78c8924d55013a174df1b4b21222698e51..27fba306eb336222c86a0190cfa9739af5160874 100644
--- a/cmd/dex/serve.go
+++ b/cmd/dex/serve.go
@@ -153,7 +153,28 @@ func serve(cmd *cobra.Command, args []string) error {
 	logger.Infof("config storage: %s", c.Storage.Type)
 
 	if len(c.StaticClients) > 0 {
-		for _, client := range c.StaticClients {
+		for i, client := range c.StaticClients {
+			if client.Name == "" {
+				return fmt.Errorf("invalid config: Name field is required for a client")
+			}
+			if client.ID == "" && client.IDEnv == "" {
+				return fmt.Errorf("invalid config: ID or IDEnv field is required for a client")
+			}
+			if client.IDEnv != "" {
+				if client.ID != "" {
+					return fmt.Errorf("invalid config: ID and IDEnv fields are exclusive for client %q", client.ID)
+				}
+				c.StaticClients[i].ID = os.Getenv(client.IDEnv)
+			}
+			if client.Secret == "" && client.SecretEnv == "" {
+				return fmt.Errorf("invalid config: Secret or SecretEnv field is required for client %q", client.ID)
+			}
+			if client.SecretEnv != "" {
+				if client.Secret != "" {
+					return fmt.Errorf("invalid config: Secret and SecretEnv fields are exclusive for client %q", client.ID)
+				}
+				c.StaticClients[i].Secret = os.Getenv(client.SecretEnv)
+			}
 			logger.Infof("config static client: %s", client.Name)
 		}
 		s = storage.WithStaticClients(s, c.StaticClients)
diff --git a/storage/storage.go b/storage/storage.go
index 42ecd8ed410a346ddf3913eb46f5d8ebe6419b75..5bbb2b3f1b2e9caa6812b2ba122c6a5001660a7e 100644
--- a/storage/storage.go
+++ b/storage/storage.go
@@ -113,8 +113,10 @@ type Storage interface {
 //   * Public clients: https://developers.google.com/api-client-library/python/auth/installed-app
 type Client struct {
 	// Client ID and secret used to identify the client.
-	ID     string `json:"id" yaml:"id"`
-	Secret string `json:"secret" yaml:"secret"`
+	ID        string `json:"id" yaml:"id"`
+	IDEnv     string `json:"idEnv" yaml:"idEnv"`
+	Secret    string `json:"secret" yaml:"secret"`
+	SecretEnv string `json:"secretEnv" yaml:"secretEnv"`
 
 	// A registered set of redirect URIs. When redirecting from dex to the client, the URI
 	// requested to redirect to MUST match one of these values, unless the client is "public".