diff --git a/server/auth/microsoft/microsoft.go b/server/auth/microsoft/microsoft.go
new file mode 100644
index 0000000000000000000000000000000000000000..fa2028e24e63aade371a3ca5f8e2064dd6a0a5b4
--- /dev/null
+++ b/server/auth/microsoft/microsoft.go
@@ -0,0 +1,110 @@
+package microsoft
+
+import (
+	"errors"
+	"net/http"
+	"strings"
+
+	"github.com/nsheridan/cashier/server/auth"
+	"github.com/nsheridan/cashier/server/config"
+	"github.com/nsheridan/cashier/server/metrics"
+
+	"golang.org/x/oauth2"
+	"golang.org/x/oauth2/microsoft"
+)
+
+//XXX: This is a work-in-progress! DO NOT USE!
+// MS issue INSANELY LONG access tokens that exceed shell line length
+
+const (
+	//FIXME:
+	// revokeURL = ""
+	name = "microsoft"
+)
+
+// Config is an implementation of `auth.Provider` for authenticating using a
+// Microsoft Azure AD account.
+type Config struct {
+	config    *oauth2.Config
+	tenant    string
+	whitelist map[string]bool
+}
+
+var _ auth.Provider = (*Config)(nil)
+
+// New creates a new Google provider from a configuration.
+func New(c *config.Auth) (*Config, error) {
+	uw := make(map[string]bool)
+	for _, u := range c.UsersWhitelist {
+		uw[u] = true
+	}
+	if c.ProviderOpts["tenant"] == "" && len(uw) == 0 {
+		return nil, errors.New("either AD tenant or users whitelist must be specified")
+	}
+
+	return &Config{
+		config: &oauth2.Config{
+			ClientID:     c.OauthClientID,
+			ClientSecret: c.OauthClientSecret,
+			RedirectURL:  c.OauthCallbackURL,
+			Endpoint:     microsoft.AzureADEndpoint(c.ProviderOpts["tenant"]),
+			Scopes:       []string{"user.Read"},
+		},
+		whitelist: uw,
+	}, nil
+}
+
+// A new oauth2 http client.
+func (c *Config) newClient(token *oauth2.Token) *http.Client {
+	return c.config.Client(oauth2.NoContext, token)
+}
+
+// Name returns the name of the provider.
+func (c *Config) Name() string {
+	return name
+}
+
+// Valid validates the oauth token.
+func (c *Config) Valid(token *oauth2.Token) bool {
+	// FIXME: Validate harder
+	if !token.Valid() {
+		return false
+	}
+	metrics.M.AuthValid.WithLabelValues("microsoft").Inc()
+	return true
+}
+
+// Revoke disables the access token.
+func (c *Config) Revoke(token *oauth2.Token) error {
+	//FIXME
+	return nil
+}
+
+// StartSession retrieves an authentication endpoint from Google.
+func (c *Config) StartSession(state string) *auth.Session {
+	return &auth.Session{
+		AuthURL: c.config.AuthCodeURL(state),
+	}
+}
+
+// Exchange authorizes the session and returns an access token.
+func (c *Config) Exchange(code string) (*oauth2.Token, error) {
+	t, err := c.config.Exchange(oauth2.NoContext, code)
+	if err == nil {
+		metrics.M.AuthExchange.WithLabelValues("google").Inc()
+	}
+	return t, err
+}
+
+// Email retrieves the email address of the user.
+func (c *Config) Email(token *oauth2.Token) string {
+	// TODO: Given an access token, request the current user profile from
+	// `https://graph.microsoft.com/v1.0/me`. Parse out whatever passes for an
+	// email address from the response.
+	return ""
+}
+
+// Username retrieves the username portion of the user's email address.
+func (c *Config) Username(token *oauth2.Token) string {
+	return strings.Split(c.Email(token), "@")[0]
+}
diff --git a/vendor/golang.org/x/oauth2/microsoft/microsoft.go b/vendor/golang.org/x/oauth2/microsoft/microsoft.go
new file mode 100644
index 0000000000000000000000000000000000000000..3ffbc57a6906ca8e8fa9d49960e97e45efd5df54
--- /dev/null
+++ b/vendor/golang.org/x/oauth2/microsoft/microsoft.go
@@ -0,0 +1,31 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package microsoft provides constants for using OAuth2 to access Windows Live ID.
+package microsoft // import "golang.org/x/oauth2/microsoft"
+
+import (
+	"golang.org/x/oauth2"
+)
+
+// LiveConnectEndpoint is Windows's Live ID OAuth 2.0 endpoint.
+var LiveConnectEndpoint = oauth2.Endpoint{
+	AuthURL:  "https://login.live.com/oauth20_authorize.srf",
+	TokenURL: "https://login.live.com/oauth20_token.srf",
+}
+
+// AzureADEndpoint returns a new oauth2.Endpoint for the given tenant at Azure Active Directory.
+// If tenant is empty, it uses the tenant called `common`.
+//
+// For more information see:
+// https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols#endpoints
+func AzureADEndpoint(tenant string) oauth2.Endpoint {
+	if tenant == "" {
+		tenant = "common"
+	}
+	return oauth2.Endpoint{
+		AuthURL:  "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/authorize",
+		TokenURL: "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token",
+	}
+}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 01e666ceb8604eb201d1038671346e8c24381aad..0f7a2bab33fc88e5559b8bc7b3072e81f6412154 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -958,6 +958,12 @@
 			"revision": "ef147856a6ddbb60760db74283d2424e98c87bff",
 			"revisionTime": "2018-06-20T17:47:24Z"
 		},
+		{
+			"checksumSHA1": "91mzAbqHQ6AAK65DzB4IkLOcvtk=",
+			"path": "golang.org/x/oauth2/microsoft",
+			"revision": "ef147856a6ddbb60760db74283d2424e98c87bff",
+			"revisionTime": "2018-06-20T17:47:24Z"
+		},
 		{
 			"checksumSHA1": "USMsFbKZrNd1b9oRFbjevPr6PmI=",
 			"path": "golang.org/x/sys/unix",