diff --git a/TODO.md b/TODO.md
index 03e9bc525435d0c5ddf766df2dea60fc3d4f7716..e67bea3085cece15c52a9278b19118754807277c 100644
--- a/TODO.md
+++ b/TODO.md
@@ -48,4 +48,3 @@ Backend
 
 - [ ] Improve logging, possibly switch to logrus
 - [ ] Standardize OAuth2 error handling
-- [ ] Switch to github.com/ghodss/yaml for []byte to base64 string logic
diff --git a/cmd/dex/config.go b/cmd/dex/config.go
index 69b4f12ce71291bf6f0f3b2bc959e26750f14709..26c82311831dc8c4a748a11a62e141d29973f8a1 100644
--- a/cmd/dex/config.go
+++ b/cmd/dex/config.go
@@ -1,7 +1,7 @@
 package main
 
 import (
-	"encoding/base64"
+	"encoding/json"
 	"fmt"
 
 	"github.com/coreos/dex/connector"
@@ -18,144 +18,108 @@ import (
 
 // Config is the config format for the main application.
 type Config struct {
-	Issuer     string      `yaml:"issuer"`
-	Storage    Storage     `yaml:"storage"`
-	Connectors []Connector `yaml:"connectors"`
-	Web        Web         `yaml:"web"`
-	OAuth2     OAuth2      `yaml:"oauth2"`
-	GRPC       GRPC        `yaml:"grpc"`
+	Issuer     string      `json:"issuer"`
+	Storage    Storage     `json:"storage"`
+	Connectors []Connector `json:"connectors"`
+	Web        Web         `json:"web"`
+	OAuth2     OAuth2      `json:"oauth2"`
+	GRPC       GRPC        `json:"grpc"`
 
-	Templates server.TemplateConfig `yaml:"templates"`
+	Templates server.TemplateConfig `json:"templates"`
 
 	// StaticClients cause the server to use this list of clients rather than
 	// querying the storage. Write operations, like creating a client, will fail.
-	StaticClients []storage.Client `yaml:"staticClients"`
+	StaticClients []storage.Client `json:"staticClients"`
 
 	// If enabled, the server will maintain a list of passwords which can be used
 	// to identify a user.
-	EnablePasswordDB bool `yaml:"enablePasswordDB"`
+	EnablePasswordDB bool `json:"enablePasswordDB"`
 
 	// StaticPasswords cause the server use this list of passwords rather than
 	// querying the storage. Cannot be specified without enabling a passwords
 	// database.
-	//
-	// The "password" type is identical to the storage.Password type, but does
-	// unmarshaling into []byte correctly.
-	StaticPasswords []password `yaml:"staticPasswords"`
-}
-
-type password struct {
-	Email    string `yaml:"email"`
-	Username string `yaml:"username"`
-	UserID   string `yaml:"userID"`
-
-	// Because our YAML parser doesn't base64, we have to do it ourselves.
-	//
-	// TODO(ericchiang): switch to github.com/ghodss/yaml
-	Hash string `yaml:"hash"`
-}
-
-// decode the hash appropriately and convert to the storage passwords.
-func (p password) toPassword() (storage.Password, error) {
-	hash, err := base64.StdEncoding.DecodeString(p.Hash)
-	if err != nil {
-		return storage.Password{}, fmt.Errorf("decoding hash: %v", err)
-	}
-	return storage.Password{
-		Email:    p.Email,
-		Username: p.Username,
-		UserID:   p.UserID,
-		Hash:     hash,
-	}, nil
+	StaticPasswords []storage.Password `json:"staticPasswords"`
 }
 
 // OAuth2 describes enabled OAuth2 extensions.
 type OAuth2 struct {
-	ResponseTypes []string `yaml:"responseTypes"`
+	ResponseTypes []string `json:"responseTypes"`
 	// If specified, do not prompt the user to approve client authorization. The
 	// act of logging in implies authorization.
-	SkipApprovalScreen bool `yaml:"skipApprovalScreen"`
+	SkipApprovalScreen bool `json:"skipApprovalScreen"`
 }
 
 // Web is the config format for the HTTP server.
 type Web struct {
-	HTTP    string `yaml:"http"`
-	HTTPS   string `yaml:"https"`
-	TLSCert string `yaml:"tlsCert"`
-	TLSKey  string `yaml:"tlsKey"`
+	HTTP    string `json:"http"`
+	HTTPS   string `json:"https"`
+	TLSCert string `json:"tlsCert"`
+	TLSKey  string `json:"tlsKey"`
 }
 
 // GRPC is the config for the gRPC API.
 type GRPC struct {
 	// The port to listen on.
-	Addr        string `yaml:"addr"`
-	TLSCert     string `yaml:"tlsCert"`
-	TLSKey      string `yaml:"tlsKey"`
-	TLSClientCA string `yaml:"tlsClientCA"`
+	Addr        string `json:"addr"`
+	TLSCert     string `json:"tlsCert"`
+	TLSKey      string `json:"tlsKey"`
+	TLSClientCA string `json:"tlsClientCA"`
 }
 
 // Storage holds app's storage configuration.
 type Storage struct {
-	Type   string        `yaml:"type"`
-	Config StorageConfig `yaml:"config"`
+	Type   string        `json:"type"`
+	Config StorageConfig `json:"config"`
 }
 
-// UnmarshalYAML allows Storage to unmarshal its config field dynamically
-// depending on the type of storage.
-func (s *Storage) UnmarshalYAML(unmarshal func(interface{}) error) error {
-	var storageMeta struct {
-		Type string `yaml:"type"`
+// StorageConfig is a configuration that can create a storage.
+type StorageConfig interface {
+	Open() (storage.Storage, error)
+}
+
+var storages = map[string]func() StorageConfig{
+	"kubernetes": func() StorageConfig { return new(kubernetes.Config) },
+	"memory":     func() StorageConfig { return new(memory.Config) },
+	"sqlite3":    func() StorageConfig { return new(sql.SQLite3) },
+	"postgres":   func() StorageConfig { return new(sql.Postgres) },
+}
+
+// UnmarshalJSON allows Storage to implement the unmarshaler interface to
+// dynamically determine the type of the storage config.
+func (s *Storage) UnmarshalJSON(b []byte) error {
+	var store struct {
+		Type   string          `json:"type"`
+		Config json.RawMessage `json:"config"`
 	}
-	if err := unmarshal(&storageMeta); err != nil {
-		return err
+	if err := json.Unmarshal(b, &store); err != nil {
+		return fmt.Errorf("parse storage: %v", err)
 	}
-	s.Type = storageMeta.Type
-	// TODO(ericchiang): replace this with a registration process.
-	var err error
-	switch storageMeta.Type {
-	case "kubernetes":
-		var config struct {
-			Config kubernetes.Config `yaml:"config"`
-		}
-		err = unmarshal(&config)
-		s.Config = &config.Config
-	case "memory":
-		var config struct {
-			Config memory.Config `yaml:"config"`
-		}
-		err = unmarshal(&config)
-		s.Config = &config.Config
-	case "sqlite3":
-		var config struct {
-			Config sql.SQLite3 `yaml:"config"`
-		}
-		err = unmarshal(&config)
-		s.Config = &config.Config
-	case "postgres":
-		var config struct {
-			Config sql.Postgres `yaml:"config"`
-		}
-		err = unmarshal(&config)
-		s.Config = &config.Config
-	default:
-		return fmt.Errorf("unknown storage type %q", storageMeta.Type)
+	f, ok := storages[store.Type]
+	if !ok {
+		return fmt.Errorf("unknown storage type %q", store.Type)
 	}
-	return err
-}
 
-// StorageConfig is a configuration that can create a storage.
-type StorageConfig interface {
-	Open() (storage.Storage, error)
+	storageConfig := f()
+	if len(store.Config) != 0 {
+		if err := json.Unmarshal([]byte(store.Config), storageConfig); err != nil {
+			return fmt.Errorf("parse storace config: %v", err)
+		}
+	}
+	*s = Storage{
+		Type:   store.Type,
+		Config: storageConfig,
+	}
+	return nil
 }
 
 // Connector is a magical type that can unmarshal YAML dynamically. The
 // Type field determines the connector type, which is then customized for Config.
 type Connector struct {
-	Type string `yaml:"type"`
-	Name string `yaml:"name"`
-	ID   string `yaml:"id"`
+	Type string `json:"type"`
+	Name string `json:"name"`
+	ID   string `json:"id"`
 
-	Config ConnectorConfig `yaml:"config"`
+	Config ConnectorConfig `json:"config"`
 }
 
 // ConnectorConfig is a configuration that can open a connector.
@@ -163,55 +127,43 @@ type ConnectorConfig interface {
 	Open() (connector.Connector, error)
 }
 
-// UnmarshalYAML allows Connector to unmarshal its config field dynamically
-// depending on the type of connector.
-func (c *Connector) UnmarshalYAML(unmarshal func(interface{}) error) error {
-	var connectorMetadata struct {
-		Type string `yaml:"type"`
-		Name string `yaml:"name"`
-		ID   string `yaml:"id"`
+var connectors = map[string]func() ConnectorConfig{
+	"mockCallback": func() ConnectorConfig { return new(mock.CallbackConfig) },
+	"mockPassword": func() ConnectorConfig { return new(mock.PasswordConfig) },
+	"ldap":         func() ConnectorConfig { return new(ldap.Config) },
+	"github":       func() ConnectorConfig { return new(github.Config) },
+	"oidc":         func() ConnectorConfig { return new(oidc.Config) },
+}
+
+// UnmarshalJSON allows Connector to implement the unmarshaler interface to
+// dynamically determine the type of the connector config.
+func (c *Connector) UnmarshalJSON(b []byte) error {
+	var conn struct {
+		Type string `json:"type"`
+		Name string `json:"name"`
+		ID   string `json:"id"`
+
+		Config json.RawMessage `json:"config"`
 	}
-	if err := unmarshal(&connectorMetadata); err != nil {
-		return err
+	if err := json.Unmarshal(b, &conn); err != nil {
+		return fmt.Errorf("parse connector: %v", err)
 	}
-	c.Type = connectorMetadata.Type
-	c.Name = connectorMetadata.Name
-	c.ID = connectorMetadata.ID
-
-	var err error
-	switch c.Type {
-	case "mockCallback":
-		var config struct {
-			Config mock.CallbackConfig `yaml:"config"`
-		}
-		err = unmarshal(&config)
-		c.Config = &config.Config
-	case "mockPassword":
-		var config struct {
-			Config mock.PasswordConfig `yaml:"config"`
-		}
-		err = unmarshal(&config)
-		c.Config = &config.Config
-	case "ldap":
-		var config struct {
-			Config ldap.Config `yaml:"config"`
-		}
-		err = unmarshal(&config)
-		c.Config = &config.Config
-	case "github":
-		var config struct {
-			Config github.Config `yaml:"config"`
-		}
-		err = unmarshal(&config)
-		c.Config = &config.Config
-	case "oidc":
-		var config struct {
-			Config oidc.Config `yaml:"config"`
+	f, ok := connectors[conn.Type]
+	if !ok {
+		return fmt.Errorf("unknown connector type %q", conn.Type)
+	}
+
+	connConfig := f()
+	if len(conn.Config) != 0 {
+		if err := json.Unmarshal([]byte(conn.Config), connConfig); err != nil {
+			return fmt.Errorf("parse connector config: %v", err)
 		}
-		err = unmarshal(&config)
-		c.Config = &config.Config
-	default:
-		return fmt.Errorf("unknown connector type %q", c.Type)
 	}
-	return err
+	*c = Connector{
+		Type:   conn.Type,
+		Name:   conn.Type,
+		ID:     conn.ID,
+		Config: connConfig,
+	}
+	return nil
 }
diff --git a/cmd/dex/serve.go b/cmd/dex/serve.go
index 489a20c0f1e202617fc15ae3eeaa8c41dc4bc55f..d6d545e768c59e6d9ee67bd08bf5d763012901a9 100644
--- a/cmd/dex/serve.go
+++ b/cmd/dex/serve.go
@@ -11,11 +11,11 @@ import (
 	"net/http"
 	"os"
 
+	"github.com/ghodss/yaml"
 	"github.com/spf13/cobra"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials"
-	yaml "gopkg.in/yaml.v2"
 
 	"github.com/coreos/dex/api"
 	"github.com/coreos/dex/server"
@@ -136,13 +136,7 @@ func serve(cmd *cobra.Command, args []string) error {
 		s = storage.WithStaticClients(s, c.StaticClients)
 	}
 	if len(c.StaticPasswords) > 0 {
-		p := make([]storage.Password, len(c.StaticPasswords))
-		for i, pw := range c.StaticPasswords {
-			if p[i], err = pw.toPassword(); err != nil {
-				return err
-			}
-		}
-		s = storage.WithStaticPasswords(s, p)
+		s = storage.WithStaticPasswords(s, c.StaticPasswords)
 	}
 
 	serverConfig := server.Config{
diff --git a/connector/github/github.go b/connector/github/github.go
index ab22217b4853d131984e843ea7f9fd110f6b9d53..9e14f60fa8abcb3586e01ea13654888e53e19e59 100644
--- a/connector/github/github.go
+++ b/connector/github/github.go
@@ -19,10 +19,10 @@ const baseURL = "https://api.github.com"
 
 // Config holds configuration options for github logins.
 type Config struct {
-	ClientID     string `yaml:"clientID"`
-	ClientSecret string `yaml:"clientSecret"`
-	RedirectURI  string `yaml:"redirectURI"`
-	Org          string `yaml:"org"`
+	ClientID     string `json:"clientID"`
+	ClientSecret string `json:"clientSecret"`
+	RedirectURI  string `json:"redirectURI"`
+	Org          string `json:"org"`
 }
 
 // Open returns a strategy for logging in through GitHub.
diff --git a/connector/ldap/ldap.go b/connector/ldap/ldap.go
index 841ff11062fc08705287af37eaca1acaa06dea42..dd45dd10d63f64175e43bb5d81021a830eeca3e6 100644
--- a/connector/ldap/ldap.go
+++ b/connector/ldap/ldap.go
@@ -53,52 +53,52 @@ import (
 type Config struct {
 	// The host and optional port of the LDAP server. If port isn't supplied, it will be
 	// guessed based on the TLS configuration. 389 or 636.
-	Host string `yaml:"host"`
+	Host string `json:"host"`
 
 	// Required if LDAP host does not use TLS.
-	InsecureNoSSL bool `yaml:"insecureNoSSL"`
+	InsecureNoSSL bool `json:"insecureNoSSL"`
 
 	// Path to a trusted root certificate file.
-	RootCA string `yaml:"rootCA"`
+	RootCA string `json:"rootCA"`
 
 	// BindDN and BindPW for an application service account. The connector uses these
 	// credentials to search for users and groups.
-	BindDN string `yaml:"bindDN"`
-	BindPW string `yaml:"bindPW"`
+	BindDN string `json:"bindDN"`
+	BindPW string `json:"bindPW"`
 
 	// User entry search configuration.
 	UserSearch struct {
 		// BsaeDN to start the search from. For example "cn=users,dc=example,dc=com"
-		BaseDN string `yaml:"baseDN"`
+		BaseDN string `json:"baseDN"`
 
 		// Optional filter to apply when searching the directory. For example "(objectClass=person)"
-		Filter string `yaml:"filter"`
+		Filter string `json:"filter"`
 
 		// Attribute to match against the inputted username. This will be translated and combined
 		// with the other filter as "(<attr>=<username>)".
-		Username string `yaml:"username"`
+		Username string `json:"username"`
 
 		// Can either be:
 		// * "sub" - search the whole sub tree
 		// * "one" - only search one level
-		Scope string `yaml:"scope"`
+		Scope string `json:"scope"`
 
 		// A mapping of attributes on the user entry to claims.
-		IDAttr    string `yaml:"idAttr"`    // Defaults to "uid"
-		EmailAttr string `yaml:"emailAttr"` // Defaults to "mail"
-		NameAttr  string `yaml:"nameAttr"`  // No default.
+		IDAttr    string `json:"idAttr"`    // Defaults to "uid"
+		EmailAttr string `json:"emailAttr"` // Defaults to "mail"
+		NameAttr  string `json:"nameAttr"`  // No default.
 
-	} `yaml:"userSearch"`
+	} `json:"userSearch"`
 
 	// Group search configuration.
 	GroupSearch struct {
 		// BsaeDN to start the search from. For example "cn=groups,dc=example,dc=com"
-		BaseDN string `yaml:"baseDN"`
+		BaseDN string `json:"baseDN"`
 
 		// Optional filter to apply when searching the directory. For example "(objectClass=posixGroup)"
-		Filter string `yaml:"filter"`
+		Filter string `json:"filter"`
 
-		Scope string `yaml:"scope"` // Defaults to "sub"
+		Scope string `json:"scope"` // Defaults to "sub"
 
 		// These two fields are use to match a user to a group.
 		//
@@ -108,12 +108,12 @@ type Config struct {
 		//
 		//   (<groupAttr>=<userAttr value>)
 		//
-		UserAttr  string `yaml:"userAttr"`
-		GroupAttr string `yaml:"groupAttr"`
+		UserAttr  string `json:"userAttr"`
+		GroupAttr string `json:"groupAttr"`
 
 		// The attribute of the group that represents its name.
-		NameAttr string `yaml:"nameAttr"`
-	} `yaml:"groupSearch"`
+		NameAttr string `json:"nameAttr"`
+	} `json:"groupSearch"`
 }
 
 func parseScope(s string) (int, bool) {
diff --git a/connector/mock/connectortest.go b/connector/mock/connectortest.go
index 1ceeb36119a0d3a61293c0f4e2f4ad404353c981..58b3e10b3aec79ae92e15a697303fb5222b4e1bc 100644
--- a/connector/mock/connectortest.go
+++ b/connector/mock/connectortest.go
@@ -69,8 +69,8 @@ func (c *CallbackConfig) Open() (connector.Connector, error) {
 // PasswordConfig holds the configuration for a mock connector which prompts for the supplied
 // username and password.
 type PasswordConfig struct {
-	Username string `yaml:"username"`
-	Password string `yaml:"password"`
+	Username string `json:"username"`
+	Password string `json:"password"`
 }
 
 // Open returns an authentication strategy which prompts for a predefined username and password.
diff --git a/connector/oidc/oidc.go b/connector/oidc/oidc.go
index 9b5aad20da587305d396d60b8a84f152c9a74a15..cd9656f1c94969bb8fd97ecc4b110fa7d0139cea 100644
--- a/connector/oidc/oidc.go
+++ b/connector/oidc/oidc.go
@@ -15,12 +15,12 @@ import (
 
 // Config holds configuration options for OpenID Connect logins.
 type Config struct {
-	Issuer       string `yaml:"issuer"`
-	ClientID     string `yaml:"clientID"`
-	ClientSecret string `yaml:"clientSecret"`
-	RedirectURI  string `yaml:"redirectURI"`
+	Issuer       string `json:"issuer"`
+	ClientID     string `json:"clientID"`
+	ClientSecret string `json:"clientSecret"`
+	RedirectURI  string `json:"redirectURI"`
 
-	Scopes []string `yaml:"scopes"` // defaults to "profile" and "email"
+	Scopes []string `json:"scopes"` // defaults to "profile" and "email"
 }
 
 // Open returns a connector which can be used to login users through an upstream
diff --git a/glide.lock b/glide.lock
index c743fb337f1cdfbd8da47a3d002d1a4931dd2ddd..41f250fa5a061d2a4866c303bf8d656310d3f3a3 100644
--- a/glide.lock
+++ b/glide.lock
@@ -1,5 +1,5 @@
-hash: a813cbca07393d7cbe35d411cdef588afac7a3bab8a287ffe7b9587516ef5898
-updated: 2016-10-23T20:51:55.313818678-07:00
+hash: bc7fa6bbfddcb39710064a9d6dab090d49bd88486571cae12c68c4b70093e716
+updated: 2016-11-03T14:31:37.323302694-07:00
 imports:
 - name: github.com/cockroachdb/cockroach-go
   version: 31611c0501c812f437d4861d87d117053967c955
@@ -7,6 +7,8 @@ imports:
   - crdb
 - name: github.com/ericchiang/oidc
   version: 1907f0e61549f9081f26bdf269f11603496c9dee
+- name: github.com/ghodss/yaml
+  version: bea76d6a4713e18b7f5321a2b020738552def3ea
 - name: github.com/go-sql-driver/mysql
   version: 0b58b37b664c21f3010e836f1b931e1d0b0b0685
 - name: github.com/golang/protobuf
diff --git a/storage/kubernetes/client.go b/storage/kubernetes/client.go
index dfb1fe35688f1b95c3231749df6ceee5ea847947..99fefa827387eed564dad5dd1c1bb2c3ffcdaa27 100644
--- a/storage/kubernetes/client.go
+++ b/storage/kubernetes/client.go
@@ -21,9 +21,9 @@ import (
 	"strings"
 	"time"
 
+	"github.com/ghodss/yaml"
 	"github.com/gtank/cryptopasta"
 	"golang.org/x/net/context"
-	yaml "gopkg.in/yaml.v2"
 
 	"github.com/coreos/dex/storage"
 	"github.com/coreos/dex/storage/kubernetes/k8sapi"
diff --git a/storage/kubernetes/k8sapi/client.go b/storage/kubernetes/k8sapi/client.go
index d84fa5ccee3bab76a9e5c7bf2bd152a8dcec70e4..4e71dd075ef31efbbd40d55f6d35c24a91f3f45e 100644
--- a/storage/kubernetes/k8sapi/client.go
+++ b/storage/kubernetes/k8sapi/client.go
@@ -23,124 +23,124 @@ package k8sapi
 type Config struct {
 	// Legacy field from pkg/api/types.go TypeMeta.
 	// TODO(jlowdermilk): remove this after eliminating downstream dependencies.
-	Kind string `yaml:"kind,omitempty"`
+	Kind string `json:"kind,omitempty"`
 	// DEPRECATED: APIVersion is the preferred api version for communicating with the kubernetes cluster (v1, v2, etc).
 	// Because a cluster can run multiple API groups and potentially multiple versions of each, it no longer makes sense to specify
 	// a single value for the cluster version.
 	// This field isn't really needed anyway, so we are deprecating it without replacement.
 	// It will be ignored if it is present.
-	APIVersion string `yaml:"apiVersion,omitempty"`
+	APIVersion string `json:"apiVersion,omitempty"`
 	// Preferences holds general information to be use for cli interactions
-	Preferences Preferences `yaml:"preferences"`
+	Preferences Preferences `json:"preferences"`
 	// Clusters is a map of referencable names to cluster configs
-	Clusters []NamedCluster `yaml:"clusters"`
+	Clusters []NamedCluster `json:"clusters"`
 	// AuthInfos is a map of referencable names to user configs
-	AuthInfos []NamedAuthInfo `yaml:"users"`
+	AuthInfos []NamedAuthInfo `json:"users"`
 	// Contexts is a map of referencable names to context configs
-	Contexts []NamedContext `yaml:"contexts"`
+	Contexts []NamedContext `json:"contexts"`
 	// CurrentContext is the name of the context that you would like to use by default
-	CurrentContext string `yaml:"current-context"`
+	CurrentContext string `json:"current-context"`
 	// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
-	Extensions []NamedExtension `yaml:"extensions,omitempty"`
+	Extensions []NamedExtension `json:"extensions,omitempty"`
 }
 
 // Preferences contains information about the users command line experience preferences.
 type Preferences struct {
-	Colors bool `yaml:"colors,omitempty"`
+	Colors bool `json:"colors,omitempty"`
 	// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
-	Extensions []NamedExtension `yaml:"extensions,omitempty"`
+	Extensions []NamedExtension `json:"extensions,omitempty"`
 }
 
 // Cluster contains information about how to communicate with a kubernetes cluster
 type Cluster struct {
 	// Server is the address of the kubernetes cluster (https://hostname:port).
-	Server string `yaml:"server"`
+	Server string `json:"server"`
 	// APIVersion is the preferred api version for communicating with the kubernetes cluster (v1, v2, etc).
-	APIVersion string `yaml:"api-version,omitempty"`
+	APIVersion string `json:"api-version,omitempty"`
 	// InsecureSkipTLSVerify skips the validity check for the server's certificate. This will make your HTTPS connections insecure.
-	InsecureSkipTLSVerify bool `yaml:"insecure-skip-tls-verify,omitempty"`
+	InsecureSkipTLSVerify bool `json:"insecure-skip-tls-verify,omitempty"`
 	// CertificateAuthority is the path to a cert file for the certificate authority.
-	CertificateAuthority string `yaml:"certificate-authority,omitempty"`
+	CertificateAuthority string `json:"certificate-authority,omitempty"`
 	// CertificateAuthorityData contains PEM-encoded certificate authority certificates. Overrides CertificateAuthority
 	//
 	// NOTE(ericchiang): Our yaml parser doesn't assume []byte is a base64 encoded string.
-	CertificateAuthorityData string `yaml:"certificate-authority-data,omitempty"`
+	CertificateAuthorityData string `json:"certificate-authority-data,omitempty"`
 	// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
-	Extensions []NamedExtension `yaml:"extensions,omitempty"`
+	Extensions []NamedExtension `json:"extensions,omitempty"`
 }
 
 // AuthInfo contains information that describes identity information.  This is use to tell the kubernetes cluster who you are.
 type AuthInfo struct {
 	// ClientCertificate is the path to a client cert file for TLS.
-	ClientCertificate string `yaml:"client-certificate,omitempty"`
+	ClientCertificate string `json:"client-certificate,omitempty"`
 	// ClientCertificateData contains PEM-encoded data from a client cert file for TLS. Overrides ClientCertificate
 	//
 	// NOTE(ericchiang): Our yaml parser doesn't assume []byte is a base64 encoded string.
-	ClientCertificateData string `yaml:"client-certificate-data,omitempty"`
+	ClientCertificateData string `json:"client-certificate-data,omitempty"`
 	// ClientKey is the path to a client key file for TLS.
-	ClientKey string `yaml:"client-key,omitempty"`
+	ClientKey string `json:"client-key,omitempty"`
 	// ClientKeyData contains PEM-encoded data from a client key file for TLS. Overrides ClientKey
 	//
 	// NOTE(ericchiang): Our yaml parser doesn't assume []byte is a base64 encoded string.
-	ClientKeyData string `yaml:"client-key-data,omitempty"`
+	ClientKeyData string `json:"client-key-data,omitempty"`
 	// Token is the bearer token for authentication to the kubernetes cluster.
-	Token string `yaml:"token,omitempty"`
+	Token string `json:"token,omitempty"`
 	// Impersonate is the username to imperonate.  The name matches the flag.
-	Impersonate string `yaml:"as,omitempty"`
+	Impersonate string `json:"as,omitempty"`
 	// Username is the username for basic authentication to the kubernetes cluster.
-	Username string `yaml:"username,omitempty"`
+	Username string `json:"username,omitempty"`
 	// Password is the password for basic authentication to the kubernetes cluster.
-	Password string `yaml:"password,omitempty"`
+	Password string `json:"password,omitempty"`
 	// AuthProvider specifies a custom authentication plugin for the kubernetes cluster.
-	AuthProvider *AuthProviderConfig `yaml:"auth-provider,omitempty"`
+	AuthProvider *AuthProviderConfig `json:"auth-provider,omitempty"`
 	// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
-	Extensions []NamedExtension `yaml:"extensions,omitempty"`
+	Extensions []NamedExtension `json:"extensions,omitempty"`
 }
 
 // Context is a tuple of references to a cluster (how do I communicate with a kubernetes cluster), a user (how do I identify myself), and a namespace (what subset of resources do I want to work with)
 type Context struct {
 	// Cluster is the name of the cluster for this context
-	Cluster string `yaml:"cluster"`
+	Cluster string `json:"cluster"`
 	// AuthInfo is the name of the authInfo for this context
-	AuthInfo string `yaml:"user"`
+	AuthInfo string `json:"user"`
 	// Namespace is the default namespace to use on unspecified requests
-	Namespace string `yaml:"namespace,omitempty"`
+	Namespace string `json:"namespace,omitempty"`
 	// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
-	Extensions []NamedExtension `yaml:"extensions,omitempty"`
+	Extensions []NamedExtension `json:"extensions,omitempty"`
 }
 
 // NamedCluster relates nicknames to cluster information
 type NamedCluster struct {
 	// Name is the nickname for this Cluster
-	Name string `yaml:"name"`
+	Name string `json:"name"`
 	// Cluster holds the cluster information
-	Cluster Cluster `yaml:"cluster"`
+	Cluster Cluster `json:"cluster"`
 }
 
 // NamedContext relates nicknames to context information
 type NamedContext struct {
 	// Name is the nickname for this Context
-	Name string `yaml:"name"`
+	Name string `json:"name"`
 	// Context holds the context information
-	Context Context `yaml:"context"`
+	Context Context `json:"context"`
 }
 
 // NamedAuthInfo relates nicknames to auth information
 type NamedAuthInfo struct {
 	// Name is the nickname for this AuthInfo
-	Name string `yaml:"name"`
+	Name string `json:"name"`
 	// AuthInfo holds the auth information
-	AuthInfo AuthInfo `yaml:"user"`
+	AuthInfo AuthInfo `json:"user"`
 }
 
 // NamedExtension relates nicknames to extension information
 type NamedExtension struct {
 	// Name is the nickname for this Extension
-	Name string `yaml:"name"`
+	Name string `json:"name"`
 }
 
 // AuthProviderConfig holds the configuration for a specified auth provider.
 type AuthProviderConfig struct {
-	Name   string            `yaml:"name"`
-	Config map[string]string `yaml:"config"`
+	Name   string            `json:"name"`
+	Config map[string]string `json:"config"`
 }
diff --git a/storage/kubernetes/storage.go b/storage/kubernetes/storage.go
index 05e088d489544dbf771e421691085012323608a3..08df0161c7710e982d6310975af6c8ffd2f0800c 100644
--- a/storage/kubernetes/storage.go
+++ b/storage/kubernetes/storage.go
@@ -34,8 +34,8 @@ const (
 
 // Config values for the Kubernetes storage type.
 type Config struct {
-	InCluster      bool   `yaml:"inCluster"`
-	KubeConfigFile string `yaml:"kubeConfigFile"`
+	InCluster      bool   `json:"inCluster"`
+	KubeConfigFile string `json:"kubeConfigFile"`
 }
 
 // Open returns a storage using Kubernetes third party resource.
diff --git a/storage/sql/config.go b/storage/sql/config.go
index f8cdf248cd374115783e8013b7ac3f73c694f8d7..071f0b039997895e71f45e1be2573161125ba4f3 100644
--- a/storage/sql/config.go
+++ b/storage/sql/config.go
@@ -12,7 +12,7 @@ import (
 // SQLite3 options for creating an SQL db.
 type SQLite3 struct {
 	// File to
-	File string `yaml:"file"`
+	File string `json:"file"`
 }
 
 // Open creates a new storage implementation backed by SQLite3
diff --git a/storage/storage.go b/storage/storage.go
index addec4ae251feb1b4991a6e3e746130159d11fa6..0d5b1f7ff68626ef703cc9f1ac65d070fd4c544b 100644
--- a/storage/storage.go
+++ b/storage/storage.go
@@ -247,16 +247,16 @@ type Password struct {
 	//
 	// Storages that don't support an extended character set for IDs, such as '.' and '@'
 	// (cough cough, kubernetes), must map this value appropriately.
-	Email string `yaml:"email"`
+	Email string `json:"email"`
 
 	// Bcrypt encoded hash of the password. This package enforces a min cost value of 10
-	Hash []byte `yaml:"hash"`
+	Hash []byte `json:"hash"`
 
 	// Optional username to display. NOT used during login.
-	Username string `yaml:"username"`
+	Username string `json:"username"`
 
 	// Randomly generated user ID. This is NOT the primary ID of the Password object.
-	UserID string `yaml:"userID"`
+	UserID string `json:"userID"`
 }
 
 // VerificationKey is a rotated signing key which can still be used to verify