Initial buzzfeed-sso chart - Oauth over your Kubernetes services (#8157)

* Initial sso chart

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Rename to buzzfeed-sso

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Remove auth code secret from proxy

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Make tls templating more flexible

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Remove proxy code secret from the configuration

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Use buzzfeed-sso in README

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Use quote filter in proxy virtualHost variable

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Set CLUSTER in proxy as configurable and dev by default

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Quote all templated environment variables

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Set cookie secure to true by default

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Allow definition of a custom secret key
This will skip secret creation via helm

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Make auth ingress tls secret name configurable

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Separate upstream configuration from ingress

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Update image to v1.1.0
Adds a new optional environment variable for the proxy that allows split dns deployments

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Move chart to incubator

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Fix auth configuration variables

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Use component label to distinguish between auth and proxy

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Make google admin email optional

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Fix proxy url internal environment variable

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Remove unnecessary virtual host

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Add only google service account credentials when admin email is given

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Make annotations configurable
It also adds the secret file to the checksum

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Fix ingress hosts example

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Allow installation with default values showing errors

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Remove unusued virtualHost parameter

Signed-off-by: Dario Blanco <dblanco@minddoc.de>

* Add OWNERS file

Signed-off-by: Dario Blanco <dblanco@minddoc.de>
This commit is contained in:
Dario Blanco
2019-04-03 10:55:44 -07:00
committed by Kubernetes Prow Robot
parent d83478b793
commit 920ab2e239
14 changed files with 874 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
apiVersion: v1
description: Single sign-on for your Kubernetes services using Google OAuth
name: buzzfeed-sso
version: 0.0.1
appVersion: 1.1.0
home: https://github.com/buzzfeed/sso
sources:
- https://hub.docker.com/r/buzzfeed/sso/
keywords:
- sso
- octoboi
- ssoctopus
icon: https://user-images.githubusercontent.com/10510566/44476420-a64e5980-a605-11e8-8ad9-2820109deb75.png
maintainers:
- name: darioblanco
email: dblanco@minddoc.de
+4
View File
@@ -0,0 +1,4 @@
approvers:
- darioblanco
reviewers:
- darioblanco
+182
View File
@@ -0,0 +1,182 @@
# Buzzfeed SSO
Single sign-on for your Kubernetes services using Google OAuth (more providers are welcomed)
[Blogpost](https://tech.buzzfeed.com/unleashing-the-a6a1a5da39d6?gi=e6db395406ae)
[Quickstart guide](https://github.com/buzzfeed/sso/blob/master/docs/quickstart.md)
[SSO in Kubernetes with Google Auth](https://medium.com/@while1eq1/single-sign-on-for-internal-apps-in-kubernetes-using-google-oauth-sso-2386a34bc433)
[Repo](https://github.com/buzzfeed/sso)
This helm chart is heavily inspired in [Buzzfeed's example](https://github.com/buzzfeed/sso/tree/master/quickstart/kubernetes), and provides a way of protecting Kubernetes services that have no authentication layer globally from a single OAuth proxy.
Many of the Kubernetes OAuth solutions require to run an extra container within the pod using [oauth2_proxy](https://github.com/bitly/oauth2_proxy), but the project seems to not be maintained anymore. The approach presented on this chart allows to have a global OAuth2 Proxy that can protect services even in different namespaces, thanks to [Kube DNS](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/).
We use this chart in production at [MindDoc](https://minddoc.de) for protecting endpoints that have no built-in authentication (or that would require to run inner containers), like `Kibana`, `Prometheus`, etc...
## Introduction
This chart creates a SSO deployment on a [Kubernetes](http://kubernetes.io)
cluster using the [Helm](https://helm.sh) package manager.
## Prerequisites
- Kubernetes 1.8+ with Beta APIs enabled
- Kube DNS
## Installing the Chart
To install the chart with the release name `my-release`:
```bash
$ helm install --name my-release stable/buzzfeed-sso
```
The command deploys SSO on the Kubernetes cluster using the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
This chart has required variables, see [Configuration](#configuration).
## Uninstalling the Chart
To uninstall/delete the `my-release` deployment:
```bash
$ helm delete --purge my-release
```
The command removes all the Kubernetes components associated with the chart and deletes the release.
## Configuration
The following table lists the configurable parameters of the SSO chart and their default/required values.
Parameter | Description | Default
--- | --- | ---
`namespace` | namespace to use | `default`
`emailDomain` | the sso email domain for authentication | REQUIRED
`rootDomain` | the parent domain used for protecting your backends | REQUIRED
`auth.annotations` | extra annotations for auth pods | `{}`
`auth.domain` | the auth domain used for OAuth callbacks | REQUIRED
`auth.replicaCount` | desired number of auth pods | `1`
`auth.resources` | resource limits and requests for auth pods | `{ limits: { memory: "256Mi", cpu: "200m" }}`
`auth.nodeSelector` | node selector logic for auth pods | `{}`
`auth.tolerations` | resource tolerations for auth pods | `{}`
`auth.affinity` | node affinity for auth pods | `{}`
`auth.service.type` | type of auth service to create | `ClusterIP`
`auth.service.port` | port for the http auth service | `80`
`auth.secret` | secrets to be generated randomly with `openssl rand -base64 32 | head -c 32`. | REQUIRED if `auth.customSecret` is not set
`auth.tls` | tls configuration for central sso auth ingress. | `{ secretName: "sso-auth-tls-secret" }`
`auth.customSecret` | the secret key to reuse (avoids secret creation via helm) | REQUIRED if `auth.secret` is not set
`proxy.annotations` | extra annotations for proxy pods | `{}`
`proxy.providerUrlInternal` | url for split dns deployments |
`proxy.cluster` | the cluster name for SSO | `dev`
`proxy.replicaCount` | desired number of proxy pods | `1`
`proxy.resources` | resource limits and requests for proxy pods | `{ limits: { memory: "256Mi", cpu: "200m" }}`
`proxy.nodeSelector` | node selector logic for proxy pods | `{}`
`proxy.tolerations` | resource tolerations for proxy pods | `{}`
`proxy.affinity` | node affinity for proxy pods | `{}`
`proxy.service.type` | type of proxy service to create | `ClusterIP`
`proxy.service.port` | port for the http proxy service | `80`
`proxy.secret` | secrets to be generated randomly with `openssl rand -base64 32 | head -c 32 | base64`. | REQUIRED if `proxy.customSecret` is not set
`proxy.customSecret` | the secret key to reuse (avoids secret creation via helm) | REQUIRED if `proxy.secret` is not set
`provider.google` | the Oauth provider to use (only Google support for now) | REQUIRED
`provider.google.adminEmail` | the Google admin email | `undefined`
`provider.google.secret` | the Google OAuth secrets | REQUIRED if `provider.google.customSecret` is not set
`provider.google.customSecret` | the secret key to reuse instead of creating it via helm | REQUIRED if `provider.google.secret` is not set
`image.repository` | container image repository | `buzzfeed/sso`
`image.tag` | container image tag | `v1.0.0`
`image.pullPolicy` | container image pull policy | `IfNotPresent`
`ingress.annotations` | ingress load balancer annotations | `{}`
`ingress.hosts` | proxied hosts | `[]`
`ingress.tls` | tls certificates for the proxied hosts | `[]`
`upstreams` | configuration of services that use sso | `[]`
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
```bash
$ helm install --name my-release \
--set key_1=value_1,key_2=value_2 \
stable/buzzfeed-sso
```
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
```bash
$ helm install --name my-release -f values.yaml stable/buzzfeed-sso
```
> **Tip**: This will merge parameters with [values.yaml](values.yaml), which does not specify all the required values
### Example
**NEVER expose your `auth.secret`, `proxy.secret`, `provider.google.clientId`, `provider.google.clientSecret` and `provider.google.serviceAccount`.** Always keep them in a safe place and do not push them to any repository. As values are merged, you can always generate a different `.yaml` file. For instance:
```yaml
# values.yaml
emailDomain: 'email.coolcompany.foo'
rootDomain: 'coolcompany.foo'
auth:
domain: sso-auth.coolcompany.foo
proxy:
cluster: dev
google:
adminEmail: iamtheadmin@email.coolcompany.foo
```
```yaml
# secrets.yaml
auth:
secret:
codeSecret: 'randomSecret1'
cookieSecret: 'randomSecret2'
proxy:
secret:
clientId: 'randomSecret3'
clientSecret: 'randomSecret4'
cookieSecret: 'randomSecret6'
google:
secret:
clientId: 'googleSecret!'
clientSecret: 'evenMoreSecret'
serviceAccount: '{ <json content super secret> }'
```
Therefore, you could push your own `values.yaml` to a repo and keep `secrets.yaml` locally safe, and then install/update the chart:
```bash
$ helm install --name my-release -f values.yaml -f secrets.yaml stable/buzzfeed-sso
```
Alternatively, you can specify your own secret key, if you have already created it in the cluster. The secret should follow the data format defined in `secret.yaml` (auth and proxy) and `google-secret.yaml` (google provider).
```yaml
# values.yaml
emailDomain: 'email.coolcompany.foo'
rootDomain: 'coolcompany.foo'
auth:
domain: sso-auth.coolcompany.foo
customSecret: my-sso-auth-secret
proxy:
cluster: dev
customSecret: my-sso-proxy-secret
provider:
google:
adminEmail: iamtheadmin@email.coolcompany.foo
customSecret: my-sso-google-secret
```
## Updating the Chart
You can update the chart values and trigger a pod reload. If the configmap changes, it will automatically retrieve the new values.
```bash
$ helm upgrade -f values.yaml my-release stable/buzzfeed-sso
```
+134
View File
@@ -0,0 +1,134 @@
Please be patient: buzzfeed-sso might take a few minutes to install.
{{- if eq .Values.emailDomain "<your_email_domain>" }}
###############################################################################
#### ERROR: You did not provide an email domain. ####
###############################################################################
This deployment will be incomplete until you configure a valid email domain.
The email domain is required for the auth and proxy deployments.
{{- end }}
{{- if eq .Values.rootDomain "<your_root_domain>" }}
###############################################################################
#### ERROR: You did not provide a root domain. ####
###############################################################################
This deployment will be incomplete until you configure a valid root domain.
The root domain is required for the auth deployment.
{{- end }}
{{- if eq .Values.auth.domain "<your_auth_domain>" }}
###############################################################################
#### ERROR: You did not provide proper auth domain. ####
###############################################################################
This deployment will be incomplete until you configure a valid auth domain.
For instance, "sso-auth.mydomain.foo".
{{- end }}
{{- if not (or .Values.auth.secret .Values.auth.customSecret) }}
###############################################################################
#### ERROR: You did not provide proper auth secrets. ####
###############################################################################
This deployment will be incomplete until you configure proper auth secrets.
You can generate an auth secret by running
helm upgrade {{ .Release.Name }} \
--reuse-values \
--set auth.secret.codeSecret="$(openssl rand -base64 32 | head -c 32 | base64)" \
--set auth.secret.cookieSecret="$(openssl rand -base64 32 | head -c 32 | base64)" \
incubator/buzzfeed-sso
Or you can provide a custom auth secret that is a reference to an already created
Kubernetes secret resource.
kubectl create secret generic buzzfeed-sso-auth-secret \
--namespace={{ .Release.Namespace }} \
--from-literal=auth-code-secret="auth-code-secret"
--from-literal=auth-cookie-secret="auth-cookie-secret"
helm upgrade {{ .Release.Name }} \
--reuse-values \
--set auth.customSecret="buzzfeed-sso-auth-secret" \
incubator/buzzfeed-sso
{{- end }}
{{- if not (or .Values.proxy.secret .Values.proxy.customSecret) }}
###############################################################################
#### ERROR: You did not provide proper proxy secrets. ####
###############################################################################
This deployment will be incomplete until you configure proper proxy secrets.
You can generate a proxy secret by running
helm upgrade {{ .Release.Name }} \
--reuse-values \
--set proxy.secret.clientId="$(openssl rand -base64 32 | head -c 32 | base64)" \
--set proxy.secret.clientSecret="$(openssl rand -base64 32 | head -c 32 | base64)" \
--set proxy.secret.cookieSecret="$(openssl rand -base64 32 | head -c 32 | base64)" \
incubator/buzzfeed-sso
Or you can provide a custom proxy secret that is a reference to an already created
Kubernetes secret resource.
kubectl create secret generic buzzfeed-sso-proxy-secret \
--namespace={{ .Release.Namespace }} \
--from-literal=proxy-client-id="proxy-client-id"
--from-literal=proxy-client-secret="proxy-client-secret"
--from-literal=proxy-cookie-secret="proxy-cookie-secret"
helm upgrade {{ .Release.Name }} \
--reuse-values \
--set proxy.customSecret="buzzfeed-sso-proxy-secret" \
incubator/buzzfeed-sso
{{- end }}
{{- if not (or .Values.provider.google.secret .Values.provider.google.customSecret) }}
###############################################################################
#### ERROR: You did not provide a proper Google provider. ####
###############################################################################
This deployment will be incomplete until you configure a valid provider.
Currently, the only accepted provider is Google. You need to specify it with
a given secret or custom secret.
You can define the secret with your Google's client id, client secret and
service account in JSON format.
helm upgrade {{ .Release.Name }} \
--reuse-values \
--set provider.google.secret.clientId="foo123123-fake123123.apps.googleusercontent.com" \
--set provider.google.secret.clientSecret="googleOauthClientSecret" \
--set provider.google.secret.serviceAccount="$(cat myserviceaccount.json)" \
incubator/buzzfeed-sso
Or you can provide a custom secret that is a reference to an already created
Kubernetes secret resource.
kubectl create secret generic buzzfeed-sso-google-secret \
--namespace={{ .Release.Namespace }} \
--from-literal=google-client-id="foo123123-fake123123.apps.googleusercontent.com"
--from-literal=google-client-secret="googleOauthClientSecret"
--from-literal=service-account="$(cat myserviceaccount.json)"
helm upgrade {{ .Release.Name }} \
--reuse-values \
--set provider.google.customSecret="buzzfeed-sso-google-secret" \
incubator/buzzfeed-sso
{{- end }}
{{- if .Values.ingress.hosts }}
Visit the external application URLs to use your application:
{{- range .Values.ingress.hosts }}
https://{{ .domain }}{{ .path }}
{{- end }}
{{- end }}
@@ -0,0 +1,32 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "buzzfeed-sso.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "buzzfeed-sso.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "buzzfeed-sso.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
@@ -0,0 +1,150 @@
{{- if and (or .Values.auth.customSecret .Values.auth.secret) (or .Values.provider.google.customSecret .Values.provider.google.secret) (ne .Values.auth.domain "<your_auth_domain>") -}}
{{- $fullName := include "buzzfeed-sso.fullname" . -}}
{{- $googleSecret := .Values.provider.google.customSecret | default (printf "%s-google" ($fullName)) -}}
{{- $authSecret := .Values.auth.customSecret | default ($fullName) -}}
{{- $name := include "buzzfeed-sso.name" . -}}
{{- $authDomain := .Values.auth.domain -}}
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: {{ $fullName }}-auth
labels:
app: {{ $name }}
chart: {{ template "buzzfeed-sso.chart" . }}
component: {{ $name }}-auth
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
replicas: {{ .Values.auth.replicaCount }}
selector:
matchLabels:
app: {{ $name }}
component: {{ $name }}-auth
release: {{ .Release.Name }}
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- with .Values.auth.annotations }}
{{ toYaml . | indent 8 }}
{{- end }}
labels:
app: {{ $name }}
component: {{ $name }}-auth
release: {{ .Release.Name }}
spec:
{{- if .Values.provider.google }}
volumes:
- name: google-service-account
secret:
secretName: {{ $googleSecret }}
items:
- key: service-account
path: sso-serviceaccount.json
{{- end }}
containers:
- name: {{ .Chart.Name }}-auth
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
command: ["/bin/sso-auth"]
ports:
- name: http
containerPort: 4180
protocol: TCP
env:
- name: SSO_EMAIL_DOMAIN
value: {{ .Values.emailDomain | quote }}
- name: HOST
value: {{ $authDomain }}
- name: REDIRECT_URL
value: https://{{ $authDomain }}
- name: PROXY_ROOT_DOMAIN
value: {{ .Values.rootDomain | quote }}
- name: PROXY_CLIENT_ID
valueFrom:
secretKeyRef:
name: {{ $authSecret }}
key: proxy-client-id
- name: PROXY_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: {{ $authSecret }}
key: proxy-client-secret
- name: AUTH_CODE_SECRET
valueFrom:
secretKeyRef:
name: {{ $authSecret }}
key: auth-code-secret
- name: COOKIE_SECRET
valueFrom:
secretKeyRef:
name: {{ $authSecret }}
key: auth-cookie-secret
# # OLD_COOKIE_SECRET is the same as COOKIE_SECRET, not sure why its even needed at this point
- name: OLD_COOKIE_SECRET
valueFrom:
secretKeyRef:
name: {{ $authSecret }}
key: auth-cookie-secret
# STATSD_HOST and STATSD_PORT must be defined or the app wont launch, they dont need to be a real host / port
- name: STATSD_HOST
value: localhost
- name: STATSD_PORT
value: "11111"
- name: COOKIE_SECURE
value: "true"
- name: CLUSTER
value: dev
# Provider variables
{{- with .Values.provider.google }}
{{- if .adminEmail }}
- name: GOOGLE_ADMIN_EMAIL
value: {{ .adminEmail | quote }}
- name: GOOGLE_SERVICE_ACCOUNT_JSON
value: /creds/sso-serviceaccount.json
{{- end }}
- name: CLIENT_ID
valueFrom:
secretKeyRef:
name: {{ $googleSecret }}
key: google-client-id
- name: CLIENT_SECRET
valueFrom:
secretKeyRef:
name: {{ $googleSecret }}
key: google-client-secret
{{- end }}
readinessProbe:
httpGet:
path: /ping
port: 4180
scheme: HTTP
livenessProbe:
httpGet:
path: /ping
port: 4180
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 1
{{- if .Values.provider.google.adminEmail }}
volumeMounts:
- name: google-service-account
mountPath: /creds
readOnly: true
{{- end }}
resources:
{{ toYaml .Values.auth.resources | indent 12 }}
{{- with .Values.auth.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.auth.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.auth.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- end }}
@@ -0,0 +1,22 @@
{{- $name := include "buzzfeed-sso.name" . -}}
apiVersion: v1
kind: Service
metadata:
name: {{ template "buzzfeed-sso.fullname" . }}-auth
labels:
app: {{ $name }}
chart: {{ template "buzzfeed-sso.chart" . }}
component: {{ $name }}-auth
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
type: {{ .Values.auth.service.type }}
ports:
- name: http
port: {{ .Values.auth.service.port }}
targetPort: 4180
protocol: TCP
selector:
app: {{ $name }}
component: {{ $name }}-auth
release: {{ .Release.Name }}
@@ -0,0 +1,14 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "buzzfeed-sso.fullname" . }}
labels:
app: {{ template "buzzfeed-sso.name" . }}
chart: {{ template "buzzfeed-sso.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
data:
{{- with .Values.upstreams }}
upstream_configs.yml: |-
{{ toYaml . | indent 4 }}
{{- end }}
@@ -0,0 +1,18 @@
{{- if .Values.provider.google.secret }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "buzzfeed-sso.fullname" . }}-google
labels:
app: {{ template "buzzfeed-sso.name" . }}
chart: {{ template "buzzfeed-sso.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
type: Opaque
data:
{{- with .Values.provider.google.secret }}
google-client-id: {{ .clientId | b64enc }}
google-client-secret: {{ .clientSecret | b64enc }}
service-account: {{ .serviceAccount | b64enc }}
{{- end }}
{{- end }}
@@ -0,0 +1,48 @@
{{- if ne .Values.auth.domain "<your_auth_domain>" -}}
{{- $fullName := include "buzzfeed-sso.fullname" . -}}
{{- $authDomain := .Values.auth.domain -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
app: {{ template "buzzfeed-sso.name" . }}
chart: {{ template "buzzfeed-sso.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
{{- with .Values.ingress.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
tls:
- hosts:
- {{ $authDomain }}
secretName: {{ .Values.auth.tls.secretName -}}
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
rules:
# Upstreams that need SSO authentication
{{- range .Values.ingress.hosts }}
- host: {{ .domain }}
http:
paths:
- path: {{ .path }}
backend:
serviceName: {{ $fullName }}-proxy
servicePort: http
{{- end }}
# Global SSO used in the callback for login
- host: {{ $authDomain }}
http:
paths:
- path: /
backend:
serviceName: {{ $fullName }}-auth
servicePort: http
{{- end }}
@@ -0,0 +1,112 @@
{{- if or .Values.proxy.customSecret .Values.proxy.secret -}}
{{- $fullName := include "buzzfeed-sso.fullname" . -}}
{{- $proxySecret := .Values.proxy.customSecret | default ($fullName) -}}
{{- $name := include "buzzfeed-sso.name" . -}}
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: {{ $fullName }}-proxy
labels:
app: {{ $name }}
chart: {{ template "buzzfeed-sso.chart" . }}
component: {{ $name }}-proxy
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
replicas: {{ .Values.proxy.replicaCount }}
selector:
matchLabels:
app: {{ $name }}
component: {{ $name }}-proxy
release: {{ .Release.Name }}
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- with .Values.proxy.annotations }}
{{ toYaml . | indent 8 }}
{{- end }}
labels:
app: {{ $name }}
component: {{ $name }}-proxy
release: {{ .Release.Name }}
spec:
volumes:
- name: {{ $fullName }}
configMap:
name: {{ $fullName }}
containers:
- name: {{ .Chart.Name }}-proxy
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
command: ["/bin/sso-proxy"]
ports:
- name: http
containerPort: 8080
protocol: TCP
env:
- name: CLIENT_ID
valueFrom:
secretKeyRef:
name: {{ $proxySecret }}
key: proxy-client-id
- name: CLIENT_SECRET
valueFrom:
secretKeyRef:
name: {{ $proxySecret }}
key: proxy-client-secret
- name: COOKIE_SECRET
valueFrom:
secretKeyRef:
name: {{ $proxySecret }}
key: proxy-cookie-secret
- name: EMAIL_DOMAIN
value: {{ .Values.emailDomain | quote }}
- name: UPSTREAM_CONFIGS
value: /sso/upstream_configs.yml
- name: PROVIDER_URL
value: https://{{ .Values.auth.domain }}
# STATSD_HOST and STATSD_PORT must be defined or the app wont launch, they dont need to be a real host / port, but they do need to be defined.
- name: STATSD_HOST
value: localhost
- name: STATSD_PORT
value: "11111"
- name: COOKIE_SECURE
value: "true"
- name: CLUSTER
value: {{ .Values.proxy.cluster | quote }}
{{- if .Values.proxy.providerUrlInternal }}
- name: PROVIDER_URL_INTERNAL
value: {{ .Values.proxy.providerUrlInternal | quote }}
{{- end }}
readinessProbe:
httpGet:
path: /ping
port: 4180
scheme: HTTP
livenessProbe:
httpGet:
path: /ping
port: 4180
scheme: HTTP
initialDelaySeconds: 10
timeoutSeconds: 1
volumeMounts:
- name: {{ $fullName }}
mountPath: /sso
resources:
{{ toYaml .Values.proxy.resources | indent 12 }}
{{- with .Values.proxy.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.proxy.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.proxy.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
{{- end }}
@@ -0,0 +1,22 @@
{{- $name := include "buzzfeed-sso.name" . -}}
apiVersion: v1
kind: Service
metadata:
name: {{ template "buzzfeed-sso.fullname" . }}-proxy
labels:
app: {{ $name }}
chart: {{ template "buzzfeed-sso.chart" . }}
component: {{ $name }}-proxy
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
type: {{ .Values.proxy.service.type }}
ports:
- name: http
port: {{ .Values.proxy.service.port }}
targetPort: 4180
protocol: TCP
selector:
app: {{ $name }}
component: {{ $name }}-proxy
release: {{ .Release.Name }}
@@ -0,0 +1,22 @@
{{- if or .Values.auth.secret .Values.proxy.secret }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "buzzfeed-sso.fullname" . }}
labels:
app: {{ template "buzzfeed-sso.name" . }}
chart: {{ template "buzzfeed-sso.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
type: Opaque
data:
{{- with .Values.proxy.secret }}
proxy-client-id: {{ .clientId | b64enc }}
proxy-client-secret: {{ .clientSecret | b64enc }}
proxy-cookie-secret: {{ .cookieSecret | b64enc }}
{{- end }}
{{- with .Values.auth.secret }}
auth-code-secret: {{ .codeSecret | b64enc }}
auth-cookie-secret: {{ .cookieSecret | b64enc }}
{{- end }}
{{- end }}
+98
View File
@@ -0,0 +1,98 @@
# Default values for buzzfeed-sso.
emailDomain: "<your_email_domain>" # Required. e.g "email.mydomain.foo"
rootDomain: "<your_root_domain>" # Required. e.g "mydomain.foo"
auth:
annotations: {}
domain: "<your_auth_domain>" # Required. e.g "sso-auth.mydomain.foo"
replicaCount: 1
resources:
limits:
memory: "256Mi"
cpu: "200m"
nodeSelector: {}
tolerations: []
affinity: {}
service:
type: ClusterIP
port: 80
# Generate these secrets with the command:
# 'openssl rand -base64 32 | head -c 32 | base64'
secret: {} # Required (if customSecret is not set)
# codeSecret: ''
# cookieSecret: ''
# # Or if you do not want to create the secret via helm
# customSecret: my-sso-auth-secret
tls:
secretName: sso-auth-tls-secret
proxy:
annotations: {}
# providerUrlInternal: https://sso-auth.mydomain.com
cluster: dev
replicaCount: 1
resources:
limits:
memory: "256Mi"
cpu: "200m"
nodeSelector: {}
tolerations: []
affinity: {}
service:
type: ClusterIP
port: 80
# Generate these secrets with the command:
# 'openssl rand -base64 32 | head -c 32 | base64'
secret: {} # Required (if customSecret is not set)
# clientId: ''
# clientSecret: ''
# cookieSecret: ''
# # Or if you do not want to create the secret via helm
# customSecret: my-sso-proxy-secret
provider:
google: {} # Required.
# google:
# adminEmail: me@mydomain.foo
# secret:
# clientId: foo123123-fake123123.apps.googleusercontent.com
# clientSecret: googleOauthClientSecret
# serviceAccount: 'service account content in JSON format'
# # Or if you do not want to create the secret via helm
# google:
# adminEmail: me@mydomain.foo
# customSecret: my-sso-google-secret
image:
repository: buzzfeed/sso
tag: v1.1.0
pullPolicy: IfNotPresent
ingress:
annotations: {}
# kubernetes.io/ingress.class: nginx
# certmanager.k8s.io/cluster-issuer: my-letsencrypt-issuer
# ingress.kubernetes.io/ssl-redirect: "true"
hosts: []
# - domain: mybackend.mydomain.foo
# path: /
tls: []
# - secretName: mybackend-mydomain-tls
# hosts:
# - mybackend.mydomain.foo
upstreams: []
# See https://github.com/buzzfeed/sso/blob/f437f237ac977201f15868601c9bc0e9dff11f40/docs/sso_config.md#proxy-config
# - service: mybackend
# default:
# from: mybackend.mydomain.foo
# to: http://mybackend.mynamespace.svc.cluster.local:9091
# options:
# allowed_groups:
# - sso-test-group-1@example.com
# - sso-test-group-2@example.com
# skip_auth_regex:
# - ^\/github-webhook\/$
# header_overrides:
# X-Frame-Options: DENY