A common infrastructure problem is managing access to internal applications. Some patterns for solving that problem include: fronting internal apps with HTTP Basic or HTTP Digest authentication through Apache or nginx, running the apps on secret ports, and bundling an authentication system as part of each application. Many off-the-shelf applications include no built-in authentication, and […]
A common infrastructure problem is managing access to internal applications. Some patterns for solving that problem
include: fronting internal apps with HTTP Basic or HTTP Digest authentication through Apache or nginx, running the apps
on secret ports, and bundling an authentication system as part of each application. Many off-the-shelf applications
include no built-in authentication, and count on upstream proxies/systems for access control which limits options for
securing them. Google Auth Proxy is a tool we have developed to give us a better ability to
secure internal applications by using Google Account authentication (like many other startups, we rely on Google Apps).
At bitly, we like fronting HTTP applications with Nginx and use that approach for nearly all of our stack, from Tornado
apps handling our core APIs to common internal tools (e.g. Nagios, Munin, Graphite) to homegrown tools like NSQ
and our deploy system. For many of those systems, we took advantage of this by configuring HTTP Basic authentication to
restrict access. Using Basic Auth however led to situations where the authentication information would be stored in
configuration files and scripts, leaking it throughout the repository.
Some of our homegrown tools initially relied on bitly’s OAuth 2 service for authentication, which meant
that sign in was managed through bitly accounts by the OAuth flow. This left each application to handle
authorization by maintaining a list of bitly accounts that actually had permission to access the app. This was an
improvement over HTTP Basic Auth as each application did not need to accept or store passwords, but it was less than
ideal because each app still needed to store and manage its own list of authorized users. Over time, this led to a large
number of disparate systems with separate authorization lists. This approach was only feasible for internal tools and
thus couldn’t apply to other open source applications we were using.
We developed Google Auth Proxy as a new tool to use in securing internal applications. It is a HTTP
Reverse Proxy that provides authentication using Google’s OAuth2 API with flexibility to authorize
individual Google Accounts (by email address) or a whole Google apps domain.
For internal applications, this is convenient because we can now allow our whole
@bit.ly Google apps domain without
separately managing accounts or passwords.
Google Auth Proxy requires a limited set of privileges in order to authenticate users (asking for only the
OAuth2 scopes). This authentication information
is then passed to the upstream application as HTTP Basic Auth (with an empty value for the password), and in a HTTP
X-Forwarded-User for applications that need that context.
Google Auth Proxy has been in production for 6 months and has helped reduce overhead for managing internal applications
(no setup time for new or removed accounts) and has made it easier for us to open up access for important tools to the
entire company. It’s also worth mentioning that if you use
two-factor-authentication with your Google accounts, that security carries over to improved authentication for Google
We chose to write Google Auth Proxy in Go because golang has built in support for writing a concurrent
ReverseProxy in the
net/http/httputil package. This meant that little work was needed to proxy
requests and we could focus on just writing the authentication layer.
If you find this useful, we’d love to hear about it @bitly