Skip to content

Commit 9c169b3

Browse files
author
Shraya Ramani
committed
sso: init commit
1 parent 44bc220 commit 9c169b3

File tree

104 files changed

+17621
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+17621
-0
lines changed

.circleci/config.yml

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
version: 2
2+
jobs:
3+
build:
4+
docker:
5+
- image: circleci/golang:1.9
6+
working_directory: /go/src/github.com/buzzfeed/sso
7+
steps:
8+
- checkout
9+
- run:
10+
name: get lint
11+
command: go get github.com/golang/lint/golint
12+
- run:
13+
name: install dependencies
14+
command: |
15+
cp Godeps /tmp/Godeps
16+
cp gpm /tmp/gpm
17+
cd /tmp && ./gpm
18+
- run:
19+
name: copy source
20+
command: |
21+
mkdir bin
22+
- run:
23+
name: run lint and tests for both services
24+
command: |
25+
scripts/test
26+
- run:
27+
name: build sso_auth
28+
command: |
29+
cd cmd/sso-auth
30+
go build
31+
- run:
32+
name: build sso_proxy
33+
command: |
34+
cd cmd/sso-proxy
35+
go build

CODE_OF_CONDUCT.md

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Contributor Code of Conduct
2+
3+
As contributors and maintainers of this project, and in the interest of fostering an open and
4+
welcoming community, we pledge to respect all people who contribute through reporting issues,
5+
posting feature requests, updating documentation, submitting pull requests or patches, and other
6+
activities.
7+
8+
We are committed to making participation in this project a harassment-free experience for everyone,
9+
regardless of level of experience, gender, gender identity and expression, sexual orientation,
10+
disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
11+
12+
Examples of unacceptable behavior by participants include:
13+
14+
* The use of sexualized language or imagery
15+
* Personal attacks
16+
* Trolling or insulting/derogatory comments
17+
* Public or private harassment
18+
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
19+
* Other unethical or unprofessional conduct.
20+
21+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits,
22+
code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By
23+
adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently
24+
applying these principles to every aspect of managing this project. Project maintainers who do not
25+
follow or enforce the Code of Conduct may be permanently removed from the project team.
26+
27+
This code of conduct applies both within project spaces and in public spaces when an individual is
28+
representing the project or its community.
29+
30+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an
31+
issue or contacting one or more of the project maintainers.
32+
33+
This Code of Conduct is adapted from the [Contributor Covenant][1], version 1.2.0, available at
34+
[http://contributor-covenant.org/version/1/2/0/][2].
35+
36+
[1]: http://contributor-covenant.org
37+
[2]: http://contributor-covenant.org/version/1/2/0/

CONTRIBUTING.md

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Contributing
2+
3+
Thank you for your interest in contributing to BuzzFeed's SSO!
4+
5+
## Code of Conduct
6+
7+
Help us keep SSO open and inclusive. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).
8+
9+
## Getting Started
10+
11+
### The Basics
12+
13+
If you've never contributed to a project on Github before, take a look at [Rob Allen's beginner's guide to contributing to a Github project][begin-guide].
14+
15+
* Make sure you have a [GitHub account](https://github.com/signup/free)
16+
* Submit a ticket for your issue, assuming one does not already exist. In that issue:
17+
* Clearly describe the issue including steps to reproduce when it is a bug
18+
* Identify specific versions of the binaries and client libraries
19+
* Fork the repository on GitHub
20+
21+
### Making Changes
22+
23+
* Create a branch from where you want to base your work
24+
* We typically name branches according to the following format: `helpful_name_<issue_number>`
25+
* Make commits of logical units
26+
* Make sure your [commit messages](https://chris.beams.io/posts/git-commit/) are in a clear and readable format, example:
27+
28+
```
29+
sso: added structured logging
30+
31+
* use Logrus to add structured logging
32+
* update logging documentation
33+
* ...
34+
```
35+
36+
### Quickstart
37+
38+
If you want to get SSO up and running, please see our [quickstart guide](docs/quickstart.md).
39+
40+
### Running Tests
41+
42+
All bug fixes and new features are expected to include tests, so it's helpful to know how to run them locally while you're developing!
43+
44+
Here are the steps to running the tests for SSO:
45+
46+
1. [Install go][go]
47+
2. Be sure to set your workspace directory and set your GOPATH
48+
3. Add the sso repo to your gopath:
49+
50+
```sh
51+
ln -s path/to/sso $GOPATH/src/github.com/buzzfeed/sso
52+
```
53+
54+
4. Install gpm and dependencies:
55+
56+
```sh
57+
brew install gpm
58+
gpm install
59+
```
60+
61+
5. Run the tests in the root directory
62+
63+
```sh
64+
./scripts/test
65+
```
66+
67+
### Submitting Changes
68+
69+
* Push your changes to your branch in your fork of the repository
70+
* Submit a [pull request against BuzzFeed's repository](https://akrabat.com/the-beginners-guide-to-contributing-to-a-github-project/#step-3-create-the-pr)
71+
* Comment in the pull request when you're ready for the changes to be reviewed: `"ready for review"`
72+
73+
### Code review
74+
75+
Changes to `buzzfeed/sso` happen via GitHub pull requests, which is where at least one other engineer reviews and approves all code changes. Some tips for pull requests and code review:
76+
77+
* Each pull request is a branch from `master` — there are no other long-lived branches
78+
* A single pull request is used for each set of changes — i.e., once a pull request has been opened, any follow-up commits to address code review and discussion should be pushed to that pull request instead of a new one
79+
* Before a pull request is merged, it must get a green check mark from our CI for passing tests
80+
* Before a pull request is merged, the author should take the opportunity to clean up and rewrite the commits on the branch (see [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/).
81+
* A maintainer will merge your changes once they're approved and ready!
82+
* **Most importantly: Practice [mindful communication][mindful-comms]!**
83+
84+
[begin-guide]: https://akrabat.com/the-beginners-guide-to-contributing-to-a-github-project/
85+
[mindful-comms]: https://kickstarter.engineering/a-guide-to-mindful-communication-in-code-reviews-48aab5282e5e
86+
[go]: https://golang.org/doc/install

Dockerfile

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM golang:1.9.2
2+
3+
RUN apt-get update && apt-get install -y curl bash git jq gettext
4+
5+
# install gpm dependencies
6+
COPY gpm /tmp/gpm
7+
COPY Godeps /tmp/Godeps
8+
RUN cd /tmp && ./gpm
9+
10+
COPY / /go/src/github.com/buzzfeed/sso/
11+
12+
RUN cd /go/src/github.com/buzzfeed/sso/cmd/sso-auth; go build -o /bin/sso-auth
13+
RUN cd /go/src/github.com/buzzfeed/sso/cmd/sso-proxy; go build -o /bin/sso-proxy

Godeps

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
github.com/18F/hmacauth 1.0.1
2+
gopkg.in/yaml.v2 v2
3+
github.com/imdario/mergo v0.3.4
4+
github.com/BurntSushi/toml d94612f9fc140360834f9742158c70b5c5b5535b
5+
github.com/bitly/go-simplejson da1a8928f709389522c8023062a3739f3b4af419
6+
github.com/mreiferson/go-options 77551d20752b54535462404ad9d877ebdb26e53d
7+
github.com/datadog/datadog-go/statsd c74bd0589c83817c93e4eff39ccae69d6c46df9b
8+
golang.org/x/oauth2 7fdf09982454086d5570c7db3e11f360194830ca
9+
golang.org/x/net/context 242b6b35177ec3909636b6cf6a47e8c2c6324b5d
10+
google.golang.org/api/admin/directory/v1 650535c7d6201e8304c92f38c922a9a3a36c6877
11+
cloud.google.com/go/compute/metadata v0.7.0
12+
github.com/benbjohnson/clock 7dc76406b6d3c05b5f71a86293cbcf3c4ea03b19
13+
github.com/kelseyhightower/envconfig v1.3.0
14+
github.com/miscreant/miscreant/go 9a32f76c00c1294ef308947092687049a057381b
15+
github.com/sirupsen/logrus e54a77765aca7bbdd8e56c1c54f60579968b2dc9

LICENSE

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Permission is hereby granted, free of charge, to any person obtaining a copy
2+
of this software and associated documentation files (the "Software"), to deal
3+
in the Software without restriction, including without limitation the rights
4+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5+
copies of the Software, and to permit persons to whom the Software is
6+
furnished to do so, subject to the following conditions:
7+
8+
The above copyright notice and this permission notice shall be included in
9+
all copies or substantial portions of the Software.
10+
11+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17+
THE SOFTWARE.

README.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# SSO
2+
3+
[![CircleCI](https://circleci.com/gh/buzzfeed/sso.svg?style=svg)](https://circleci.com/gh/buzzfeed/sso)
4+
[![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)
5+
6+
<img src="https://user-images.githubusercontent.com/10510566/44476420-a64e5980-a605-11e8-8ad9-2820109deb75.png" width="128px">
7+
8+
----
9+
10+
BuzzFeed's SSO is our single sign-on experience for our internal web services, lovingly known as the *S.S. Octopus* (octoboi) by our team. In addition to the source code, we publish an official [Docker image][docker_hub].
11+
12+
SSO is used to provide single-sign-on authentication and authorization for internal web applications behind it by ensuring that only people in a specific email domain (and optionally users in specific Google Groups) can access them. It consists of two processes - `auth` and `proxy`.
13+
14+
The main idea of SSO is a "double OAuth2" flow, where `auth` is the OAuth2 provider for `proxy`, and Google or another third-party provider, is the OAuth2 provider for `auth`.
15+
16+
In a nutshell:
17+
18+
1. If a user visits a `proxy`-protected service (`foo.sso.example.com`) and does not have a session cookie, they are redirected to `auth` (`sso-auth.example.com`).
19+
- If the user **does not** have a session cookie for `auth`,
20+
they are prompted to log in via the usual Google OAuth2 flow, and then
21+
redirected back to `proxy` where they will now be logged in (to
22+
`foo.sso.example.com`)
23+
- If the user *does* have a session cookie for `auth` (e.g. they
24+
have already logged into `bar.sso.example.com`), they are
25+
transparently redirected back to `proxy` where they will be logged in,
26+
without needing to go through the Google OAuth2 flow
27+
2. `proxy` transparently re-validates & refreshes the user's session with `auth`
28+
3. After 15 days, all sessions are expired and `proxy` will redirect the user to `auth` to go through the Google OAuth2 flow once, after which they will again have access to all SSO-protected services.
29+
30+
## Code of Conduct
31+
32+
Help us keep SSO open and inclusive. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md).
33+
34+
## Contributing
35+
36+
Contributions to SSO are welcome! Please follow our [contribution guideline](CONTRIBUTING.md).
37+
38+
### Issues
39+
40+
Please file any issues you find in our [issue tracker](https://github.com/buzzfeed/sso/issues).
41+
42+
### Security Vulns
43+
44+
If you come across any security vulnerabilities with the SSO repo or software, please email [email protected]. In your email, please request access to our [bug bounty program](https://hackerone.com/buzzfeed) so we can compensate you for any valid issues reported.
45+
46+
## Maintainers
47+
48+
SSO is actively maintained by the BuzzFeed Infrastructure teams.
49+
50+
[docker_hub]: https://hub.docker.com/r/buzzfeed/sso/

cmd/sso-auth/main.go

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"os"
7+
8+
"github.com/buzzfeed/sso/internal/auth"
9+
log "github.com/buzzfeed/sso/internal/pkg/logging"
10+
"github.com/buzzfeed/sso/internal/pkg/options"
11+
"github.com/kelseyhightower/envconfig"
12+
)
13+
14+
func init() {
15+
log.SetServiceName("sso-authenticator")
16+
}
17+
18+
func main() {
19+
logger := log.NewLogEntry()
20+
21+
opts := auth.NewOptions()
22+
23+
err := envconfig.Process("", opts)
24+
if err != nil {
25+
logger.Error(err, "error loading in env vars")
26+
os.Exit(1)
27+
}
28+
29+
err = opts.Validate()
30+
if err != nil {
31+
logger.Error(err, "error validating opts")
32+
os.Exit(1)
33+
}
34+
35+
emailValidator := func(p *auth.Authenticator) error {
36+
p.Validator = options.NewEmailValidator(opts.EmailDomains)
37+
return nil
38+
}
39+
40+
authenticator, err := auth.NewAuthenticator(opts, emailValidator, auth.SetCookieStore(opts), auth.AssignStatsdClient(opts))
41+
if err != nil {
42+
logger.Error(err, "error creating new Authenticator")
43+
os.Exit(1)
44+
}
45+
defer authenticator.Stop()
46+
47+
// we leave the message field blank, which will inherit the stdlib timeout page which is sufficient
48+
// and better than other naive messages we would currently place here
49+
timeoutHandler := http.TimeoutHandler(authenticator.ServeMux, opts.RequestTimeout, "")
50+
51+
s := &http.Server{
52+
Addr: fmt.Sprintf(":%d", opts.Port),
53+
ReadTimeout: opts.TCPReadTimeout,
54+
WriteTimeout: opts.TCPWriteTimeout,
55+
Handler: auth.NewLoggingHandler(os.Stdout, timeoutHandler, opts.RequestLogging, authenticator.StatsdClient),
56+
}
57+
58+
logger.Fatal(s.ListenAndServe())
59+
}

cmd/sso-proxy/main.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"os"
7+
8+
log "github.com/buzzfeed/sso/internal/pkg/logging"
9+
"github.com/buzzfeed/sso/internal/pkg/options"
10+
"github.com/buzzfeed/sso/internal/proxy"
11+
"github.com/kelseyhightower/envconfig"
12+
)
13+
14+
func init() {
15+
log.SetServiceName("sso-proxy")
16+
}
17+
18+
func main() {
19+
logger := log.NewLogEntry()
20+
21+
opts := proxy.NewOptions()
22+
err := envconfig.Process("", opts)
23+
if err != nil {
24+
logger.Error(err, "error parsing env vars into options")
25+
os.Exit(1)
26+
}
27+
28+
err = opts.Validate()
29+
if err != nil {
30+
logger.Error(err, "error validing options")
31+
os.Exit(1)
32+
}
33+
34+
validator := func(p *proxy.OAuthProxy) error {
35+
p.EmailValidator = options.NewEmailValidator(opts.EmailDomains)
36+
return nil
37+
}
38+
39+
oauthproxy, err := proxy.NewOAuthProxy(opts, validator)
40+
if err != nil {
41+
logger.Error(err, "error creating oauthproxy")
42+
os.Exit(1)
43+
}
44+
45+
s := &http.Server{
46+
Addr: fmt.Sprintf(":%d", opts.Port),
47+
ReadTimeout: opts.TCPReadTimeout,
48+
WriteTimeout: opts.TCPWriteTimeout,
49+
Handler: proxy.NewLoggingHandler(os.Stdout, oauthproxy.Handler(), opts.RequestLogging, oauthproxy.StatsdClient),
50+
}
51+
logger.Fatal(s.ListenAndServe())
52+
}

docs/.DS_Store

10 KB
Binary file not shown.

0 commit comments

Comments
 (0)