├── .gitignore ├── README.md ├── charts ├── gitea │ ├── .helmignore │ ├── Chart.yaml │ ├── requirements.lock │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── ingress.yaml │ │ ├── pvc.yaml │ │ ├── service.yaml │ │ ├── ssh-service.yaml │ │ ├── statefulset.yaml │ │ └── tests │ │ │ └── test-connection.yaml │ └── values.yaml ├── kube-oidc-proxy │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── clusterrole.yaml │ │ ├── clusterrolebinding.yaml │ │ ├── deployment.yaml │ │ ├── ingress.yaml │ │ ├── poddisruptionbudget.yaml │ │ ├── secret_config.yaml │ │ ├── secret_tls.yaml │ │ ├── service.yaml │ │ ├── serviceaccount.yaml │ │ └── tests │ │ │ └── test-connection.yaml │ └── values.yaml ├── oauth2-proxy │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── ci │ │ ├── default-values.yaml │ │ ├── ingress-extra-paths-values.yaml │ │ ├── pdb-values.yaml │ │ └── pod-security-context-values.yaml │ ├── default-values.yaml │ ├── pdb-values.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── configmap-authenticated-emails-file.yaml │ │ ├── configmap-htpasswd-file.yaml │ │ ├── configmap.yaml │ │ ├── deployment.yaml │ │ ├── google-secret.yaml │ │ ├── ingress.yaml │ │ ├── poddisruptionbudget.yaml │ │ ├── secret.yaml │ │ ├── service.yaml │ │ └── serviceaccount.yaml │ └── values.yaml └── openldap │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── configmap-customldif.yaml │ ├── configmap-env.yaml │ ├── deployment.yaml │ ├── pvc.yaml │ ├── secret.yaml │ ├── service.yaml │ └── tests │ │ ├── openldap-test-runner.yaml │ │ └── openldap-tests.yaml │ └── values.yaml ├── docker-registry ├── .DS_Store └── values-docker-registry.yml ├── gitea └── values-gitea.yml ├── group-auth └── cluster-role-binding.yml ├── harbor └── values-harbor.yml ├── jwt-ruby-example ├── Gemfile ├── Gemfile.lock └── main.rb ├── keycloak └── values-keycloak.yml ├── kube-oidc-proxy └── values-kube-oidc.yml ├── kubelogin └── kubeconfig.yml ├── nginx-demo-app └── values-nginx.yml ├── oauth2-proxy └── values-oauth2-proxy.yml └── openldap └── values-openldap.yml /.gitignore: -------------------------------------------------------------------------------- 1 | *.pem 2 | .envrc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is the supporting code for the tutorial series [A Comprehensive Guide to SSO on Kubernetes](http://localhost:4000/kubernetes-sso-a-comprehensive-guide). 2 | 3 | Some of the highlights this series explains how to do are: 4 | 5 | 1. Login to the `kubectl` cli using SSO credentials via the browser 6 | 1. Replace basic auth ingress annotations with equally simple but much more secure SSO annotations 7 | 1. Push and pull to a secure private docker registry with full ACL 8 | 9 | ## Structure 10 | 11 | - `charts/`: Charts which are currently only available as part of the deprecated `stable` helm repository. Any charts in this directory remain subject to the [licenses in the original repos, Apache 2.0 at time of writing](https://github.com/helm/charts/blob/master/LICENSE). As these charts become available elsewhere, they'll be removed when the tutorial series is updated. 12 | - `docker-registry/`: The example helm values file for configuring the basic docker registry chart 13 | - `gitea/`: The example helm values file for configuring gitea 14 | - `group-auth/`: An example cluster role binding definition for configuring a specific SSO group to automatically have cluster admin access 15 | - `harbor/`: The example helm values file for configuring harbor 16 | - `jwt-ruby-example/`: An example ruby application showing how to decode JSON Web Tokens 17 | - `keycloak/`: The example helm values file for configuring Keycloak 18 | - `kube-oidc-proxy/`: The example helm values for for configuring Kube OIDC Proxy 19 | - `kubelogin/`: An example KUBECONFIG file for use with kubelogin and kube oidc proxy 20 | - `nginx-demo-app/`: An example helm values file for deploying Nginx with ingress annotations which delegate authentication to Keycloak via OIDC and demonstrate passing the JWT through 21 | - `oauth2-proxy/`: An example helm values file for `oauth2-proxy` which provides the underlying endpoints needed for nginx to delegate auth to Keycloak 22 | - `openldap/`: An example helm values file for installing and configuring openldap 23 | -------------------------------------------------------------------------------- /charts/gitea/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /charts/gitea/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: A Helm chart for installing Gitea 4 | name: gitea 5 | version: 0.1.0 6 | -------------------------------------------------------------------------------- /charts/gitea/requirements.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: postgresql 3 | repository: https://charts.bitnami.com/bitnami 4 | version: 8.7.0 5 | digest: sha256:5e35b3b967df9a4b0e75ae3678193cbf0c531649631d3c7a5d46632a854564c7 6 | generated: "2020-04-06T10:13:02.629925+01:00" 7 | -------------------------------------------------------------------------------- /charts/gitea/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "gitea.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "gitea.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "gitea.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "gitea.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | echo "Visit http://127.0.0.1:8080 to use your application" 20 | kubectl port-forward $POD_NAME 8080:80 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /charts/gitea/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "gitea.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "gitea.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "gitea.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /charts/gitea/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "gitea.fullname" . -}} 3 | apiVersion: extensions/v1beta1 4 | kind: Ingress 5 | metadata: 6 | name: {{ $fullName }} 7 | labels: 8 | app.kubernetes.io/name: {{ include "gitea.name" . }} 9 | helm.sh/chart: {{ include "gitea.chart" . }} 10 | app.kubernetes.io/instance: {{ .Release.Name }} 11 | app.kubernetes.io/managed-by: {{ .Release.Service }} 12 | {{- with .Values.ingress.annotations }} 13 | annotations: 14 | {{- toYaml . | nindent 4 }} 15 | {{- end }} 16 | spec: 17 | {{- if .Values.ingress.tls }} 18 | tls: 19 | {{- range .Values.ingress.tls }} 20 | - hosts: 21 | {{- range .hosts }} 22 | - {{ . | quote }} 23 | {{- end }} 24 | secretName: {{ .secretName }} 25 | {{- end }} 26 | {{- end }} 27 | rules: 28 | {{- range .Values.ingress.hosts }} 29 | - host: {{ .host | quote }} 30 | http: 31 | paths: 32 | {{- range .paths }} 33 | - path: {{ . }} 34 | backend: 35 | serviceName: {{ $fullName }} 36 | servicePort: http 37 | {{- end }} 38 | {{- end }} 39 | {{- end }} 40 | -------------------------------------------------------------------------------- /charts/gitea/templates/pvc.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TalkingQuickly/kubernetes-sso-guide/4c5f976e4d72735809a5c86882ac2d0f648d0133/charts/gitea/templates/pvc.yaml -------------------------------------------------------------------------------- /charts/gitea/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "gitea.fullname" . }} 5 | labels: 6 | app.kubernetes.io/name: {{ include "gitea.name" . }} 7 | helm.sh/chart: {{ include "gitea.chart" . }} 8 | app.kubernetes.io/instance: {{ .Release.Name }} 9 | app.kubernetes.io/managed-by: {{ .Release.Service }} 10 | spec: 11 | type: {{ .Values.service.type }} 12 | ports: 13 | - port: {{ .Values.service.web.port }} 14 | targetPort: http 15 | protocol: TCP 16 | name: http 17 | 18 | - port: {{ .Values.service.ssh.port }} 19 | targetPort: ssh 20 | protocol: TCP 21 | name: ssh 22 | 23 | - port: 80 24 | targetPort: http 25 | protocol: TCP 26 | name: http-internal 27 | 28 | selector: 29 | app.kubernetes.io/name: {{ include "gitea.name" . }} 30 | app.kubernetes.io/instance: {{ .Release.Name }} 31 | -------------------------------------------------------------------------------- /charts/gitea/templates/ssh-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "gitea.fullname" . }}-ssh 5 | labels: 6 | app.kubernetes.io/name: {{ include "gitea.name" . }}-ssh 7 | helm.sh/chart: {{ include "gitea.chart" . }} 8 | app.kubernetes.io/instance: {{ .Release.Name }} 9 | app.kubernetes.io/managed-by: {{ .Release.Service }} 10 | spec: 11 | {{ if eq .Values.service.ssh.type "LoadBalancer"}} 12 | type: LoadBalancer 13 | ports: 14 | - name: ssh 15 | port: {{ .Values.service.ssh.port }} 16 | targetPort: {{ .Values.service.ssh.targetPort }} 17 | {{ else }} 18 | type: NodePort 19 | ports: 20 | - port: {{ .Values.service.ssh.port }} 21 | targetPort: {{ .Values.service.ssh.port }} 22 | nodePort: {{ .Values.service.ssh.nodePort }} 23 | {{ end }} 24 | 25 | selector: 26 | app.kubernetes.io/name: {{ include "gitea.name" . }} 27 | app.kubernetes.io/instance: {{ .Release.Name }} 28 | -------------------------------------------------------------------------------- /charts/gitea/templates/statefulset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: StatefulSet 3 | metadata: 4 | name: {{ include "gitea.fullname" . }} 5 | labels: 6 | app.kubernetes.io/name: {{ include "gitea.name" . }} 7 | helm.sh/chart: {{ include "gitea.chart" . }} 8 | app.kubernetes.io/instance: {{ .Release.Name }} 9 | app.kubernetes.io/managed-by: {{ .Release.Service }} 10 | spec: 11 | replicas: 1 12 | serviceName: {{ include "gitea.fullname" . }}-headless 13 | selector: 14 | matchLabels: 15 | app.kubernetes.io/name: {{ include "gitea.name" . }} 16 | app.kubernetes.io/instance: {{ .Release.Name }} 17 | template: 18 | metadata: 19 | labels: 20 | app.kubernetes.io/name: {{ include "gitea.name" . }} 21 | app.kubernetes.io/instance: {{ .Release.Name }} 22 | spec: 23 | containers: 24 | - name: {{ .Chart.Name }} 25 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 26 | imagePullPolicy: {{ .Values.image.pullPolicy }} 27 | env: 28 | - name: INSTALL_LOCK 29 | value: "{{ .Values.gitea.installLock }}" 30 | - name: APP_NAME 31 | value: "{{ .Values.gitea.appName }}" 32 | - name: SSH_DOMAIN 33 | value: "{{ .Values.gitea.sshDomain }}" 34 | - name: SSH_PORT 35 | value: "{{ .Values.gitea.sshPort }}" 36 | - name: SSH_LISTEN_PORT 37 | value: "22" 38 | - name: ROOT_URL 39 | value: "{{ .Values.gitea.protocol }}://{{ .Values.gitea.domain }}/" 40 | - name: RUN_MODE 41 | value: "prod" 42 | - name: REQUIRE_SIGNIN_VIEW 43 | value: "true" 44 | - name: DISABLE_REGISTRATION 45 | value: "true" 46 | - name: LEVEL 47 | value: "Debug" 48 | ports: 49 | - name: http 50 | containerPort: 3000 51 | protocol: TCP 52 | - name: ssh 53 | containerPort: 22 54 | protocol: TCP 55 | livenessProbe: 56 | httpGet: 57 | path: / 58 | port: http 59 | readinessProbe: 60 | httpGet: 61 | path: / 62 | port: http 63 | volumeMounts: 64 | - name: data 65 | mountPath: /data 66 | resources: 67 | {{- toYaml .Values.resources | nindent 12 }} 68 | volumes: 69 | - name: data 70 | persistentVolumeClaim: 71 | claimName: {{ template "gitea.fullname" . }} 72 | {{- with .Values.nodeSelector }} 73 | nodeSelector: 74 | {{- toYaml . | nindent 8 }} 75 | {{- end }} 76 | {{- with .Values.affinity }} 77 | affinity: 78 | {{- toYaml . | nindent 8 }} 79 | {{- end }} 80 | {{- with .Values.tolerations }} 81 | tolerations: 82 | {{- toYaml . | nindent 8 }} 83 | {{- end }} 84 | volumeClaimTemplates: 85 | - metadata: 86 | name: data 87 | annotations: {} 88 | spec: 89 | accessModes: 90 | - ReadWriteOnce 91 | resources: 92 | requests: 93 | storage: 10Gi 94 | -------------------------------------------------------------------------------- /charts/gitea/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "gitea.fullname" . }}-test-connection" 5 | labels: 6 | app.kubernetes.io/name: {{ include "gitea.name" . }} 7 | helm.sh/chart: {{ include "gitea.chart" . }} 8 | app.kubernetes.io/instance: {{ .Release.Name }} 9 | app.kubernetes.io/managed-by: {{ .Release.Service }} 10 | annotations: 11 | "helm.sh/hook": test-success 12 | spec: 13 | containers: 14 | - name: wget 15 | image: busybox 16 | command: ['wget'] 17 | args: ['{{ include "gitea.fullname" . }}:{{ .Values.service.port }}'] 18 | restartPolicy: Never 19 | -------------------------------------------------------------------------------- /charts/gitea/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for gitea. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: gitea/gitea 9 | tag: latest 10 | pullPolicy: IfNotPresent 11 | 12 | nameOverride: "" 13 | fullnameOverride: "" 14 | 15 | gitea: 16 | domain: gitea.gitea.svc.cluster.local 17 | protocol: http 18 | installLock: "true" 19 | appName: "Cluster Gitea" 20 | sshDomain: gitea.gitea.svc.cluster.local 21 | sshPort: 30010 22 | 23 | service: 24 | web: 25 | type: ClusterIP 26 | port: 3000 27 | ssh: 28 | type: NodePort 29 | port: 22 30 | nodePort: 30010 31 | 32 | ingress: 33 | enabled: true 34 | annotations: {} 35 | # kubernetes.io/ingress.class: nginx 36 | # kubernetes.io/tls-acme: "true" 37 | hosts: 38 | - host: gitea.local 39 | paths: ['/'] 40 | 41 | tls: [] 42 | # - secretName: chart-example-tls 43 | # hosts: 44 | # - chart-example.local 45 | 46 | resources: {} 47 | # We usually recommend not to specify default resources and to leave this as a conscious 48 | # choice for the user. This also increases chances charts run on environments with little 49 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 50 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 51 | # limits: 52 | # cpu: 100m 53 | # memory: 128Mi 54 | # requests: 55 | # cpu: 100m 56 | # memory: 128Mi 57 | 58 | nodeSelector: {} 59 | 60 | tolerations: [] 61 | 62 | affinity: {} 63 | 64 | persistence: 65 | size: 10G 66 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "v0.3.0" 3 | description: A Helm chart for kube-oidc-proxy 4 | home: https://github.com/jetstack/kube-oidc-proxy 5 | name: kube-oidc-proxy 6 | version: 0.3.1 7 | maintainers: 8 | - name: mhrabovcin 9 | - name: joshvanl 10 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/README.md: -------------------------------------------------------------------------------- 1 | # kube-oidc-proxy helm chart 2 | 3 | This is a `helm` chart that installs [`kube-oidc-proxy`](https://github.com/jetstack/kube-oidc-proxy/). 4 | This helm chart cannot be installed out of the box without providing own 5 | configuration. 6 | 7 | This helm chart is based on example configuration provided in `kube-oidc-proxy` 8 | [repository](https://github.com/jetstack/kube-oidc-proxy/blob/master/deploy/yaml/kube-oidc-proxy.yaml). 9 | 10 | Minimal required configuration is `oidc` section of `value.yaml` file. 11 | 12 | ```yaml 13 | oidc: 14 | clientId: my-client 15 | issuerUrl: https://accounts.google.com 16 | usernameClaim: email 17 | ``` 18 | 19 | When a custom root CA certificate is required it should be added as PEM encoded 20 | text value: 21 | 22 | ```yaml 23 | oidc: 24 | caPEM: | 25 | -----BEGIN CERTIFICATE----- 26 | MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG 27 | A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv 28 | b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw 29 | MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i 30 | YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT 31 | aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ 32 | jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp 33 | xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp 34 | 1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG 35 | snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ 36 | U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 37 | 9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E 38 | BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B 39 | AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz 40 | yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE 41 | 38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP 42 | AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad 43 | DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME 44 | HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== 45 | -----END CERTIFICATE----- 46 | ``` 47 | 48 | This minimal configuration gives a cluster internal IP address that can be used 49 | with `kubectl` to authenticate requests to Kubernetes API server. 50 | 51 | The service can be exposed via ingress controller and give access to external 52 | clients. Example of exposing via ingress controller. 53 | 54 | ```yaml 55 | ingress: 56 | enabled: true 57 | annotations: 58 | kubernetes.io/ingress.class: traefik 59 | traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip 60 | hosts: 61 | - host: "" 62 | paths: 63 | - /oidc-proxy 64 | ``` 65 | 66 | By default the helm chart will create self-signed TLS certificate for `kube-oidc-proxy` 67 | service. It is possible to provide secret name that contains TLS artifacts for 68 | service. The secret must be of `kubernetes.io/tls` type. 69 | 70 | ```yaml 71 | tls: 72 | secretName: my-tls-secret-with-key-and-cert 73 | ``` 74 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "kube-oidc-proxy.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "kube-oidc-proxy.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "kube-oidc-proxy.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "kube-oidc-proxy.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | echo "Visit http://127.0.0.1:8080 to use your application" 20 | kubectl port-forward $POD_NAME 8080:80 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "kube-oidc-proxy.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "kube-oidc-proxy.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "kube-oidc-proxy.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "kube-oidc-proxy.labels" -}} 38 | app.kubernetes.io/name: {{ include "kube-oidc-proxy.name" . }} 39 | helm.sh/chart: {{ include "kube-oidc-proxy.chart" . }} 40 | app.kubernetes.io/instance: {{ .Release.Name }} 41 | {{- if .Chart.AppVersion }} 42 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 43 | {{- end }} 44 | app.kubernetes.io/managed-by: {{ .Release.Service }} 45 | {{- end -}} 46 | 47 | {{/* 48 | Required claims serialized to CLI argument 49 | */}} 50 | {{- define "requiredClaims" -}} 51 | {{- if .Values.oidc.requiredClaims -}} 52 | {{- $local := (list) -}} 53 | {{- range $k, $v := .Values.oidc.requiredClaims -}} 54 | {{- $local = (printf "%s=%s" $k $v | append $local) -}} 55 | {{- end -}} 56 | {{ join "," $local }} 57 | {{- end -}} 58 | {{- end -}} 59 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/templates/clusterrole.yaml: -------------------------------------------------------------------------------- 1 | kind: ClusterRole 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | metadata: 4 | labels: 5 | {{ include "kube-oidc-proxy.labels" . | indent 4 }} 6 | name: {{ include "kube-oidc-proxy.fullname" . }} 7 | rules: 8 | - apiGroups: 9 | - "" 10 | resources: 11 | - "users" 12 | - "groups" 13 | - "serviceaccounts" 14 | verbs: 15 | - "impersonate" 16 | - apiGroups: 17 | - "authentication.k8s.io" 18 | resources: 19 | - "userextras/scopes" 20 | - "tokenreviews" 21 | verbs: 22 | - "create" 23 | - "impersonate" 24 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/templates/clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | kind: ClusterRoleBinding 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | metadata: 4 | labels: 5 | {{ include "kube-oidc-proxy.labels" . | indent 4 }} 6 | name: {{ include "kube-oidc-proxy.fullname" . }} 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: {{ include "kube-oidc-proxy.fullname" . }} 11 | subjects: 12 | - kind: ServiceAccount 13 | name: {{ include "kube-oidc-proxy.fullname" . }} 14 | namespace: {{ .Release.Namespace }} 15 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | {{ $fullname := include "kube-oidc-proxy.fullname" . }} 2 | {{ $defaultTlsSecretName := printf "%s-tls" $fullname }} 3 | {{ $tlsSecretName := .Values.tls.secretName | default $defaultTlsSecretName }} 4 | apiVersion: apps/v1 5 | kind: Deployment 6 | metadata: 7 | name: {{ include "kube-oidc-proxy.fullname" . }} 8 | labels: 9 | {{ include "kube-oidc-proxy.labels" . | indent 4 }} 10 | spec: 11 | replicas: {{ .Values.replicaCount }} 12 | selector: 13 | matchLabels: 14 | app.kubernetes.io/name: {{ include "kube-oidc-proxy.name" . }} 15 | app.kubernetes.io/instance: {{ .Release.Name }} 16 | template: 17 | metadata: 18 | labels: 19 | app.kubernetes.io/name: {{ include "kube-oidc-proxy.name" . }} 20 | app.kubernetes.io/instance: {{ .Release.Name }} 21 | spec: 22 | serviceAccountName: {{ include "kube-oidc-proxy.fullname" . }} 23 | containers: 24 | - name: {{ .Chart.Name }} 25 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 26 | imagePullPolicy: {{ .Values.image.pullPolicy }} 27 | ports: 28 | - containerPort: 443 29 | - containerPort: 8080 30 | readinessProbe: 31 | httpGet: 32 | path: /ready 33 | port: 8080 34 | initialDelaySeconds: 15 35 | periodSeconds: 10 36 | command: ["kube-oidc-proxy"] 37 | args: 38 | - "--secure-port=443" 39 | - "--tls-cert-file=/etc/oidc/tls/crt.pem" 40 | - "--tls-private-key-file=/etc/oidc/tls/key.pem" 41 | - "--oidc-client-id=$(OIDC_CLIENT_ID)" 42 | - "--oidc-issuer-url=$(OIDC_ISSUER_URL)" 43 | - "--oidc-username-claim=$(OIDC_USERNAME_CLAIM)" 44 | {{- if .Values.oidc.caPEM }} 45 | - "--oidc-ca-file=/etc/oidc/oidc-ca.pem" 46 | {{ end }} 47 | {{- if .Values.oidc.usernamePrefix }} 48 | - "--oidc-username-prefix=$(OIDC_USERNAME_PREFIX)" 49 | {{ end }} 50 | {{- if .Values.oidc.groupsClaim }} 51 | - "--oidc-groups-claim=$(OIDC_GROUPS_CLAIM)" 52 | {{ end }} 53 | {{- if .Values.oidc.groupsPrefix }} 54 | - "--oidc-groups-prefix=$(OIDC_GROUPS_PREFIX)" 55 | {{ end }} 56 | {{- if .Values.oidc.signingAlgs }} 57 | - "--oidc-signing-algs=$(OIDC_SIGNING_ALGS)" 58 | {{ end }} 59 | {{- if .Values.oidc.requiredClaims }} 60 | - "--oidc-signing-algs=$(OIDC_REQUIRED_CLAIMS)" 61 | {{ end }} 62 | {{- if .Values.tokenPassthrough.enabled }} 63 | - "--token-passthrough" 64 | {{- if .Values.tokenPassthrough.audiences }} 65 | - "--token-passthrough-audiences={{ join "," .Values.tokenPassthrough.audiences }}" 66 | {{ end }} 67 | {{ end }} 68 | {{- if .Values.extraImpersonationHeaders.clientIP }} 69 | - "--extra-user-header-client-ip" 70 | {{ end }} 71 | {{- if .Values.extraImpersonationHeaders.headers }} 72 | - "--extra-user-headers={{ .Values.extraImpersonationHeaders.headers }}" 73 | {{ end }} 74 | {{- range $key, $value := .Values.extraArgs -}} 75 | - "--{{ $key }}={{ $value -}}" 76 | {{ end }} 77 | resources: 78 | {{- toYaml .Values.resources | nindent 12 }} 79 | env: 80 | - name: OIDC_CLIENT_ID 81 | valueFrom: 82 | secretKeyRef: 83 | name: {{ include "kube-oidc-proxy.fullname" . }}-config 84 | key: oidc.client-id 85 | - name: OIDC_ISSUER_URL 86 | valueFrom: 87 | secretKeyRef: 88 | name: {{ include "kube-oidc-proxy.fullname" . }}-config 89 | key: oidc.issuer-url 90 | - name: OIDC_USERNAME_CLAIM 91 | valueFrom: 92 | secretKeyRef: 93 | name: {{ include "kube-oidc-proxy.fullname" . }}-config 94 | key: oidc.username-claim 95 | {{- if .Values.oidc.usernamePrefix }} 96 | - name: OIDC_USERNAME_PREFIX 97 | valueFrom: 98 | secretKeyRef: 99 | name: {{ include "kube-oidc-proxy.fullname" . }}-config 100 | key: oidc.username-prefix 101 | {{ end }} 102 | {{- if .Values.oidc.groupsClaim }} 103 | - name: OIDC_GROUPS_CLAIM 104 | valueFrom: 105 | secretKeyRef: 106 | name: {{ include "kube-oidc-proxy.fullname" . }}-config 107 | key: oidc.groups-claim 108 | {{ end }} 109 | {{- if .Values.oidc.groupsPrefix }} 110 | - name: OIDC_GROUPS_PREFIX 111 | valueFrom: 112 | secretKeyRef: 113 | name: {{ include "kube-oidc-proxy.fullname" . }}-config 114 | key: oidc.groups-prefix 115 | {{ end }} 116 | {{- if .Values.oidc.signingAlgs }} 117 | - name: OIDC_SIGNING_ALGS 118 | valueFrom: 119 | secretKeyRef: 120 | name: {{ include "kube-oidc-proxy.fullname" . }}-config 121 | key: oidc.signing-algs 122 | {{ end }} 123 | {{- if .Values.oidc.requiredClaims }} 124 | - name: OIDC_REQUIRED_CLAIMS 125 | valueFrom: 126 | secretKeyRef: 127 | name: {{ include "kube-oidc-proxy.fullname" . }}-config 128 | key: oidc.required-claims 129 | {{ end }} 130 | volumeMounts: 131 | {{- if .Values.oidc.caPEM }} 132 | - name: kube-oidc-proxy-config 133 | mountPath: /etc/oidc 134 | readOnly: true 135 | {{ end }} 136 | - name: kube-oidc-proxy-tls 137 | mountPath: /etc/oidc/tls 138 | readOnly: true 139 | {{- if .Values.extraVolumeMounts }}{{ toYaml .Values.extraVolumeMounts | trim | nindent 10 }}{{ end }} 140 | volumes: 141 | {{ if .Values.oidc.caPEM }} 142 | - name: kube-oidc-proxy-config 143 | secret: 144 | secretName: {{ include "kube-oidc-proxy.fullname" . }}-config 145 | items: 146 | - key: oidc.ca-pem 147 | path: oidc-ca.pem 148 | {{ end }} 149 | {{- if .Values.extraVolumes }}{{ toYaml .Values.extraVolumes | trim | nindent 8 }}{{ end }} 150 | - name: kube-oidc-proxy-tls 151 | secret: 152 | secretName: {{ $tlsSecretName }} 153 | items: 154 | - key: tls.crt 155 | path: crt.pem 156 | - key: tls.key 157 | path: key.pem 158 | {{- with .Values.nodeSelector }} 159 | nodeSelector: 160 | {{- toYaml . | nindent 8 }} 161 | {{- end }} 162 | {{- with .Values.affinity }} 163 | affinity: 164 | {{- toYaml . | nindent 8 }} 165 | {{- end }} 166 | {{- with .Values.tolerations }} 167 | tolerations: 168 | {{- toYaml . | nindent 8 }} 169 | {{- end }} 170 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "kube-oidc-proxy.fullname" . -}} 3 | apiVersion: extensions/v1beta1 4 | kind: Ingress 5 | metadata: 6 | name: {{ $fullName }} 7 | labels: 8 | {{ include "kube-oidc-proxy.labels" . | indent 4 }} 9 | {{- with .Values.ingress.annotations }} 10 | annotations: 11 | {{- toYaml . | nindent 4 }} 12 | {{- end }} 13 | spec: 14 | {{- if .Values.ingress.tls }} 15 | tls: 16 | {{- range .Values.ingress.tls }} 17 | - hosts: 18 | {{- range .hosts }} 19 | - {{ . | quote }} 20 | {{- end }} 21 | secretName: {{ .secretName }} 22 | {{- end }} 23 | {{- end }} 24 | rules: 25 | {{- range .Values.ingress.hosts }} 26 | - host: {{ .host | quote }} 27 | http: 28 | paths: 29 | {{- range .paths }} 30 | - path: {{ . }} 31 | backend: 32 | serviceName: {{ $fullName }} 33 | servicePort: https 34 | {{- end }} 35 | {{- end }} 36 | {{- end }} 37 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/templates/poddisruptionbudget.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.podDisruptionBudget.enabled -}} 2 | apiVersion: policy/v1beta1 3 | kind: PodDisruptionBudget 4 | metadata: 5 | name: {{ include "kube-oidc-proxy.fullname" . }} 6 | namespace: {{ $.Release.Namespace }} 7 | labels: 8 | {{ include "kube-oidc-proxy.labels" . | indent 4 }} 9 | spec: 10 | minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} 11 | selector: 12 | matchLabels: 13 | app.kubernetes.io/name: {{ include "kube-oidc-proxy.name" . }} 14 | app.kubernetes.io/instance: {{ .Release.Name }} 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/templates/secret_config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: {{ include "kube-oidc-proxy.fullname" . }}-config 5 | labels: 6 | {{ include "kube-oidc-proxy.labels" . | indent 4 }} 7 | type: Opaque 8 | data: 9 | {{- if .Values.oidc.caPEM }} 10 | oidc.ca-pem: {{ .Values.oidc.caPEM | default "" | b64enc }} 11 | {{- end }} 12 | 13 | {{- if .Values.oidc.issuerUrl }} 14 | oidc.issuer-url: {{ .Values.oidc.issuerUrl | b64enc }} 15 | {{- end }} 16 | 17 | {{- if .Values.oidc.usernameClaim }} 18 | oidc.username-claim: {{ .Values.oidc.usernameClaim | default "" | b64enc }} 19 | {{- end }} 20 | 21 | {{- if .Values.oidc.clientId }} 22 | oidc.client-id: {{ .Values.oidc.clientId | b64enc }} 23 | {{- end }} 24 | 25 | {{- if .Values.oidc.usernamePrefix }} 26 | oidc.username-prefix: {{ .Values.oidc.usernamePrefix | default "" | b64enc }} 27 | {{- end }} 28 | 29 | {{- if .Values.oidc.groupsClaim }} 30 | oidc.groups-claim: {{ .Values.oidc.groupsClaim | default "" | b64enc }} 31 | {{- end }} 32 | 33 | {{- if .Values.oidc.groupsPrefix }} 34 | oidc.groups-prefix: {{ .Values.oidc.groupsPrefix | default "" | b64enc }} 35 | {{- end }} 36 | 37 | {{- if .Values.oidc.signingAlgs }} 38 | oidc.signing-algs: {{ join "," .Values.oidc.signingAlgs | default "" | b64enc }} 39 | {{- end }} 40 | 41 | {{- if .Values.oidc.requiredClaims }} 42 | oidc.required-claims: {{ include "requiredClaims" . | b64enc }} 43 | {{- end }} 44 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/templates/secret_tls.yaml: -------------------------------------------------------------------------------- 1 | {{- if (not .Values.tls.secretName) }} 2 | {{ $fullname := include "kube-oidc-proxy.fullname" . }} 3 | {{ $ca := genCA (printf "%s-ca" $fullname) 3650 }} 4 | {{ $cn := printf "%s.%s.svc.cluster.local" $fullname .Release.Namespace }} 5 | {{ $server := genSignedCert $cn nil nil 365 $ca }} 6 | 7 | apiVersion: v1 8 | kind: Secret 9 | type: kubernetes.io/tls 10 | metadata: 11 | name: {{ template "kube-oidc-proxy.fullname" . }}-tls 12 | labels: 13 | {{ include "kube-oidc-proxy.labels" . | indent 4 }} 14 | data: 15 | tls.crt: {{ b64enc $server.Cert }} 16 | tls.key: {{ b64enc $server.Key }} 17 | {{ end }} 18 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "kube-oidc-proxy.fullname" . }} 5 | labels: 6 | {{ include "kube-oidc-proxy.labels" . | indent 4 }} 7 | annotations: 8 | {{- range $key, $val := .Values.service.annotations }} 9 | {{ $key }}: {{ $val | quote }} 10 | {{- end }} 11 | spec: 12 | type: {{ .Values.service.type }} 13 | {{- if .Values.service.loadBalancerIP }} 14 | loadBalancerIP: "{{ .Values.service.loadBalancerIP }}" 15 | {{- end }} 16 | {{- if .Values.service.loadBalancerSourceRanges }} 17 | loadBalancerSourceRanges: 18 | {{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} 19 | {{- end }} 20 | ports: 21 | - port: {{ .Values.service.port }} 22 | targetPort: 443 23 | protocol: TCP 24 | name: https 25 | selector: 26 | app.kubernetes.io/name: {{ include "kube-oidc-proxy.name" . }} 27 | app.kubernetes.io/instance: {{ .Release.Name }} 28 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | labels: 5 | {{ include "kube-oidc-proxy.labels" . | indent 4 }} 6 | name: {{ include "kube-oidc-proxy.fullname" . }} 7 | 8 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "kube-oidc-proxy.fullname" . }}-test-connection" 5 | labels: 6 | {{ include "kube-oidc-proxy.labels" . | indent 4 }} 7 | annotations: 8 | "helm.sh/hook": test-success 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "kube-oidc-proxy.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /charts/kube-oidc-proxy/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for kube-oidc-proxy. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: quay.io/jetstack/kube-oidc-proxy 9 | tag: v0.3.0 10 | pullPolicy: IfNotPresent 11 | 12 | imagePullSecrets: [] 13 | nameOverride: "" 14 | fullnameOverride: "" 15 | 16 | service: 17 | type: ClusterIP 18 | port: 443 19 | annotations: 20 | # You can use this field to add annotations to the Service. 21 | # Define it in a key-value pairs. E.g. 22 | # service.beta.kubernetes.io/aws-load-balancer-internal: true 23 | 24 | loadBalancerIP: "" 25 | loadBalancerSourceRanges: [] 26 | 27 | tls: 28 | # `secretName` must be a name of Secret of TLS type. If not provided a 29 | # self-signed certificate will get generated. 30 | secretName: 31 | 32 | # These values needs to be set in overrides in order to get kube-oidc-proxy 33 | # working. 34 | oidc: 35 | # A minimal configuration requires setting clientId, issuerUrl and usernameClaim 36 | # values. 37 | clientId: "" 38 | issuerUrl: "" 39 | usernameClaim: "" 40 | 41 | # PEM encoded value of CA cert that will verify TLS connection to 42 | # OIDC issuer URL. If not provided, default hosts root CA's will be used. 43 | caPEM: 44 | 45 | usernamePrefix: 46 | groupsClaim: 47 | groupsPrefix: 48 | 49 | signingAlgs: 50 | - RS256 51 | requiredClaims: {} 52 | 53 | # To enable token passthrough feature 54 | # https://github.com/jetstack/kube-oidc-proxy/blob/master/docs/tasks/token-passthrough.md 55 | tokenPassthrough: 56 | enabled: false 57 | audiences: [] 58 | 59 | # To add extra impersonation headers 60 | # https://github.com/jetstack/kube-oidc-proxy/blob/master/docs/tasks/extra-impersonation-headers.md 61 | extraImpersonationHeaders: 62 | clientIP: false 63 | #headers: key1=foo,key2=bar,key1=bar 64 | 65 | extraArgs: {} 66 | #audit-log-path: /audit-log 67 | #audit-policy-file: /audit/audit.yaml 68 | 69 | extraVolumeMounts: {} 70 | #- name: audit 71 | # mountPath: /audit 72 | # readOnly: true 73 | 74 | extraVolumes: {} 75 | #- configMap: 76 | #defaultMode: 420 77 | #name: kube-oidc-proxy-policy 78 | #name: audit 79 | 80 | ingress: 81 | enabled: false 82 | annotations: {} 83 | # kubernetes.io/ingress.class: nginx 84 | # kubernetes.io/tls-acme: "true" 85 | hosts: 86 | - host: chart-example.local 87 | paths: [] 88 | 89 | tls: [] 90 | # - secretName: chart-example-tls 91 | # hosts: 92 | # - chart-example.local 93 | 94 | # Enable Pod Disruption Budget 95 | podDisruptionBudget: 96 | enabled: false 97 | minAvailable: 1 98 | 99 | resources: {} 100 | # We usually recommend not to specify default resources and to leave this as a conscious 101 | # choice for the user. This also increases chances charts run on environments with little 102 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 103 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 104 | # limits: 105 | # cpu: 100m 106 | # memory: 128Mi 107 | # requests: 108 | # cpu: 100m 109 | # memory: 128Mi 110 | # 111 | 112 | initContainers: [] 113 | 114 | nodeSelector: {} 115 | 116 | tolerations: [] 117 | 118 | affinity: {} 119 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | 23 | OWNERS 24 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: oauth2-proxy 2 | version: 3.2.5 3 | apiVersion: v1 4 | appVersion: 5.1.0 5 | home: https://pusher.github.io/oauth2_proxy/ 6 | description: DEPRECATED - A reverse proxy that provides authentication with Google, Github or other providers 7 | keywords: 8 | - kubernetes 9 | - oauth 10 | - oauth2 11 | - authentication 12 | - google 13 | - github 14 | deprecated: true 15 | sources: 16 | - https://github.com/pusher/oauth2_proxy 17 | engine: gotpl 18 | kubeVersion: ">=1.9.0-0" 19 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/README.md: -------------------------------------------------------------------------------- 1 | # ⚠️ Repo Archive Notice 2 | 3 | As of Nov 13, 2020, charts in this repo will no longer be updated. 4 | For more information, see the Helm Charts [Deprecation and Archive Notice](https://github.com/helm/charts#%EF%B8%8F-deprecation-and-archive-notice), and [Update](https://helm.sh/blog/charts-repo-deprecation/). 5 | 6 | # oauth2-proxy 7 | 8 | [oauth2-proxy](https://github.com/pusher/oauth2_proxy) is a reverse proxy and static file server that provides authentication using Providers (Google, GitHub, and others) to validate accounts by email, domain or group. 9 | 10 | ## DEPRECATION NOTICE 11 | 12 | This chart is deprecated and no longer supported. 13 | 14 | ## TL;DR; 15 | 16 | ```console 17 | $ helm install stable/oauth2-proxy 18 | ``` 19 | 20 | ## Introduction 21 | 22 | This chart bootstraps an oauth2-proxy deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. 23 | 24 | ## Installing the Chart 25 | 26 | To install the chart with the release name `my-release`: 27 | 28 | ```console 29 | $ helm install stable/oauth2-proxy --name my-release 30 | ``` 31 | 32 | The command deploys oauth2-proxy on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. 33 | 34 | ## Uninstalling the Chart 35 | 36 | To uninstall/delete the `my-release` deployment: 37 | 38 | ```console 39 | $ helm delete my-release 40 | ``` 41 | 42 | The command removes all the Kubernetes components associated with the chart and deletes the release. 43 | 44 | ## Upgrading an existing Release to a new major version 45 | 46 | A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an 47 | incompatible breaking change needing manual actions. 48 | 49 | ### To 1.0.0 50 | 51 | This version upgrade oauth2-proxy to v4.0.0. Please see the [changelog](https://github.com/pusher/oauth2_proxy/blob/v4.0.0/CHANGELOG.md#v400) in order to upgrade. 52 | 53 | ### To 2.0.0 54 | 55 | Version 2.0.0 of this chart introduces support for Kubernetes v1.16.x by way of addressing the deprecation of the Deployment object apiVersion `apps/v1beta2`. See [the v1.16 API deprecations page](https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/) for more information. 56 | 57 | Due to [this issue](https://github.com/helm/helm/issues/6583) there may be errors performing a `helm upgrade`of this chart from versions earlier than 2.0.0. 58 | 59 | ### To 3.0.0 60 | 61 | Version 3.0.0 introduces support for [EKS IAM roles for service accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) by adding a managed service account to the chart. This is a breaking change since the service account is enabled by default. To disable this behaviour set `serviceAccount.enabled` to `false` 62 | 63 | ## Configuration 64 | 65 | The following table lists the configurable parameters of the oauth2-proxy chart and their default values. 66 | 67 | Parameter | Description | Default 68 | --- | --- | --- 69 | `affinity` | node/pod affinities | None 70 | `authenticatedEmailsFile.enabled` | Enables authorize individual email addresses | `false` 71 | `authenticatedEmailsFile.template` | Name of the configmap that is handled outside of that chart | `""` 72 | `authenticatedEmailsFile.restricted_access` | [email addresses](https://github.com/pusher/oauth2_proxy#email-authentication) list config | `""` 73 | `config.clientID` | oauth client ID | `""` 74 | `config.clientSecret` | oauth client secret | `""` 75 | `config.cookieSecret` | server specific cookie for the secret; create a new one with `openssl rand -base64 32 | head -c 32 | base64` | `""` 76 | `config.existingSecret` | existing Kubernetes secret to use for OAuth2 credentials. See [secret template](https://github.com/helm/charts/blob/master/stable/oauth2-proxy/templates/secret.yaml) for the required values | `nil` 77 | `config.configFile` | custom [oauth2_proxy.cfg](https://github.com/pusher/oauth2_proxy/blob/master/contrib/oauth2_proxy.cfg.example) contents for settings not overridable via environment nor command line | `""` 78 | `config.existingConfig` | existing Kubernetes configmap to use for the configuration file. See [config template](https://github.com/helm/charts/blob/master/stable/oauth2-proxy/templates/configmap.yaml) for the required values | `nil` 79 | `config.google.adminEmail` | user impersonated by the google service account | `""` 80 | `config.google.serviceAccountJson` | google service account json contents | `""` 81 | `config.google.existingConfig` | existing Kubernetes configmap to use for the service account file. See [google secret template](https://github.com/helm/charts/blob/master/stable/oauth2-proxy/templates/google-secret.yaml) for the required values | `nil` 82 | `extraArgs` | key:value list of extra arguments to give the binary | `{}` 83 | `extraEnv` | key:value list of extra environment variables to give the binary | `[]` 84 | `extraVolumes` | list of extra volumes | `[]` 85 | `extraVolumeMounts` | list of extra volumeMounts | `[]` 86 | `htpasswdFile.enabled` | enable htpasswd-file option | `false` 87 | `htpasswdFile.entries` | list of [SHA encrypted user:passwords](https://pusher.github.io/oauth2_proxy/configuration#command-line-options) | `{}` 88 | `htpasswdFile.existingSecret` | existing Kubernetes secret to use for OAuth2 htpasswd file | `""` 89 | `httpScheme` | `http` or `https`. `name` used for port on the deployment. `httpGet` port `name` and `scheme` used for `liveness`- and `readinessProbes`. `name` and `targetPort` used for the service. | `http` 90 | `image.pullPolicy` | Image pull policy | `IfNotPresent` 91 | `image.repository` | Image repository | `quay.io/pusher/oauth2_proxy` 92 | `image.tag` | Image tag | `v5.1.0` 93 | `imagePullSecrets` | Specify image pull secrets | `nil` (does not add image pull secrets to deployed pods) 94 | `ingress.enabled` | Enable Ingress | `false` 95 | `ingress.path` | Ingress accepted path | `/` 96 | `ingress.extraPaths` | Ingress extra paths to prepend to every host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions). | `[]` 97 | `ingress.annotations` | Ingress annotations | `nil` 98 | `ingress.hosts` | Ingress accepted hostnames | `nil` 99 | `ingress.tls` | Ingress TLS configuration | `nil` 100 | `livenessProbe.enabled` | enable Kubernetes livenessProbe. Disable to use oauth2-proxy with Istio mTLS. See [Istio FAQ](https://istio.io/help/faq/security/#k8s-health-checks) | `true` 101 | `livenessProbe.initialDelaySeconds` | number of seconds | 0 102 | `livenessProbe.timeoutSeconds` | number of seconds | 1 103 | `nodeSelector` | node labels for pod assignment | `{}` 104 | `podAnnotations` | annotations to add to each pod | `{}` 105 | `podLabels` | additional labesl to add to each pod | `{}` 106 | `podDisruptionBudget.enabled`| Enabled creation of PodDisruptionBudget (only if replicaCount > 1) | true 107 | `podDisruptionBudget.minAvailable`| minAvailable parameter for PodDisruptionBudget | 1 108 | `podSecurityContext` | Kubernetes security context to apply to pod | `{}` 109 | `priorityClassName` | priorityClassName | `nil` 110 | `readinessProbe.enabled` | enable Kubernetes readinessProbe. Disable to use oauth2-proxy with Istio mTLS. See [Istio FAQ](https://istio.io/help/faq/security/#k8s-health-checks) | `true` 111 | `readinessProbe.initialDelaySeconds` | number of seconds | 0 112 | `readinessProbe.timeoutSeconds` | number of seconds | 1 113 | `readinessProbe.periodSeconds` | number of seconds | 10 114 | `readinessProbe.successThreshold` | number of successes | 1 115 | `replicaCount` | desired number of pods | `1` 116 | `resources` | pod resource requests & limits | `{}` 117 | `service.port` | port for the service | `80` 118 | `service.type` | type of service | `ClusterIP` 119 | `service.clusterIP` | cluster ip address | `nil` 120 | `service.loadBalancerIP` | ip of load balancer | `nil` 121 | `service.loadBalancerSourceRanges` | allowed source ranges in load balancer | `nil` 122 | `serviceAccount.enabled` | create a service account | `true` 123 | `serviceAccount.name` | the service account name | `` 124 | `serviceAccount.annotations` | (optional) annotations for the service account | `{}` 125 | `tolerations` | list of node taints to tolerate | `[]` 126 | `securityContext.enabled` | enable Kubernetes security context on container | `false` 127 | `securityContext.runAsNonRoot` | make sure that the container runs as a non-root user | `true` 128 | `proxyVarsAsSecrets` | choose between environment values or secrets for setting up OAUTH2_PROXY variables. When set to false, remember to add the variables OAUTH2_PROXY_CLIENT_ID, OAUTH2_PROXY_CLIENT_SECRET, OAUTH2_PROXY_COOKIE_SECRET in extraEnv | `true` 129 | 130 | 131 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, 132 | 133 | ```console 134 | $ helm install stable/oauth2-proxy --name my-release \ 135 | --set=image.tag=v0.0.2,resources.limits.cpu=200m 136 | ``` 137 | 138 | Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, 139 | 140 | ```console 141 | $ helm install stable/oauth2-proxy --name my-release -f values.yaml 142 | ``` 143 | 144 | > **Tip**: You can use the default [values.yaml](values.yaml) 145 | 146 | ## SSL Configuration 147 | 148 | See: [SSL Configuration](https://pusher.github.io/oauth2_proxy/tls-configuration). 149 | Use ```values.yaml``` like: 150 | 151 | ```yaml 152 | ... 153 | extraArgs: 154 | tls-cert: /path/to/cert.pem 155 | tls-key: /path/to/cert.key 156 | 157 | extraVolumes: 158 | - name: ssl-cert 159 | secret: 160 | secretName: my-ssl-secret 161 | 162 | extraVolumeMounts: 163 | - mountPath: /path/to/ 164 | name: ssl-cert 165 | ... 166 | ``` 167 | 168 | With a secret called `my-ssl-secret`: 169 | 170 | ```yaml 171 | ... 172 | data: 173 | cert.pem: AB..== 174 | cert.key: CD..== 175 | ``` 176 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/ci/default-values.yaml: -------------------------------------------------------------------------------- 1 | # Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. 2 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/ci/ingress-extra-paths-values.yaml: -------------------------------------------------------------------------------- 1 | ingress: 2 | extraPaths: 3 | - path: /* 4 | backend: 5 | serviceName: ssl-redirect 6 | servicePort: use-annotation 7 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/ci/pdb-values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 2 # Enables PodDisruptionBudget which is disabled when replicaCount is 1 2 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/ci/pod-security-context-values.yaml: -------------------------------------------------------------------------------- 1 | # Allocate a FSGroup that owns the pod’s volumes via podSecurityContext 2 | --- 3 | podSecurityContext: 4 | fsGroup: 2000 5 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/default-values.yaml: -------------------------------------------------------------------------------- 1 | # Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. 2 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/pdb-values.yaml: -------------------------------------------------------------------------------- 1 | # Will trigger creation of pdb 2 | replicaCount: 2 3 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | To verify that oauth2-proxy has started, run: 2 | 3 | kubectl --namespace={{ .Release.Namespace }} get pods -l "app={{ template "oauth2-proxy.fullname" . }}" 4 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "oauth2-proxy.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "oauth2-proxy.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "oauth2-proxy.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Get the secret name. 36 | */}} 37 | {{- define "oauth2-proxy.secretName" -}} 38 | {{- if .Values.config.existingSecret -}} 39 | {{- printf "%s" .Values.config.existingSecret -}} 40 | {{- else -}} 41 | {{- printf "%s" (include "oauth2-proxy.fullname" .) -}} 42 | {{- end -}} 43 | {{- end -}} 44 | 45 | {{/* 46 | Create the name of the service account to use 47 | */}} 48 | {{- define "oauth2-proxy.serviceAccountName" -}} 49 | {{- if .Values.serviceAccount.enabled -}} 50 | {{ default (include "oauth2-proxy.fullname" .) .Values.serviceAccount.name }} 51 | {{- else -}} 52 | {{ default "default" .Values.serviceAccount.name }} 53 | {{- end -}} 54 | {{- end -}} 55 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/templates/configmap-authenticated-emails-file.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.authenticatedEmailsFile.enabled }} 2 | {{- if .Values.authenticatedEmailsFile.restricted_access }} 3 | apiVersion: v1 4 | kind: ConfigMap 5 | metadata: 6 | labels: 7 | app: {{ template "oauth2-proxy.name" . }} 8 | chart: {{ template "oauth2-proxy.chart" . }} 9 | heritage: {{ .Release.Service }} 10 | release: {{ .Release.Name }} 11 | name: {{ template "oauth2-proxy.fullname" . }}-accesslist 12 | data: 13 | restricted_user_access: {{ .Values.authenticatedEmailsFile.restricted_access | quote }} 14 | {{- end }} 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/templates/configmap-htpasswd-file.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.htpasswdFile.enabled (not .Values.htpasswdFile.existingSecret) }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | labels: 6 | app: {{ template "oauth2-proxy.name" . }} 7 | chart: {{ template "oauth2-proxy.chart" . }} 8 | heritage: {{ .Release.Service }} 9 | release: {{ .Release.Name }} 10 | name: {{ template "oauth2-proxy.fullname" . }}-htpasswd-file 11 | type: Opaque 12 | stringData: 13 | users.txt: |- 14 | {{- range $entries := .Values.htpasswdFile.entries }} 15 | {{ $entries }} 16 | {{- end -}} 17 | {{- end }} -------------------------------------------------------------------------------- /charts/oauth2-proxy/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if not .Values.config.existingConfig }} 2 | {{- if .Values.config.configFile }} 3 | apiVersion: v1 4 | kind: ConfigMap 5 | metadata: 6 | labels: 7 | app: {{ template "oauth2-proxy.name" . }} 8 | chart: {{ template "oauth2-proxy.chart" . }} 9 | heritage: {{ .Release.Service }} 10 | release: {{ .Release.Name }} 11 | name: {{ template "oauth2-proxy.fullname" . }} 12 | data: 13 | oauth2_proxy.cfg: {{ .Values.config.configFile | quote }} 14 | {{- end }} 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | app: {{ template "oauth2-proxy.name" . }} 6 | chart: {{ template "oauth2-proxy.chart" . }} 7 | heritage: {{ .Release.Service }} 8 | release: {{ .Release.Name }} 9 | name: {{ template "oauth2-proxy.fullname" . }} 10 | spec: 11 | replicas: {{ .Values.replicaCount }} 12 | selector: 13 | matchLabels: 14 | app: {{ template "oauth2-proxy.name" . }} 15 | release: {{ .Release.Name }} 16 | template: 17 | metadata: 18 | annotations: 19 | checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} 20 | checksum/config-emails: {{ include (print $.Template.BasePath "/configmap-authenticated-emails-file.yaml") . | sha256sum }} 21 | checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} 22 | checksum/google-secret: {{ include (print $.Template.BasePath "/google-secret.yaml") . | sha256sum }} 23 | {{- if .Values.htpasswdFile.enabled }} 24 | checksum/htpasswd: {{ include (print $.Template.BasePath "/configmap-htpasswd-file.yaml") . | sha256sum }} 25 | {{- end }} 26 | {{- if .Values.podAnnotations }} 27 | {{ toYaml .Values.podAnnotations | indent 8 }} 28 | {{- end }} 29 | labels: 30 | app: {{ template "oauth2-proxy.name" . }} 31 | release: "{{ .Release.Name }}" 32 | {{- if .Values.podLabels }} 33 | {{ toYaml .Values.podLabels | indent 8 }} 34 | {{- end }} 35 | spec: 36 | {{- if .Values.priorityClassName }} 37 | priorityClassName: "{{ .Values.priorityClassName }}" 38 | {{- end }} 39 | {{- with .Values.podSecurityContext }} 40 | securityContext: 41 | {{- toYaml . | nindent 8 }} 42 | {{- end }} 43 | serviceAccountName: {{ template "oauth2-proxy.serviceAccountName" . }} 44 | containers: 45 | - name: {{ .Chart.Name }} 46 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 47 | imagePullPolicy: {{ .Values.image.pullPolicy }} 48 | args: 49 | - --http-address=0.0.0.0:4180 50 | {{- range $key, $value := .Values.extraArgs }} 51 | {{- if $value }} 52 | - --{{ $key }}={{ $value }} 53 | {{- else }} 54 | - --{{ $key }} 55 | {{- end }} 56 | {{- end }} 57 | {{- if or .Values.config.existingConfig .Values.config.configFile }} 58 | - --config=/etc/oauth2_proxy/oauth2_proxy.cfg 59 | {{- end }} 60 | {{- if .Values.authenticatedEmailsFile.enabled }} 61 | {{- if .Values.authenticatedEmailsFile.template }} 62 | - --authenticated-emails-file=/etc/oauth2-proxy/{{ .Values.authenticatedEmailsFile.template }} 63 | {{- else }} 64 | - --authenticated-emails-file=/etc/oauth2-proxy/authenticated-emails-list 65 | {{- end }} 66 | {{- end }} 67 | {{- with .Values.config.google }} 68 | {{- if and .adminEmail (or .serviceAccountJson .existingSecret) }} 69 | - --google-admin-email={{ .adminEmail }} 70 | - --google-service-account-json=/google/service-account.json 71 | {{- end }} 72 | {{- end }} 73 | {{- if .Values.htpasswdFile.enabled }} 74 | - --htpasswd-file=/etc/oauth2_proxy/htpasswd/users.txt 75 | {{- end }} 76 | env: 77 | {{- if .Values.proxyVarsAsSecrets }} 78 | - name: OAUTH2_PROXY_CLIENT_ID 79 | valueFrom: 80 | secretKeyRef: 81 | name: {{ template "oauth2-proxy.secretName" . }} 82 | key: client-id 83 | - name: OAUTH2_PROXY_CLIENT_SECRET 84 | valueFrom: 85 | secretKeyRef: 86 | name: {{ template "oauth2-proxy.secretName" . }} 87 | key: client-secret 88 | - name: OAUTH2_PROXY_COOKIE_SECRET 89 | valueFrom: 90 | secretKeyRef: 91 | name: {{ template "oauth2-proxy.secretName" . }} 92 | key: cookie-secret 93 | {{- end }} 94 | {{- if .Values.extraEnv }} 95 | {{ toYaml .Values.extraEnv | indent 8 }} 96 | {{- end }} 97 | ports: 98 | - containerPort: 4180 99 | name: {{ .Values.httpScheme }} 100 | protocol: TCP 101 | {{- if .Values.livenessProbe.enabled }} 102 | livenessProbe: 103 | httpGet: 104 | path: /ping 105 | port: {{ .Values.httpScheme }} 106 | scheme: {{ .Values.httpScheme | upper }} 107 | initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} 108 | timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} 109 | {{- end }} 110 | {{- if .Values.readinessProbe.enabled }} 111 | readinessProbe: 112 | httpGet: 113 | path: /ping 114 | port: {{ .Values.httpScheme }} 115 | scheme: {{ .Values.httpScheme | upper }} 116 | initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} 117 | timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} 118 | successThreshold: {{ .Values.readinessProbe.successThreshold }} 119 | periodSeconds: {{ .Values.readinessProbe.periodSeconds }} 120 | {{- end }} 121 | resources: 122 | {{ toYaml .Values.resources | indent 10 }} 123 | volumeMounts: 124 | {{- with .Values.config.google }} 125 | {{- if and .adminEmail (or .serviceAccountJson .existingSecret) }} 126 | - name: google-secret 127 | mountPath: /google 128 | readOnly: true 129 | {{- end }} 130 | {{- end }} 131 | {{- if or .Values.config.existingConfig .Values.config.configFile }} 132 | - mountPath: /etc/oauth2_proxy 133 | name: configmain 134 | {{- end }} 135 | {{- if .Values.authenticatedEmailsFile.enabled }} 136 | - mountPath: /etc/oauth2-proxy 137 | name: configaccesslist 138 | readOnly: true 139 | {{- end }} 140 | {{- if .Values.htpasswdFile.enabled }} 141 | - mountPath: /etc/oauth2_proxy/htpasswd 142 | name: {{ template "oauth2-proxy.fullname" . }}-htpasswd-file 143 | readOnly: true 144 | {{- end }} 145 | {{- if ne (len .Values.extraVolumeMounts) 0 }} 146 | {{ toYaml .Values.extraVolumeMounts | indent 8 }} 147 | {{- end }} 148 | {{- if .Values.securityContext.enabled }} 149 | securityContext: 150 | runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} 151 | {{- end}} 152 | volumes: 153 | {{- with .Values.config.google }} 154 | {{- if and .adminEmail (or .serviceAccountJson .existingSecret) }} 155 | - name: google-secret 156 | secret: 157 | secretName: {{ if .existingSecret }}{{ .existingSecret }}{{ else }} {{ template "oauth2-proxy.secretName" $ }}{{ end }} 158 | {{- end }} 159 | {{- end }} 160 | 161 | {{- if .Values.htpasswdFile.enabled }} 162 | - name: {{ template "oauth2-proxy.fullname" . }}-htpasswd-file 163 | secret: 164 | secretName: {{ if .Values.htpasswdFile.existingSecret }}{{ .Values.htpasswdFile.existingSecret }}{{ else }} {{ template "oauth2-proxy.fullname" . }}-htpasswd-file {{ end }} 165 | {{- end }} 166 | 167 | {{- if or .Values.config.existingConfig .Values.config.configFile }} 168 | - configMap: 169 | defaultMode: 420 170 | name: {{ if .Values.config.existingConfig }}{{ .Values.config.existingConfig }}{{ else }}{{ template "oauth2-proxy.fullname" . }}{{ end }} 171 | name: configmain 172 | {{- end }} 173 | {{- if ne (len .Values.extraVolumes) 0 }} 174 | {{ toYaml .Values.extraVolumes | indent 6 }} 175 | {{- end }} 176 | {{- if .Values.authenticatedEmailsFile.enabled }} 177 | - configMap: 178 | {{- if .Values.authenticatedEmailsFile.template }} 179 | name: {{ .Values.authenticatedEmailsFile.template }} 180 | {{- else }} 181 | name: {{ template "oauth2-proxy.fullname" . }}-accesslist 182 | {{- end }} 183 | items: 184 | - key: restricted_user_access 185 | {{- if .Values.authenticatedEmailsFile.template }} 186 | path: {{ .Values.authenticatedEmailsFile.template }} 187 | {{- else }} 188 | path: authenticated-emails-list 189 | {{- end }} 190 | name: configaccesslist 191 | {{- end }} 192 | 193 | {{- if .Values.imagePullSecrets }} 194 | imagePullSecrets: 195 | {{ toYaml .Values.imagePullSecrets | indent 8 }} 196 | {{- end }} 197 | {{- if .Values.affinity }} 198 | affinity: 199 | {{ toYaml .Values.affinity | indent 8 }} 200 | {{- end }} 201 | {{- if .Values.nodeSelector }} 202 | nodeSelector: 203 | {{ toYaml .Values.nodeSelector | indent 8 }} 204 | {{- end }} 205 | tolerations: 206 | {{ toYaml .Values.tolerations | indent 8 }} 207 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/templates/google-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.config.google (not .Values.config.google.existingSecret) }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | labels: 6 | app: {{ template "oauth2-proxy.name" . }} 7 | chart: {{ template "oauth2-proxy.chart" . }} 8 | heritage: {{ .Release.Service }} 9 | release: {{ .Release.Name }} 10 | name: {{ template "oauth2-proxy.fullname" . }}-google 11 | type: Opaque 12 | data: 13 | service-account.json: {{ .serviceAccountJson }} 14 | {{- end -}} 15 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $serviceName := include "oauth2-proxy.fullname" . -}} 3 | {{- $servicePort := .Values.service.port -}} 4 | {{- $ingressPath := .Values.ingress.path -}} 5 | {{- $extraPaths := .Values.ingress.extraPaths -}} 6 | {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}} 7 | apiVersion: networking.k8s.io/v1beta1 8 | {{- else -}} 9 | apiVersion: extensions/v1beta1 10 | {{- end }} 11 | kind: Ingress 12 | metadata: 13 | labels: 14 | app: {{ template "oauth2-proxy.name" . }} 15 | chart: {{ template "oauth2-proxy.chart" . }} 16 | heritage: {{ .Release.Service }} 17 | release: {{ .Release.Name }} 18 | name: {{ template "oauth2-proxy.fullname" . }} 19 | {{- with .Values.ingress.annotations }} 20 | annotations: 21 | {{ toYaml . | indent 4 }} 22 | {{- end }} 23 | spec: 24 | rules: 25 | {{- range $host := .Values.ingress.hosts }} 26 | - host: {{ $host | quote }} 27 | http: 28 | paths: 29 | {{ if $extraPaths }} 30 | {{ toYaml $extraPaths | indent 10 }} 31 | {{- end }} 32 | - path: {{ $ingressPath }} 33 | backend: 34 | serviceName: {{ $serviceName }} 35 | servicePort: {{ $servicePort }} 36 | {{- end -}} 37 | {{- if .Values.ingress.tls }} 38 | tls: 39 | {{ toYaml .Values.ingress.tls | indent 4 }} 40 | {{- end -}} 41 | {{- end -}} 42 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/templates/poddisruptionbudget.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.podDisruptionBudget.enabled (gt (.Values.replicaCount | int) 1) }} 2 | apiVersion: policy/v1beta1 3 | kind: PodDisruptionBudget 4 | metadata: 5 | labels: 6 | app: {{ template "oauth2-proxy.name" . }} 7 | chart: {{ template "oauth2-proxy.chart" . }} 8 | heritage: {{ .Release.Service }} 9 | release: {{ .Release.Name }} 10 | name: {{ template "oauth2-proxy.fullname" . }} 11 | spec: 12 | selector: 13 | matchLabels: 14 | app: {{ template "oauth2-proxy.name" . }} 15 | release: {{ .Release.Name }} 16 | minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} 17 | {{- end }} 18 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if and (not .Values.config.existingSecret) (.Values.proxyVarsAsSecrets) }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | labels: 6 | app: {{ template "oauth2-proxy.name" . }} 7 | chart: {{ template "oauth2-proxy.chart" . }} 8 | heritage: {{ .Release.Service }} 9 | release: {{ .Release.Name }} 10 | name: {{ template "oauth2-proxy.fullname" . }} 11 | type: Opaque 12 | data: 13 | cookie-secret: {{ .Values.config.cookieSecret | b64enc | quote }} 14 | client-secret: {{ .Values.config.clientSecret | b64enc | quote }} 15 | client-id: {{ .Values.config.clientID | b64enc | quote }} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app: {{ template "oauth2-proxy.name" . }} 6 | chart: {{ template "oauth2-proxy.chart" . }} 7 | release: {{ .Release.Name }} 8 | heritage: {{ .Release.Service }} 9 | name: {{ template "oauth2-proxy.fullname" . }} 10 | {{- if .Values.service.annotations }} 11 | annotations: 12 | {{ toYaml .Values.service.annotations | indent 4 }} 13 | {{- end }} 14 | spec: 15 | {{- if (or (eq .Values.service.type "ClusterIP") (empty .Values.service.type)) }} 16 | type: ClusterIP 17 | {{- if .Values.service.clusterIP }} 18 | clusterIP: {{ .Values.service.clusterIP }} 19 | {{end}} 20 | {{- else if eq .Values.service.type "LoadBalancer" }} 21 | type: {{ .Values.service.type }} 22 | {{- if .Values.service.loadBalancerIP }} 23 | loadBalancerIP: {{ .Values.service.loadBalancerIP }} 24 | {{- end }} 25 | {{- if .Values.service.loadBalancerSourceRanges }} 26 | loadBalancerSourceRanges: 27 | {{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} 28 | {{- end -}} 29 | {{- else }} 30 | type: {{ .Values.service.type }} 31 | {{- end }} 32 | ports: 33 | - port: {{ .Values.service.port }} 34 | targetPort: {{ .Values.httpScheme }} 35 | protocol: TCP 36 | name: {{ .Values.httpScheme }} 37 | selector: 38 | app: {{ template "oauth2-proxy.name" . }} 39 | release: {{ .Release.Name }} 40 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if or .Values.serviceAccount.enabled -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | {{- with .Values.serviceAccount.annotations }} 6 | annotations: 7 | {{- toYaml . | nindent 4 }} 8 | {{- end }} 9 | labels: 10 | app: {{ template "oauth2-proxy.name" . }} 11 | chart: {{ template "oauth2-proxy.chart" . }} 12 | release: {{ .Release.Name }} 13 | heritage: {{ .Release.Service }} 14 | name: {{ template "oauth2-proxy.fullname" . }} 15 | {{- end -}} 16 | -------------------------------------------------------------------------------- /charts/oauth2-proxy/values.yaml: -------------------------------------------------------------------------------- 1 | # Oauth client configuration specifics 2 | config: 3 | # OAuth client ID 4 | clientID: "XXXXXXX" 5 | # OAuth client secret 6 | clientSecret: "XXXXXXXX" 7 | # Create a new secret with the following command 8 | # openssl rand -base64 32 | head -c 32 | base64 9 | # Use an existing secret for OAuth2 credentials (see secret.yaml for required fields) 10 | # Example: 11 | # existingSecret: secret 12 | cookieSecret: "XXXXXXXXXX" 13 | google: {} 14 | # adminEmail: xxxx 15 | # serviceAccountJson: xxxx 16 | # Alternatively, use an existing secret (see google-secret.yaml for required fields) 17 | # Example: 18 | # existingSecret: google-secret 19 | # Default configuration, to be overridden 20 | configFile: |- 21 | email_domains = [ "*" ] 22 | upstreams = [ "file:///dev/null" ] 23 | # Custom configuration file: oauth2_proxy.cfg 24 | # configFile: |- 25 | # pass_basic_auth = false 26 | # pass_access_token = true 27 | # Use an existing config map (see configmap.yaml for required fields) 28 | # Example: 29 | # existingConfig: config 30 | 31 | image: 32 | repository: "quay.io/pusher/oauth2_proxy" 33 | tag: "v5.1.0" 34 | pullPolicy: "IfNotPresent" 35 | 36 | # Optionally specify an array of imagePullSecrets. 37 | # Secrets must be manually created in the namespace. 38 | # ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod 39 | # imagePullSecrets: 40 | # - name: myRegistryKeySecretName 41 | 42 | extraArgs: {} 43 | extraEnv: [] 44 | 45 | # To authorize individual email addresses 46 | # That is part of extraArgs but since this needs special treatment we need to do a separate section 47 | authenticatedEmailsFile: 48 | enabled: false 49 | # template is the name of the configmap what contains the email user list but has been configured without this chart. 50 | # It's a simpler way to maintain only one configmap (user list) instead changing it for each oauth2-proxy service. 51 | # Be aware the value name in the extern config map in data needs to be named to "restricted_user_access". 52 | template: "" 53 | # One email per line 54 | # example: 55 | # restricted_access: |- 56 | # name1@domain 57 | # name2@domain 58 | # If you override the config with restricted_access it will configure a user list within this chart what takes care of the 59 | # config map resource. 60 | restricted_access: "" 61 | 62 | service: 63 | type: ClusterIP 64 | # when service.type is ClusterIP ... 65 | # clusterIP: 192.0.2.20 66 | # when service.type is LoadBalancer ... 67 | # loadBalancerIP: 198.51.100.40 68 | # loadBalancerSourceRanges: 203.0.113.0/24 69 | port: 80 70 | annotations: {} 71 | # foo.io/bar: "true" 72 | 73 | ## Create or use ServiceAccount 74 | serviceAccount: 75 | ## Specifies whether a ServiceAccount should be created 76 | enabled: true 77 | ## The name of the ServiceAccount to use. 78 | ## If not set and create is true, a name is generated using the fullname template 79 | name: 80 | annotations: {} 81 | 82 | ingress: 83 | enabled: false 84 | path: / 85 | # Used to create an Ingress record. 86 | # hosts: 87 | # - chart-example.local 88 | # Extra paths to prepend to every host configuration. This is useful when working with annotation based services. 89 | # extraPaths: 90 | # - path: /* 91 | # backend: 92 | # serviceName: ssl-redirect 93 | # servicePort: use-annotation 94 | # annotations: 95 | # kubernetes.io/ingress.class: nginx 96 | # kubernetes.io/tls-acme: "true" 97 | # tls: 98 | # Secrets must be manually created in the namespace. 99 | # - secretName: chart-example-tls 100 | # hosts: 101 | # - chart-example.local 102 | 103 | resources: {} 104 | # limits: 105 | # cpu: 100m 106 | # memory: 300Mi 107 | # requests: 108 | # cpu: 100m 109 | # memory: 300Mi 110 | 111 | extraVolumes: [] 112 | # - name: ca-bundle-cert 113 | # secret: 114 | # secretName: 115 | 116 | extraVolumeMounts: [] 117 | # - mountPath: /etc/ssl/certs/ 118 | # name: ca-bundle-cert 119 | 120 | priorityClassName: "" 121 | 122 | # Affinity for pod assignment 123 | # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity 124 | # affinity: {} 125 | 126 | # Tolerations for pod assignment 127 | # Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ 128 | tolerations: [] 129 | 130 | # Node labels for pod assignment 131 | # Ref: https://kubernetes.io/docs/user-guide/node-selection/ 132 | nodeSelector: {} 133 | 134 | # Whether to use secrets instead of environment values for setting up OAUTH2_PROXY variables 135 | proxyVarsAsSecrets: true 136 | 137 | # Configure Kubernetes liveness and readiness probes. 138 | # Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ 139 | # Disable both when deploying with Istio 1.0 mTLS. https://istio.io/help/faq/security/#k8s-health-checks 140 | livenessProbe: 141 | enabled: true 142 | initialDelaySeconds: 0 143 | timeoutSeconds: 1 144 | 145 | readinessProbe: 146 | enabled: true 147 | initialDelaySeconds: 0 148 | timeoutSeconds: 1 149 | periodSeconds: 10 150 | successThreshold: 1 151 | 152 | # Configure Kubernetes security context for container 153 | # Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ 154 | securityContext: 155 | enabled: false 156 | runAsNonRoot: true 157 | 158 | podAnnotations: {} 159 | podLabels: {} 160 | replicaCount: 1 161 | 162 | ## PodDisruptionBudget settings 163 | ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ 164 | podDisruptionBudget: 165 | enabled: true 166 | minAvailable: 1 167 | 168 | # Configure Kubernetes security context for pod 169 | # Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ 170 | podSecurityContext: {} 171 | 172 | # whether to use http or https 173 | httpScheme: http 174 | 175 | # Additionally authenticate against a htpasswd file. Entries must be created with "htpasswd -s" for SHA encryption. 176 | # Alternatively supply an existing secret which contains the required information. 177 | htpasswdFile: 178 | enabled: false 179 | existingSecret: "" 180 | entries: {} 181 | # One row for each user 182 | # example: 183 | # entries: 184 | # - testuser:{SHA}EWhzdhgoYJWy0z2gyzhRYlN9DSiv 185 | -------------------------------------------------------------------------------- /charts/openldap/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /charts/openldap/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | name: openldap 3 | home: https://www.openldap.org 4 | version: 1.2.7 5 | appVersion: 2.4.48 6 | description: DEPRECATED - Community developed LDAP software 7 | icon: http://www.openldap.org/images/headers/LDAPworm.gif 8 | keywords: 9 | - ldap 10 | - openldap 11 | sources: 12 | - https://github.com/kubernetes/charts 13 | deprecated: false 14 | engine: gotpl 15 | -------------------------------------------------------------------------------- /charts/openldap/README.md: -------------------------------------------------------------------------------- 1 | # ⚠️ Repo Archive Notice 2 | 3 | As of Nov 13, 2020, charts in this repo will no longer be updated. 4 | For more information, see the Helm Charts [Deprecation and Archive Notice](https://github.com/helm/charts#%EF%B8%8F-deprecation-and-archive-notice), and [Update](https://helm.sh/blog/charts-repo-deprecation/). 5 | 6 | # OpenLDAP Helm Chart 7 | 8 | ## DEPRECATION NOTICE 9 | 10 | This chart is deprecated and no longer supported. 11 | 12 | ## Prerequisites Details 13 | * Kubernetes 1.8+ 14 | * PV support on the underlying infrastructure 15 | 16 | ## Chart Details 17 | This chart will do the following: 18 | 19 | * Instantiate an instance of OpenLDAP server 20 | 21 | ## Installing the Chart 22 | 23 | To install the chart with the release name `my-release`: 24 | 25 | ```bash 26 | $ helm install --name my-release stable/openldap 27 | ``` 28 | 29 | ## Configuration 30 | 31 | We use the docker images provided by https://github.com/osixia/docker-openldap. The docker image is highly configurable and well documented. Please consult to documentation for the docker image for more information. 32 | 33 | The following table lists the configurable parameters of the openldap chart and their default values. 34 | 35 | | Parameter | Description | Default | 36 | | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | 37 | | `replicaCount` | Number of replicas | `1` | 38 | | `strategy` | Deployment strategy | `{}` | 39 | | `image.repository` | Container image repository | `osixia/openldap` | 40 | | `image.tag` | Container image tag | `1.1.10` | 41 | | `image.pullPolicy` | Container pull policy | `IfNotPresent` | 42 | | `extraLabels` | Labels to add to the Resources | `{}` | 43 | | `podAnnotations` | Annotations to add to the pod | `{}` | 44 | | `existingSecret` | Use an existing secret for admin and config user passwords | `""` | 45 | | `service.annotations` | Annotations to add to the service | `{}` | 46 | | `service.clusterIP` | IP address to assign to the service | `nil` | 47 | | `service.externalIPs` | Service external IP addresses | `[]` | 48 | | `service.ldapPort` | External service port for LDAP | `389` | 49 | | `service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `""` | 50 | | `service.loadBalancerSourceRanges` | List of IP CIDRs allowed access to load balancer (if supported) | `[]` | 51 | | `service.sslLdapPort` | External service port for SSL+LDAP | `636` | 52 | | `service.type` | Service type | `ClusterIP` | 53 | | `env` | List of key value pairs as env variables to be sent to the docker image. See https://github.com/osixia/docker-openldap for available ones | `[see values.yaml]` | 54 | | `logLevel` | Set the container log level. Valid values: `none`, `error`, `warning`, `info`, `debug`, `trace` | `info` | 55 | | `tls.enabled` | Set to enable TLS/LDAPS - should also set `tls.secret` | `false` | 56 | | `tls.secret` | Secret containing TLS cert and key (eg, generated via cert-manager) | `""` | 57 | | `tls.CA.enabled` | Set to enable custom CA crt file - should also set `tls.CA.secret` | `false` | 58 | | `tls.CA.secret` | Secret containing CA certificate (ca.crt) | `""` | 59 | | `adminPassword` | Password for admin user. Unset to auto-generate the password | None | 60 | | `configPassword` | Password for config user. Unset to auto-generate the password | None | 61 | | `customLdifFiles` | Custom ldif files to seed the LDAP server. List of filename -> data pairs | None | 62 | | `persistence.enabled` | Whether to use PersistentVolumes or not | `false` | 63 | | `persistence.storageClass` | Storage class for PersistentVolumes. | `` | 64 | | `persistence.accessMode` | Access mode for PersistentVolumes | `ReadWriteOnce` | 65 | | `persistence.size` | PersistentVolumeClaim storage size | `8Gi` | 66 | | `persistence.existingClaim` | An Existing PVC name for openLDAPA volume | None | 67 | | `resources` | Container resource requests and limits in yaml | `{}` | 68 | | `initResources` | initContainer resource requests and limits in yaml | `{}` | 69 | | `test.enabled` | Conditionally provision test resources | `false` | 70 | | `test.image.repository` | Test container image requires bats framework | `dduportal/bats` | 71 | | `test.image.tag` | Test container tag | `0.4.0` | 72 | 73 | 74 | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. 75 | 76 | Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, 77 | 78 | ```bash 79 | $ helm install --name my-release -f values.yaml stable/openldap 80 | ``` 81 | 82 | > **Tip**: You can use the default [values.yaml](values.yaml) 83 | 84 | 85 | ## Cleanup orphaned Persistent Volumes 86 | 87 | Deleting the Deployment will not delete associated Persistent Volumes if persistence is enabled. 88 | 89 | Do the following after deleting the chart release to clean up orphaned Persistent Volumes. 90 | 91 | ```bash 92 | $ kubectl delete pvc -l release=${RELEASE-NAME} 93 | ``` 94 | 95 | ## Custom Secret 96 | 97 | `existingSecret` can be used to override the default secret.yaml provided 98 | 99 | ## Testing 100 | 101 | Helm tests are included and they confirm connection to slapd. 102 | 103 | ```bash 104 | helm install . --set test.enabled=true 105 | helm test 106 | RUNNING: foolish-mouse-openldap-service-test-akmms 107 | PASSED: foolish-mouse-openldap-service-test-akmms 108 | ``` 109 | 110 | It will confirm that we can do an ldapsearch with the default credentials 111 | -------------------------------------------------------------------------------- /charts/openldap/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | OpenLDAP has been installed. You can access the server from within the k8s cluster using: 2 | 3 | {{ template "openldap.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.ldapPort }} 4 | 5 | 6 | You can access the LDAP adminPassword and configPassword using: 7 | 8 | kubectl get secret --namespace {{ .Release.Namespace }} {{ template "openldap.secretName" . }} -o jsonpath="{.data.LDAP_ADMIN_PASSWORD}" | base64 --decode; echo 9 | kubectl get secret --namespace {{ .Release.Namespace }} {{ template "openldap.secretName" . }} -o jsonpath="{.data.LDAP_CONFIG_PASSWORD}" | base64 --decode; echo 10 | 11 | 12 | You can access the LDAP service, from within the cluster (or with kubectl port-forward) with a command like (replace password and domain): 13 | ldapsearch -x -H ldap://{{ template "openldap.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.ldapPort }} -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w $LDAP_ADMIN_PASSWORD 14 | 15 | 16 | Test server health using Helm test: 17 | helm test {{ .Release.Name }} 18 | 19 | 20 | You can also consider installing the helm chart for phpldapadmin to manage this instance of OpenLDAP, or install Apache Directory Studio, and connect using kubectl port-forward. 21 | -------------------------------------------------------------------------------- /charts/openldap/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "openldap.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "openldap.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "openldap.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | 35 | {{/* 36 | Generate chart secret name 37 | */}} 38 | {{- define "openldap.secretName" -}} 39 | {{ default (include "openldap.fullname" .) .Values.existingSecret }} 40 | {{- end -}} 41 | -------------------------------------------------------------------------------- /charts/openldap/templates/configmap-customldif.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # A ConfigMap spec for openldap slapd that map directly to files under 3 | # /container/service/slapd/assets/config/bootstrap/ldif/custom 4 | # 5 | {{- if .Values.customLdifFiles }} 6 | apiVersion: v1 7 | kind: ConfigMap 8 | metadata: 9 | name: {{ template "openldap.fullname" . }}-customldif 10 | labels: 11 | app: {{ template "openldap.name" . }} 12 | chart: {{ template "openldap.chart" . }} 13 | release: {{ .Release.Name }} 14 | heritage: {{ .Release.Service }} 15 | {{- if .Values.extraLabels }} 16 | {{ toYaml .Values.extraLabels | indent 4 }} 17 | {{- end }} 18 | data: 19 | {{- range $key, $val := .Values.customLdifFiles }} 20 | {{ $key }}: |- 21 | {{ $val | indent 4}} 22 | {{- end }} 23 | {{- end }} 24 | -------------------------------------------------------------------------------- /charts/openldap/templates/configmap-env.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # A ConfigMap spec for openldap slapd that map directly to env variables in the Pod. 3 | # List of environment variables supported is from the docker image: 4 | # https://github.com/osixia/docker-openldap#beginner-guide 5 | # Note that passwords are defined as secrets 6 | # 7 | apiVersion: v1 8 | kind: ConfigMap 9 | metadata: 10 | name: {{ template "openldap.fullname" . }}-env 11 | labels: 12 | app: {{ template "openldap.name" . }} 13 | chart: {{ template "openldap.chart" . }} 14 | release: {{ .Release.Name }} 15 | heritage: {{ .Release.Service }} 16 | {{- if .Values.extraLabels }} 17 | {{ toYaml .Values.extraLabels | indent 4 }} 18 | {{- end }} 19 | data: 20 | {{ toYaml .Values.env | indent 2 }} 21 | -------------------------------------------------------------------------------- /charts/openldap/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "openldap.fullname" . }} 5 | labels: 6 | app: {{ template "openldap.name" . }} 7 | chart: {{ template "openldap.chart" . }} 8 | release: {{ .Release.Name }} 9 | heritage: {{ .Release.Service }} 10 | {{- if .Values.extraLabels }} 11 | {{ toYaml .Values.extraLabels | indent 4 }} 12 | {{- end }} 13 | spec: 14 | replicas: {{ .Values.replicaCount }} 15 | {{- if .Values.strategy }} 16 | strategy: 17 | {{ toYaml .Values.strategy | indent 4 }} 18 | {{- end }} 19 | selector: 20 | matchLabels: 21 | app: {{ template "openldap.name" . }} 22 | release: {{ .Release.Name }} 23 | template: 24 | metadata: 25 | annotations: 26 | checksum/configmap-env: {{ include (print $.Template.BasePath "/configmap-env.yaml") . | sha256sum }} 27 | {{- if .Values.customLdifFiles}} 28 | checksum/configmap-customldif: {{ include (print $.Template.BasePath "/configmap-customldif.yaml") . | sha256sum }} 29 | {{- end }} 30 | {{- if .Values.podAnnotations}} 31 | {{ toYaml .Values.podAnnotations | indent 8}} 32 | {{- end }} 33 | labels: 34 | app: {{ template "openldap.name" . }} 35 | release: {{ .Release.Name }} 36 | spec: 37 | {{- if or .Values.customLdifFiles .Values.tls.enabled }} 38 | initContainers: 39 | {{- end }} 40 | {{- if .Values.customLdifFiles }} 41 | - name: {{ .Chart.Name }}-init-ldif 42 | image: busybox 43 | command: ['sh', '-c', 'cp /customldif/* /ldifworkingdir'] 44 | imagePullPolicy: {{ .Values.image.pullPolicy }} 45 | volumeMounts: 46 | - name: customldif 47 | mountPath: /customldif 48 | - name: ldifworkingdir 49 | mountPath: /ldifworkingdir 50 | resources: 51 | {{ toYaml .Values.initResources | indent 10 }} 52 | {{- end }} 53 | {{- if .Values.tls.enabled }} 54 | - name: {{ .Chart.Name }}-init-tls 55 | image: busybox 56 | command: ['sh', '-c', 'cp /tls/* /certs'] 57 | imagePullPolicy: {{ .Values.image.pullPolicy }} 58 | volumeMounts: 59 | - name: tls 60 | mountPath: /tls 61 | - name: certs 62 | mountPath: /certs 63 | resources: 64 | {{ toYaml .Values.initResources | indent 10 }} 65 | {{- if .Values.tls.CA.enabled }} 66 | - name: {{ .Chart.Name }}-init-catls 67 | image: busybox 68 | command: ['sh', '-c', 'cp /catls/ca.crt /certs'] 69 | volumeMounts: 70 | - name: catls 71 | mountPath: /catls 72 | - name: certs 73 | mountPath: /certs 74 | resources: 75 | {{ toYaml .Values.initResources | indent 10 }} 76 | {{- end }} 77 | {{- end }} 78 | containers: 79 | - name: {{ .Chart.Name }} 80 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 81 | imagePullPolicy: {{ .Values.image.pullPolicy }} 82 | args: 83 | - -l 84 | - {{ .Values.logLevel }} 85 | {{- if .Values.customLdifFiles }} 86 | - --copy-service 87 | {{- end }} 88 | ports: 89 | - name: ldap-port 90 | containerPort: 389 91 | - name: ssl-ldap-port 92 | containerPort: 636 93 | envFrom: 94 | - configMapRef: 95 | name: {{ template "openldap.fullname" . }}-env 96 | - secretRef: 97 | name: {{ template "openldap.secretName" . }} 98 | volumeMounts: 99 | - name: data 100 | mountPath: /var/lib/ldap 101 | subPath: data 102 | - name: data 103 | mountPath: /etc/ldap/slapd.d 104 | subPath: config-data 105 | {{- if .Values.customLdifFiles }} 106 | - name: ldifworkingdir 107 | mountPath: /container/service/slapd/assets/config/bootstrap/ldif/custom 108 | {{- end }} 109 | {{- if .Values.tls.enabled }} 110 | - name: certs 111 | mountPath: /container/service/slapd/assets/certs 112 | {{- end }} 113 | env: 114 | {{- if .Values.tls.enabled }} 115 | - name: LDAP_TLS_CRT_FILENAME 116 | value: tls.crt 117 | - name: LDAP_TLS_KEY_FILENAME 118 | value: tls.key 119 | {{- if .Values.tls.CA.enabled }} 120 | - name: LDAP_TLS_CA_CRT_FILENAME 121 | value: ca.crt 122 | {{- end }} 123 | {{- end }} 124 | livenessProbe: 125 | tcpSocket: 126 | port: ldap-port 127 | initialDelaySeconds: 20 128 | periodSeconds: 10 129 | failureThreshold: 10 130 | readinessProbe: 131 | tcpSocket: 132 | port: ldap-port 133 | initialDelaySeconds: 20 134 | periodSeconds: 10 135 | failureThreshold: 10 136 | resources: 137 | {{ toYaml .Values.resources | indent 12 }} 138 | {{- with .Values.nodeSelector }} 139 | nodeSelector: 140 | {{ toYaml . | indent 8 }} 141 | {{- end }} 142 | {{- with .Values.affinity }} 143 | affinity: 144 | {{ toYaml . | indent 8 }} 145 | {{- end }} 146 | {{- with .Values.tolerations }} 147 | tolerations: 148 | {{ toYaml . | indent 8 }} 149 | {{- end }} 150 | volumes: 151 | {{- if .Values.customLdifFiles }} 152 | - name: customldif 153 | configMap: 154 | name: {{ template "openldap.fullname" . }}-customldif 155 | - name: ldifworkingdir 156 | emptyDir: {} 157 | {{- end }} 158 | {{- if .Values.tls.enabled }} 159 | - name: tls 160 | secret: 161 | secretName: {{ .Values.tls.secret }} 162 | {{- if .Values.tls.CA.enabled }} 163 | - name: catls 164 | secret: 165 | secretName: {{ .Values.tls.CA.secret }} 166 | {{- end }} 167 | {{- end }} 168 | - name: certs 169 | emptyDir: 170 | medium: Memory 171 | - name: data 172 | {{- if .Values.persistence.enabled }} 173 | persistentVolumeClaim: 174 | claimName: {{ .Values.persistence.existingClaim | default (include "openldap.fullname" .) }} 175 | {{- else }} 176 | emptyDir: {} 177 | {{- end -}} 178 | -------------------------------------------------------------------------------- /charts/openldap/templates/pvc.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} 2 | kind: PersistentVolumeClaim 3 | apiVersion: v1 4 | metadata: 5 | name: {{ template "openldap.fullname" . }} 6 | labels: 7 | app: {{ template "openldap.name" . }} 8 | chart: {{ template "openldap.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | {{- if .Values.extraLabels }} 12 | {{ toYaml .Values.extraLabels | indent 4 }} 13 | {{- end }} 14 | spec: 15 | accessModes: 16 | - {{ .Values.persistence.accessMode | quote }} 17 | resources: 18 | requests: 19 | storage: {{ .Values.persistence.size | quote }} 20 | {{- if .Values.persistence.storageClass }} 21 | {{- if (eq "-" .Values.persistence.storageClass) }} 22 | storageClassName: "" 23 | {{- else }} 24 | storageClassName: "{{ .Values.persistence.storageClass }}" 25 | {{- end }} 26 | {{- end }} 27 | {{- end }} 28 | -------------------------------------------------------------------------------- /charts/openldap/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | {{ if not .Values.existingSecret }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ template "openldap.fullname" . }} 6 | labels: 7 | app: {{ template "openldap.name" . }} 8 | chart: {{ template "openldap.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | {{- if .Values.extraLabels }} 12 | {{ toYaml .Values.extraLabels | indent 4 }} 13 | {{- end }} 14 | type: Opaque 15 | data: 16 | LDAP_ADMIN_PASSWORD: {{ .Values.adminPassword | default (randAlphaNum 32) | b64enc | quote }} 17 | LDAP_CONFIG_PASSWORD: {{ .Values.configPassword | default (randAlphaNum 32) | b64enc | quote }} 18 | {{ end }} 19 | -------------------------------------------------------------------------------- /charts/openldap/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | {{- if .Values.service.annotations }} 5 | annotations: 6 | {{ toYaml .Values.service.annotations | indent 4 }} 7 | {{- end }} 8 | name: {{ template "openldap.fullname" . }} 9 | labels: 10 | app: {{ template "openldap.name" . }} 11 | chart: {{ template "openldap.chart" . }} 12 | release: {{ .Release.Name }} 13 | heritage: {{ .Release.Service }} 14 | {{- if .Values.extraLabels }} 15 | {{ toYaml .Values.extraLabels | indent 4 }} 16 | {{- end }} 17 | spec: 18 | {{- with .Values.service.clusterIP }} 19 | clusterIP: {{ . | quote }} 20 | {{- end }} 21 | {{- if .Values.service.externalIPs }} 22 | externalIPs: 23 | {{ toYaml .Values.service.externalIPs | indent 4 }} 24 | {{- end }} 25 | {{- if .Values.service.loadBalancerIP }} 26 | loadBalancerIP: {{ .Values.service.loadBalancerIP | quote }} 27 | {{- end }} 28 | {{- if .Values.service.loadBalancerSourceRanges }} 29 | loadBalancerSourceRanges: 30 | {{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} 31 | {{- end }} 32 | ports: 33 | - name: ldap-port 34 | protocol: TCP 35 | port: {{ .Values.service.ldapPort }} 36 | targetPort: ldap-port 37 | - name: ssl-ldap-port 38 | protocol: TCP 39 | port: {{ .Values.service.sslLdapPort }} 40 | targetPort: ssl-ldap-port 41 | selector: 42 | app: {{ template "openldap.name" . }} 43 | release: {{ .Release.Name }} 44 | type: {{ .Values.service.type }} 45 | -------------------------------------------------------------------------------- /charts/openldap/templates/tests/openldap-test-runner.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.test.enabled -}} 2 | apiVersion: v1 3 | kind: Pod 4 | metadata: 5 | name: "{{ template "openldap.fullname" . }}-test-{{ randAlphaNum 5 | lower }}" 6 | labels: 7 | app: {{ template "openldap.name" . }} 8 | chart: {{ template "openldap.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | {{- if .Values.extraLabels }} 12 | {{ toYaml .Values.extraLabels | indent 4 }} 13 | {{- end }} 14 | annotations: 15 | "helm.sh/hook": test-success 16 | spec: 17 | initContainers: 18 | - name: test-framework 19 | image: {{ .Values.test.image.repository }}:{{ .Values.test.image.tag }} 20 | command: 21 | - "bash" 22 | - "-c" 23 | - | 24 | set -ex 25 | # copy bats to tools dir 26 | cp -R /usr/local/libexec/ /tools/bats/ 27 | volumeMounts: 28 | - mountPath: /tools 29 | name: tools 30 | containers: 31 | - name: {{ .Release.Name }}-test 32 | image: {{ .Values.test.image.repository }}:{{ .Values.test.image.tag }} 33 | envFrom: 34 | - secretRef: 35 | name: {{ template "openldap.secretName" . }} 36 | command: ["/tools/bats/bats", "-t", "/tests/run.sh"] 37 | volumeMounts: 38 | - mountPath: /tests 39 | name: tests 40 | readOnly: true 41 | - mountPath: /tools 42 | name: tools 43 | volumes: 44 | - name: tests 45 | configMap: 46 | name: {{ template "openldap.fullname" . }}-tests 47 | - name: tools 48 | emptyDir: {} 49 | restartPolicy: Never 50 | {{- end -}} 51 | -------------------------------------------------------------------------------- /charts/openldap/templates/tests/openldap-tests.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.test.enabled -}} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ template "openldap.fullname" . }}-tests 6 | labels: 7 | app: {{ template "openldap.name" . }} 8 | chart: {{ template "openldap.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | {{- if .Values.extraLabels }} 12 | {{ toYaml .Values.extraLabels | indent 4 }} 13 | {{- end }} 14 | data: 15 | run.sh: |- 16 | @test "Testing connecting to slapd server" { 17 | # Ideally, this should be in the docker image, but there is not a generic image we can use 18 | # with bats and ldap-utils installed. It is not worth for now to push an image for this. 19 | apt-get update && apt-get install -y ldap-utils 20 | ldapsearch -x -H ldap://{{ template "openldap.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.ldapPort }} -b "dc=example,dc=org" -D "cn=admin,dc=example,dc=org" -w $LDAP_ADMIN_PASSWORD 21 | } 22 | {{- end -}} 23 | -------------------------------------------------------------------------------- /charts/openldap/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for openldap. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | # Define deployment strategy - IMPORTANT: use rollingUpdate: null when use Recreate strategy. 8 | # It prevents from merging with existing map keys which are forbidden. 9 | strategy: {} 10 | # type: RollingUpdate 11 | # rollingUpdate: 12 | # maxSurge: 1 13 | # maxUnavailable: 0 14 | # 15 | # or 16 | # 17 | # type: Recreate 18 | # rollingUpdate: null 19 | image: 20 | # From repository https://github.com/osixia/docker-openldap 21 | repository: osixia/openldap 22 | tag: 1.2.4 23 | pullPolicy: IfNotPresent 24 | 25 | # Spcifies an existing secret to be used for admin and config user passwords 26 | existingSecret: "" 27 | 28 | # settings for enabling TLS 29 | tls: 30 | enabled: false 31 | secret: "" # The name of a kubernetes.io/tls type secret to use for TLS 32 | CA: 33 | enabled: false 34 | secret: "" # The name of a generic secret to use for custom CA certificate (ca.crt) 35 | ## Add additional labels to all resources 36 | extraLabels: {} 37 | ## Add additional annotations to pods 38 | podAnnotations: {} 39 | service: 40 | annotations: {} 41 | 42 | ldapPort: 389 43 | sslLdapPort: 636 # Only used if tls.enabled is true 44 | ## List of IP addresses at which the service is available 45 | ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips 46 | ## 47 | externalIPs: [] 48 | 49 | loadBalancerIP: "" 50 | loadBalancerSourceRanges: [] 51 | type: ClusterIP 52 | 53 | # Default configuration for openldap as environment variables. These get injected directly in the container. 54 | # Use the env variables from https://github.com/osixia/docker-openldap#beginner-guide 55 | env: 56 | LDAP_ORGANISATION: "Example Inc." 57 | LDAP_DOMAIN: "example.org" 58 | LDAP_BACKEND: "hdb" 59 | LDAP_TLS: "true" 60 | LDAP_TLS_ENFORCE: "false" 61 | LDAP_REMOVE_CONFIG_AFTER_SETUP: "true" 62 | 63 | # Default Passwords to use, stored as a secret. If unset, passwords are auto-generated. 64 | # You can override these at install time with 65 | # helm install openldap --set openldap.adminPassword=,openldap.configPassword= 66 | # adminPassword: admin 67 | # configPassword: config 68 | 69 | # Custom openldap configuration files used to override default settings 70 | # customLdifFiles: 71 | # 01-default-users.ldif: |- 72 | # Predefine users here 73 | 74 | ## Persist data to a persistent volume 75 | persistence: 76 | enabled: false 77 | ## database data Persistent Volume Storage Class 78 | ## If defined, storageClassName: 79 | ## If set to "-", storageClassName: "", which disables dynamic provisioning 80 | ## If undefined (the default) or set to null, no storageClassName spec is 81 | ## set, choosing the default provisioner. (gp2 on AWS, standard on 82 | ## GKE, AWS & OpenStack) 83 | ## 84 | # storageClass: "-" 85 | accessMode: ReadWriteOnce 86 | size: 8Gi 87 | # existingClaim: "" 88 | 89 | resources: {} 90 | # requests: 91 | # cpu: "100m" 92 | # memory: "256Mi" 93 | # limits: 94 | # cpu: "500m" 95 | # memory: "512Mi" 96 | 97 | initResources: {} 98 | # requests: 99 | # cpu: "100m" 100 | # memory: "128Mi" 101 | # limits: 102 | # cpu: "100m" 103 | # memory: "128Mi" 104 | 105 | nodeSelector: {} 106 | 107 | tolerations: [] 108 | 109 | affinity: {} 110 | 111 | ## test container details 112 | test: 113 | enabled: false 114 | image: 115 | repository: dduportal/bats 116 | tag: 0.4.0 117 | 118 | # Set the container log level 119 | # Valid log levels: none, error, warning, info (default), debug, trace 120 | logLevel: info 121 | -------------------------------------------------------------------------------- /docker-registry/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TalkingQuickly/kubernetes-sso-guide/4c5f976e4d72735809a5c86882ac2d0f648d0133/docker-registry/.DS_Store -------------------------------------------------------------------------------- /docker-registry/values-docker-registry.yml: -------------------------------------------------------------------------------- 1 | configData: 2 | auth: 3 | token: 4 | realm: https://sso.ssotest.staging.talkingquickly.co.uk/auth/realms/master/protocol/docker-v2/auth 5 | service: simple-docker-registry 6 | issuer: https://sso.ssotest.staging.talkingquickly.co.uk/auth/realms/master 7 | rootcertbundle: /root-cert-bundle/localhost_trust_chain.pem 8 | ingress: 9 | enabled: true 10 | annotations: 11 | cert-manager.io/cluster-issuer: letsencrypt-production 12 | nginx.ingress.kubernetes.io/proxy-body-size: "0" 13 | hosts: 14 | - registry-keycloak.ssotest.staging.talkingquickly.co.uk 15 | 16 | tls: 17 | - hosts: 18 | - registry-keycloak.ssotest.staging.talkingquickly.co.uk 19 | secretName: keycloak-registry-tls-secret 20 | 21 | extraVolumes: 22 | - name: docker-registry-auth-token-rootcertbundle 23 | secret: 24 | secretName: docker-registry-auth-token-rootcertbundle 25 | 26 | extraVolumeMounts: 27 | - mountPath: /root-cert-bundle 28 | name: docker-registry-auth-token-rootcertbundle 29 | readOnly: true -------------------------------------------------------------------------------- /gitea/values-gitea.yml: -------------------------------------------------------------------------------- 1 | gitea: 2 | domain: gitea-keycloak.k4stest4.talkingquickly.co.uk 3 | protocol: https 4 | installLock: true 5 | 6 | service: 7 | ssh: 8 | type: NodePort 9 | port: 22 10 | nodePort: 30011 11 | 12 | ingress: 13 | enabled: true 14 | annotations: 15 | cert-manager.io/cluster-issuer: letsencrypt-production 16 | hosts: 17 | - host: gitea-keycloak.k4stest4.talkingquickly.co.uk 18 | paths: ['/'] 19 | tls: 20 | - secretName: gitea-keycloak-https-secret 21 | hosts: 22 | - gitea-keycloak.k4stest4.talkingquickly.co.uk -------------------------------------------------------------------------------- /group-auth/cluster-role-binding.yml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: oidc-admin-group 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: cluster-admin 9 | subjects: 10 | - apiGroup: rbac.authorization.k8s.io 11 | kind: Group 12 | name: oidcgroup:KubernetesAdmins -------------------------------------------------------------------------------- /harbor/values-harbor.yml: -------------------------------------------------------------------------------- 1 | expose: 2 | type: ingress 3 | tls: 4 | certSource: secret 5 | secret: 6 | secretName: harbor-ingress-tls 7 | ingress: 8 | annotations: 9 | cert-manager.io/cluster-issuer: letsencrypt-production 10 | 11 | hosts: 12 | core: core.harbor.ssotest.staging.talkingquickly.co.uk 13 | 14 | harborAdminPassword: 85nsafg87ehfgk0fgsgfg6u 15 | externalURL: https://core.harbor.ssotest.staging.talkingquickly.co.uk 16 | secretKey: "8d10dlskeit8fhtg" 17 | 18 | notary: 19 | enabled: false 20 | 21 | metrics: 22 | enabled: true -------------------------------------------------------------------------------- /jwt-ruby-example/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'jwt' -------------------------------------------------------------------------------- /jwt-ruby-example/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | jwt (2.2.2) 5 | 6 | PLATFORMS 7 | ruby 8 | 9 | DEPENDENCIES 10 | jwt 11 | 12 | BUNDLED WITH 13 | 2.1.4 14 | -------------------------------------------------------------------------------- /jwt-ruby-example/main.rb: -------------------------------------------------------------------------------- 1 | require 'jwt' 2 | 3 | public_key_string = """ 4 | -----BEGIN PUBLIC KEY----- 5 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsewaIX6Xidiyc8OZa6H9 6 | +WNJbpPqHi5xSDSezrL5i6LcELBtrWr890vHCcwqDWcqmWkzvTG2bTMJnuBhL1x+ 7 | DexKn3KMzHxHQczOaeRZJhORsszu/CmslWu7AxcnTe4a9KpRBAGdsfvB4caVWA4o 8 | wawe1SbwOWp8sNWh6h/i4Tv7pVdQoEkb6qBk8YW4vWbdvEMteXcL/qjaPyfsMPVQ 9 | idp0pmEjXonu2cwCzTYUX4ITWuOe1hufTBF/G9XuU6/dCD+Da48/Ad3v2GT3bT7m 10 | Awatb6RVhpUlSELHps/7q4zJVnpTxNsD4nN/QM7X1VO96uJL2C0RtqCiu1huF0ho 11 | 0wIDAQAB 12 | -----END PUBLIC KEY----- 13 | """ 14 | 15 | public_key = OpenSSL::PKey::RSA.new(public_key_string) 16 | 17 | token = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJuXzhLOUo3THlDSzdCaEZYd2pnVDl6WjNUYmNhUXM5TG0wWlhQZzBac01RIn0.eyJleHAiOjE2MTI0OTQ0MzIsImlhdCI6MTYxMjQ5NDM3MiwiYXV0aF90aW1lIjoxNjEyNDkyOTUyLCJqdGkiOiI1NDEyZjY2NC03NjU4LTQwNTQtOTg2ZC01OTE1NjNjZWRmNjYiLCJpc3MiOiJodHRwczovL3Nzby5zc290ZXN0LnN0YWdpbmcudGFsa2luZ3F1aWNrbHkuY28udWsvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjdkN2MyMTgzLTNkOTYtNDk2YS05NTE2LWRkYTc1Mzg4NTRjOSIsInR5cCI6IkJlYXJlciIsImF6cCI6Im9hdXRoMi1wcm94eSIsInNlc3Npb25fc3RhdGUiOiI2MTk2OWQ3Mi0wYTI1LTQyOWYtODQyYS0zZTYwYWE1YWMxY2YiLCJhY3IiOiIwIiwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsIm5hbWUiOiJCZW4gRGl4b24iLCJncm91cHMiOlsiL0RvY2tlclJlZ2lzdHJ5IiwiL0t1YmVybmV0ZXNBZG1pbnMiLCIvQWRtaW5pc3RyYXRvcnMiXSwicHJlZmVycmVkX3VzZXJuYW1lIjoidGFsa2luZ3F1aWNrbHkiLCJnaXZlbl9uYW1lIjoiQmVuIiwiZmFtaWx5X25hbWUiOiJEaXhvbiIsImVtYWlsIjoiYmVuQHRhbGtpbmdxdWlja2x5LmNvLnVrIn0.ZDWzHiui2K44td-DCOdPddsBsNsoONXB2qm6MVoGIj4qOSBEFkVaVRRmRZWHxHRfOaumqY3N9bZphepgAItqc5z1oKkOf0Y6eC7t80jnUPnTbM-ikMwm9qIQjgfreJ00JwgTQFyCcabB7h1eTzMgW6NkVH51yd0Hn9BVmWe3br3ZcAt2x0nez4r7qYtwlFZlxXuJkdRFsJtQeO25-orbTZrjcxHpdwme0yS_g6BF9SYL5trRk0g-x0lopFKC0xyYga6t-HYXEjwdEhvdFzzy11kI4iX_8zAYlkRxmwlEV5_JT9IGt9Ajb5rqNvB26T6loWdbP314v3-0uEpBWKSIAw" 18 | 19 | decoded_token = JWT.decode token, public_key, true, { algorithm: 'RS256' } 20 | 21 | puts decoded_token -------------------------------------------------------------------------------- /keycloak/values-keycloak.yml: -------------------------------------------------------------------------------- 1 | extraEnv: | 2 | - name: KEYCLOAK_LOGLEVEL 3 | value: DEBUG 4 | - name: KEYCLOAK_USER 5 | value: admin 6 | - name: KEYCLOAK_PASSWORD 7 | value: as897gsdfs766dfsgjhsdf 8 | - name: PROXY_ADDRESS_FORWARDING 9 | value: "true" 10 | 11 | args: 12 | - -Dkeycloak.profile.feature.docker=enabled 13 | 14 | ingress: 15 | enabled: true 16 | annotations: 17 | cert-manager.io/cluster-issuer: letsencrypt-production 18 | rules: 19 | - host: sso.ssotest.staging.talkingquickly.co.uk 20 | paths: 21 | - / 22 | 23 | tls: 24 | - hosts: 25 | - sso.ssotest.staging.talkingquickly.co.uk 26 | secretName: keycloak-tld-secret 27 | 28 | postgresql: 29 | enabled: true 30 | postgresqlPassword: asdfaso97sadfjylfasdsf78 -------------------------------------------------------------------------------- /kube-oidc-proxy/values-kube-oidc.yml: -------------------------------------------------------------------------------- 1 | oidc: 2 | clientId: kube-oidc-proxy 3 | issuerUrl: https://sso.ssotest.staging.talkingquickly.co.uk/auth/realms/master 4 | usernameClaim: sub 5 | usernamePrefix: "oidcuser:" 6 | groupsClaim: groups 7 | groupsPrefix: "oidcgroup:" 8 | 9 | extraArgs: 10 | v: 10 11 | 12 | ingress: 13 | enabled: true 14 | annotations: 15 | cert-manager.io/cluster-issuer: letsencrypt-production 16 | nginx.ingress.kubernetes.io/backend-protocol: HTTPS 17 | hosts: 18 | - host: kube.ssotest.staging.talkingquickly.co.uk 19 | paths: 20 | - / 21 | tls: 22 | - secretName: oidc-proxy-tls 23 | hosts: 24 | - kube.ssotest.staging.talkingquickly.co.uk -------------------------------------------------------------------------------- /kubelogin/kubeconfig.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | clusters: 3 | - cluster: 4 | server: https://kube.ssotest.staging.talkingquickly.co.uk 5 | name: default 6 | contexts: 7 | - context: 8 | cluster: default 9 | namespace: identity 10 | user: oidc 11 | name: default 12 | current-context: default 13 | kind: Config 14 | preferences: {} 15 | users: 16 | - name: oidc 17 | user: 18 | exec: 19 | apiVersion: client.authentication.k8s.io/v1beta1 20 | args: 21 | - oidc-login 22 | - get-token 23 | # - -v1 24 | - --oidc-issuer-url=https://sso.ssotest.staging.talkingquickly.co.uk/auth/realms/master 25 | - --oidc-client-id=kube-oidc-proxy 26 | - --oidc-client-secret=a32807bc-4b5d-40b7-8391-91bb2b80fd30 27 | - --oidc-extra-scope=email 28 | - --grant-type=authcode 29 | command: kubectl 30 | env: null 31 | provideClusterInfo: false -------------------------------------------------------------------------------- /nginx-demo-app/values-nginx.yml: -------------------------------------------------------------------------------- 1 | serverBlock: | 2 | log_format withauthheaders '$remote_addr - $remote_user [$time_local] ' 3 | '"$request" $status $body_bytes_sent "$http_referer" ' 4 | '"$http_user_agent" "$http_x_forwarded_for" "$http_x_auth_request_access_token"'; 5 | 6 | add_header x-auth-request-access-token "$http_x_auth_request_access_token"; 7 | 8 | # HTTP Server 9 | server { 10 | # Port to listen on, can also be set in IP:PORT format 11 | listen 8080; 12 | 13 | include "/opt/bitnami/nginx/conf/bitnami/*.conf"; 14 | 15 | location /status { 16 | stub_status on; 17 | access_log off; 18 | allow 127.0.0.1; 19 | deny all; 20 | } 21 | 22 | access_log /dev/stdout withauthheaders; 23 | } 24 | 25 | ingress: 26 | enabled: true 27 | hostname: nginx-demo-app2.ssotest.staging.talkingquickly.co.uk 28 | tls: true 29 | annotations: 30 | cert-manager.io/cluster-issuer: letsencrypt-staging 31 | nginx.ingress.kubernetes.io/auth-url: "https://oauth.ssotest.staging.talkingquickly.co.uk/oauth2/auth" 32 | nginx.ingress.kubernetes.io/auth-signin: "https://oauth.ssotest.staging.talkingquickly.co.uk/oauth2/start?rd=$scheme://$best_http_host$request_uri" 33 | nginx.ingress.kubernetes.io/auth-response-headers: "x-auth-request-user, x-auth-request-email, x-auth-request-access-token" 34 | nginx.ingress.kubernetes.io/proxy-buffer-size: "16k" 35 | acme.cert-manager.io/http01-edit-in-place: "true" 36 | 37 | service: 38 | type: ClusterIP -------------------------------------------------------------------------------- /oauth2-proxy/values-oauth2-proxy.yml: -------------------------------------------------------------------------------- 1 | # Oauth client configuration specifics 2 | config: 3 | clientID: "oauth2-proxy" 4 | clientSecret: "b6414612-68fa-4d73-bdb6-1f79fa8a814c" 5 | # Create a new secret with the following command 6 | # openssl rand -base64 32 | head -c 32 | base64 7 | cookieSecret: "NXA4K2lMUGsrSnFLYnprWnZESE5GUDNINzIrc2NHUnQ=" 8 | configFile: |- 9 | provider = "oidc" 10 | provider_display_name = "Keycloak" 11 | oidc_issuer_url = "https://sso.ssotest.staging.talkingquickly.co.uk/auth/realms/master" 12 | email_domains = [ "*" ] 13 | scope = "openid profile email" 14 | cookie_domain = ".ssotest.staging.talkingquickly.co.uk" 15 | whitelist_domains = ".ssotest.staging.talkingquickly.co.uk" 16 | pass_authorization_header = true 17 | pass_access_token = true 18 | pass_user_headers = true 19 | set_authorization_header = true 20 | set_xauthrequest = true 21 | cookie_refresh = "1m" 22 | cookie_expire = "30m" 23 | 24 | ingress: 25 | enabled: true 26 | path: / 27 | hosts: 28 | - oauth.ssotest.staging.talkingquickly.co.uk 29 | annotations: 30 | cert-manager.io/cluster-issuer: letsencrypt-production 31 | nginx.ingress.kubernetes.io/proxy-buffer-size: "16k" 32 | tls: 33 | - secretName: oauth-proxy-tls 34 | hosts: 35 | - oauth.ssotest.staging.talkingquickly.co.uk -------------------------------------------------------------------------------- /openldap/values-openldap.yml: -------------------------------------------------------------------------------- 1 | # Default values for openldap. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | # Define deployment strategy - IMPORTANT: use rollingUpdate: null when use Recreate strategy. 8 | # It prevents from merging with existing map keys which are forbidden. 9 | strategy: {} 10 | # type: RollingUpdate 11 | # rollingUpdate: 12 | # maxSurge: 1 13 | # maxUnavailable: 0 14 | # 15 | # or 16 | # 17 | # type: Recreate 18 | # rollingUpdate: null 19 | image: 20 | # From repository https://github.com/osixia/docker-openldap 21 | repository: osixia/openldap 22 | tag: 1.2.4 23 | pullPolicy: IfNotPresent 24 | 25 | # Spcifies an existing secret to be used for admin and config user passwords 26 | existingSecret: "" 27 | 28 | # settings for enabling TLS 29 | tls: 30 | enabled: false 31 | secret: "" # The name of a kubernetes.io/tls type secret to use for TLS 32 | CA: 33 | enabled: false 34 | secret: "" # The name of a generic secret to use for custom CA certificate (ca.crt) 35 | ## Add additional labels to all resources 36 | extraLabels: {} 37 | ## Add additional annotations to pods 38 | podAnnotations: {} 39 | service: 40 | annotations: {} 41 | clusterIP: "" 42 | 43 | ldapPort: 389 44 | sslLdapPort: 636 # Only used if tls.enabled is true 45 | ## List of IP addresses at which the service is available 46 | ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips 47 | ## 48 | externalIPs: [] 49 | 50 | loadBalancerIP: "" 51 | loadBalancerSourceRanges: [] 52 | type: ClusterIP 53 | 54 | # Default configuration for openldap as environment variables. These get injected directly in the container. 55 | # Use the env variables from https://github.com/osixia/docker-openldap#beginner-guide 56 | env: 57 | LDAP_ORGANISATION: "Talking Quickly's Demo" 58 | LDAP_DOMAIN: "ssotest.staging.talkingquickly.co.uk" 59 | LDAP_BACKEND: "hdb" 60 | LDAP_TLS: "true" 61 | LDAP_TLS_ENFORCE: "false" 62 | LDAP_REMOVE_CONFIG_AFTER_SETUP: "true" 63 | LDAP_READONLY_USER: "true" 64 | LDAP_READONLY_USER_USERNAME: readonly 65 | LDAP_READONLY_USER_MASSWORD: password 66 | 67 | # Default Passwords to use, stored as a secret. If unset, passwords are auto-generated. 68 | # You can override these at install time with 69 | # helm install openldap --set openldap.adminPassword=,openldap.configPassword= 70 | adminPassword: password 71 | configPassword: password 72 | 73 | # Custom openldap configuration files used to override default settings 74 | customLdifFiles: 75 | 0-initial-ous.ldif: |- 76 | dn: ou=People,dc=ssotest,dc=staging,dc=talkingquickly,dc=co,dc=uk 77 | objectClass: organizationalUnit 78 | ou: People 79 | 80 | dn: ou=Group,dc=ssotest,dc=staging,dc=talkingquickly,dc=co,dc=uk 81 | objectClass: organizationalUnit 82 | ou: Group 83 | 84 | ## Persist data to a persistent volume 85 | persistence: 86 | enabled: true 87 | ## database data Persistent Volume Storage Class 88 | ## If defined, storageClassName: 89 | ## If set to "-", storageClassName: "", which disables dynamic provisioning 90 | ## If undefined (the default) or set to null, no storageClassName spec is 91 | ## set, choosing the default provisioner. (gp2 on AWS, standard on 92 | ## GKE, AWS & OpenStack) 93 | ## 94 | # storageClass: "-" 95 | accessMode: ReadWriteOnce 96 | size: 8Gi 97 | # existingClaim: "" 98 | 99 | resources: {} 100 | # requests: 101 | # cpu: "100m" 102 | # memory: "256Mi" 103 | # limits: 104 | # cpu: "500m" 105 | # memory: "512Mi" 106 | 107 | initResources: {} 108 | # requests: 109 | # cpu: "100m" 110 | # memory: "128Mi" 111 | # limits: 112 | # cpu: "100m" 113 | # memory: "128Mi" 114 | 115 | nodeSelector: {} 116 | 117 | tolerations: [] 118 | 119 | affinity: {} --------------------------------------------------------------------------------