From 00c1e17f6da1de94941fe277283588317407861a Mon Sep 17 00:00:00 2001 From: Deepak Goel Date: Mon, 20 Jan 2020 11:38:08 -0800 Subject: [PATCH] [custom certs] Updates charts to support custom certificate (#369) * Updates charts to support custom certificate * updates dex-k8s-authenticator with custom cert path info Co-authored-by: Alejandro Escobar --- staging/dex-k8s-authenticator/Chart.yaml | 2 +- .../html-templates/linux-mac-common.html | 18 ++++++------ .../templates/configmap.yaml | 8 ++++++ .../templates/deployment.yaml | 28 ++++++++++++++++++- staging/dex-k8s-authenticator/values.yaml | 2 ++ staging/kube-oidc-proxy/Chart.yaml | 2 +- .../kube-oidc-proxy/templates/deployment.yaml | 13 +++++++-- staging/kube-oidc-proxy/values.yaml | 1 + staging/traefik-forward-auth/Chart.yaml | 2 +- .../templates/deployment.yaml | 11 ++++++-- staging/traefik-forward-auth/values.yaml | 1 + staging/traefik/Chart.yaml | 2 +- staging/traefik/templates/configmap.yaml | 2 +- staging/traefik/templates/deployment.yaml | 11 ++++++-- staging/traefik/values.yaml | 2 +- 15 files changed, 82 insertions(+), 23 deletions(-) diff --git a/staging/dex-k8s-authenticator/Chart.yaml b/staging/dex-k8s-authenticator/Chart.yaml index 4f9a62aac..ba2d7acd2 100644 --- a/staging/dex-k8s-authenticator/Chart.yaml +++ b/staging/dex-k8s-authenticator/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v1 appVersion: "v1.1.1" description: "Authenticator for using Dex with Kubernetes" name: dex-k8s-authenticator -version: 1.1.12 +version: 1.1.13 home: https://github.com/mesosphere/charts sources: - https://github.com/mintel/dex-k8s-authenticator diff --git a/staging/dex-k8s-authenticator/html-templates/linux-mac-common.html b/staging/dex-k8s-authenticator/html-templates/linux-mac-common.html index 44309a5e3..0e46028a0 100644 --- a/staging/dex-k8s-authenticator/html-templates/linux-mac-common.html +++ b/staging/dex-k8s-authenticator/html-templates/linux-mac-common.html @@ -8,7 +8,7 @@

Copy IDP CA Certificate From URL

-
curl --create-dirs -s {{ .IDPCaURI }} -o ${HOME}/.kube/certs/{{ .ClusterName }}/idp-ca.crt
+
curl --create-dirs -s {{ .IDPCaURI }} -o ${HOME}/.kube/certs/{{ .Username }}-{{ .ClusterName }}/idp-ca.crt
{{ end }} @@ -22,7 +22,7 @@

Copy IDP CA Certificate From PEM

-
mkdir -p ${HOME}/.kube/certs/{{ .ClusterName }}/ && cat << EOF > ${HOME}/.kube/certs/{{ .ClusterName }}/idp-ca.crt
+      
mkdir -p ${HOME}/.kube/certs/{{ .Username }}-{{ .ClusterName }}/ && cat << EOF > ${HOME}/.kube/certs/{{ .Username }}-{{ .ClusterName }}/idp-ca.crt
 {{ .IDPCaPem }}
 EOF
@@ -38,7 +38,7 @@

Copy Kubernetes CA Certificate From URL

-
curl --create-dirs -s {{ .K8sCaURI }} -o ${HOME}/.kube/certs/{{ .ClusterName }}/k8s-ca.crt
+
curl --create-dirs -s {{ .K8sCaURI }} -o ${HOME}/.kube/certs/{{ .Username }}-{{ .ClusterName }}/k8s-ca.crt
{{ end }} @@ -52,7 +52,7 @@

Copy Kubernetes CA Certificate From PEM

-
mkdir -p ${HOME}/.kube/certs/{{ .ClusterName }}/ && cat << EOF > ${HOME}/.kube/certs/{{ .ClusterName }}/k8s-ca.crt
+      
mkdir -p ${HOME}/.kube/certs/{{ .Username }}-{{ .ClusterName }}/ && cat << EOF > ${HOME}/.kube/certs/{{ .Username }}-{{ .ClusterName }}/k8s-ca.crt
 {{ .K8sCaPem }}
 EOF
@@ -67,8 +67,8 @@

Run configuration commands

-
kubectl config set-cluster {{ .ClusterName }} \
-    --certificate-authority=${HOME}/.kube/certs/{{ .ClusterName}}/k8s-ca.crt \
+  
kubectl config set-cluster {{ .Username }}-{{ .ClusterName }} \
+    --certificate-authority=${HOME}/.kube/certs/{{ .Username }}-{{ .ClusterName}}/k8s-ca.crt \
     --server={{ .K8sMasterURI }}
@@ -80,7 +80,7 @@

Run configuration commands

kubectl config set-credentials {{ .Username }}-{{ .ClusterName }} \
     --token={{ .IDToken }}
   {{- if or (.IDPCaURI) (.IDPCaPem) }} \
-    --auth-provider-arg=idp-certificate-authority=${HOME}/.kube/certs/{{ .ClusterName }}/idp-ca.crt
+    --auth-provider-arg=idp-certificate-authority=${HOME}/.kube/certs/{{ .Username }}-{{ .ClusterName }}/idp-ca.crt
   {{- end }}
@@ -90,8 +90,8 @@

Run configuration commands

kubectl config set-context {{ .Username }}-{{ .ClusterName }} \
-    --cluster={{ .ClusterName }} \
-    --user={{ .Username}}-{{.ClusterName }}
+ --cluster={{ .Username }}-{{ .ClusterName }} \ + --user={{ .Username }}-{{.ClusterName }}
diff --git a/staging/dex-k8s-authenticator/templates/configmap.yaml b/staging/dex-k8s-authenticator/templates/configmap.yaml index 9a17ad106..746d2b2e1 100644 --- a/staging/dex-k8s-authenticator/templates/configmap.yaml +++ b/staging/dex-k8s-authenticator/templates/configmap.yaml @@ -30,4 +30,12 @@ data: clusters: {{ toYaml .clusters | indent 4 }} {{- end }} + {{- if .Values.caCerts.enabled }} + caCerts: "true" + {{- if .Values.caCerts.secrets }} + caCertPath: /certs/{{ .filename }} + {{- else }} + caCertPath: /certs/ca.crt + {{- end }} + {{- end }} diff --git a/staging/dex-k8s-authenticator/templates/deployment.yaml b/staging/dex-k8s-authenticator/templates/deployment.yaml index ec249628f..803d98ff9 100644 --- a/staging/dex-k8s-authenticator/templates/deployment.yaml +++ b/staging/dex-k8s-authenticator/templates/deployment.yaml @@ -37,6 +37,18 @@ spec: {{- if .Values.initContainers }} initContainers: {{- toYaml .Values.initContainers | nindent 8 }} + volumeMounts: +{{- if .Values.caCerts.enabled }} +{{- if .Values.caCerts.secrets }} +{{- range .Values.caCerts.secrets }} + - name: {{ template "dex-k8s-authenticator.fullname" $ }}-{{ .name }} + mountPath: /certs/ +{{- end }} +{{- else if .Values.caCerts.caSecretName }} + - name: {{ template "dex-k8s-authenticator.fullname" $ }}-ca-certificate + mountPath: /certs/ +{{- end }} +{{- end }} {{- end }} containers: - name: {{ .Chart.Name }} @@ -65,10 +77,15 @@ spec: - name: html-templates mountPath: /app/templates/ {{- if .Values.caCerts.enabled }} +{{- if .Values.caCerts.secrets }} {{- range .Values.caCerts.secrets }} - name: {{ template "dex-k8s-authenticator.fullname" $ }}-{{ .name }} mountPath: /certs/ {{- end }} +{{- else if .Values.caCerts.caSecretName }} + - name: {{ template "dex-k8s-authenticator.fullname" $ }}-ca-certificate + mountPath: /certs/ +{{- end }} {{- end }} resources: {{ toYaml .Values.resources | indent 10 }} @@ -105,7 +122,8 @@ spec: path: {{ base $path }} {{- end }} {{- if .Values.caCerts.enabled }} -{{- range .Values.caCerts.secrets }} +{{- if .Values.caCerts.secrets }} +{{- range .Values.caCerts.secrets }} - name: {{ template "dex-k8s-authenticator.fullname" $ }}-{{ .name }} secret: secretName: {{ template "dex-k8s-authenticator.fullname" $ }}-{{ .name }} @@ -113,4 +131,12 @@ spec: - key: {{ .name }} path: {{ .filename }} {{- end }} +{{- else if .Values.caCerts.caSecretName }} + - name: {{ template "dex-k8s-authenticator.fullname" $ }}-ca-certificate + secret: + secretName: {{ .Values.caCerts.caSecretName }} + items: + - key: ca.crt + path: ca.crt +{{- end }} {{- end }} diff --git a/staging/dex-k8s-authenticator/values.yaml b/staging/dex-k8s-authenticator/values.yaml index f4145ce52..e791933c8 100644 --- a/staging/dex-k8s-authenticator/values.yaml +++ b/staging/dex-k8s-authenticator/values.yaml @@ -73,6 +73,8 @@ resources: {} caCerts: enabled: false + # specify either caSecretName or secrets + caSecretName: secrets: {} # Array of Self Signed Certificates # cat CA.crt | base64 -w 0 diff --git a/staging/kube-oidc-proxy/Chart.yaml b/staging/kube-oidc-proxy/Chart.yaml index a8f749e78..e41123d04 100644 --- a/staging/kube-oidc-proxy/Chart.yaml +++ b/staging/kube-oidc-proxy/Chart.yaml @@ -3,7 +3,7 @@ appVersion: "v0.1.1" description: A Helm chart for kube-oidc-proxy home: https://github.com/mesosphere/charts name: kube-oidc-proxy -version: 0.1.7 +version: 0.1.8 sources: - https://github.com/jetstack/kube-oidc-proxy maintainers: diff --git a/staging/kube-oidc-proxy/templates/deployment.yaml b/staging/kube-oidc-proxy/templates/deployment.yaml index 40783601f..9b82f22cd 100644 --- a/staging/kube-oidc-proxy/templates/deployment.yaml +++ b/staging/kube-oidc-proxy/templates/deployment.yaml @@ -49,8 +49,10 @@ spec: - "--oidc-client-id=$(OIDC_CLIENT_ID)" - "--oidc-issuer-url=$(OIDC_ISSUER_URL)" - "--oidc-username-claim=$(OIDC_USERNAME_CLAIM)" - {{- if .Values.oidc.caPEM }} + {{- if or .Values.oidc.caPEM .Values.oidc.caSecretName }} - "--oidc-ca-file=/etc/oidc/oidc-ca.pem" + {{- else }} + - "--oidc-ca-file=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" {{ end }} {{- if .Values.oidc.usernamePrefix }} - "--oidc-username-prefix=$(OIDC_USERNAME_PREFIX)" @@ -141,7 +143,7 @@ spec: key: api-audiences {{ end }} volumeMounts: - {{ if .Values.oidc.caPEM }} + {{ if or .Values.oidc.caPEM .Values.oidc.caSecretName }} - name: kube-oidc-proxy-config mountPath: /etc/oidc readOnly: true @@ -157,6 +159,13 @@ spec: items: - key: oidc.ca-pem path: oidc-ca.pem + {{- else if .Values.oidc.caSecretName }} + - name: kube-oidc-proxy-config + secret: + secretName: {{ .Values.oidc.caSecretName }} + items: + - key: ca.crt + path: oidc-ca.pem {{ end }} - name: kube-oidc-proxy-tls secret: diff --git a/staging/kube-oidc-proxy/values.yaml b/staging/kube-oidc-proxy/values.yaml index 01a016a11..6ed434276 100644 --- a/staging/kube-oidc-proxy/values.yaml +++ b/staging/kube-oidc-proxy/values.yaml @@ -38,6 +38,7 @@ oidc: # ... # -----END CERTIFICATE----- caPEM: + caSecretName: # specify caPEM or caSecretName usernamePrefix: groupsClaim: diff --git a/staging/traefik-forward-auth/Chart.yaml b/staging/traefik-forward-auth/Chart.yaml index 06f263747..2fc5af941 100644 --- a/staging/traefik-forward-auth/Chart.yaml +++ b/staging/traefik-forward-auth/Chart.yaml @@ -3,7 +3,7 @@ apiVersion: v1 appVersion: "latest" description: Minimal forward authentication service that provides OIDC based login and authentication for the traefik reverse proxy name: traefik-forward-auth -version: 0.2.11 +version: 0.2.12 keywords: - traefik-forward-auth - traefik diff --git a/staging/traefik-forward-auth/templates/deployment.yaml b/staging/traefik-forward-auth/templates/deployment.yaml index 9d05a8b31..6c6ac6c26 100644 --- a/staging/traefik-forward-auth/templates/deployment.yaml +++ b/staging/traefik-forward-auth/templates/deployment.yaml @@ -36,6 +36,13 @@ spec: items: - key: ca.crt path: ca.crt + {{- else if .Values.traefikForwardAuth.caSecretName }} + - name: etc-traefik-forward-auth-ca + secret: + secretName: {{ .Values.traefikForwardAuth.caSecretName }} + items: + - key: ca.crt + path: ca.crt {{- end }} - name: etc-traefik-forward-auth-config configMap: @@ -48,7 +55,7 @@ spec: image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} volumeMounts: - {{- if .Values.traefikForwardAuth.caCertificate }} + {{- if or .Values.traefikForwardAuth.caCertificate .Values.traefikForwardAuth.caSecretName }} - name: etc-traefik-forward-auth-ca mountPath: "/etc/traefik-forward-auth/ca" readOnly: true @@ -66,7 +73,7 @@ spec: - name: CONFIG value: "/etc/traefik-forward-auth/config/config.ini" - name: SSL_CERT_FILE - {{- if .Values.traefikForwardAuth.caCertificate }} + {{- if or .Values.traefikForwardAuth.caCertificate .Values.traefikForwardAuth.caSecretName }} value: "/etc/traefik-forward-auth/ca/ca.crt" {{- else}} value: "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" diff --git a/staging/traefik-forward-auth/values.yaml b/staging/traefik-forward-auth/values.yaml index 4ce14b64a..e1fddb828 100644 --- a/staging/traefik-forward-auth/values.yaml +++ b/staging/traefik-forward-auth/values.yaml @@ -40,6 +40,7 @@ traefikForwardAuth: # -----BEGIN # ... # -----END + # or caSecretName: < name of the secret > extraConfig: "" userCookieName: "_forward_auth_name" diff --git a/staging/traefik/Chart.yaml b/staging/traefik/Chart.yaml index 5dbb664b5..d3bc91b0b 100644 --- a/staging/traefik/Chart.yaml +++ b/staging/traefik/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: traefik -version: 1.72.11 +version: 1.72.12 appVersion: 1.7.12 description: A Traefik based Kubernetes ingress controller with Let's Encrypt support keywords: diff --git a/staging/traefik/templates/configmap.yaml b/staging/traefik/templates/configmap.yaml index 0b5dbef4d..c0538bc7a 100644 --- a/staging/traefik/templates/configmap.yaml +++ b/staging/traefik/templates/configmap.yaml @@ -97,7 +97,7 @@ data: {{- if .Values.ssl.sniStrict }} sniStrict = true {{- end }} - {{- if .Values.ssl.customCert }} + {{- if .Values.ssl.caSecretName }} [[entryPoints.https.tls.certificates]] certFile = "/custom-ssl/tls.crt" keyFile = "/custom-ssl/tls.key" diff --git a/staging/traefik/templates/deployment.yaml b/staging/traefik/templates/deployment.yaml index c7be45da2..7763f8504 100644 --- a/staging/traefik/templates/deployment.yaml +++ b/staging/traefik/templates/deployment.yaml @@ -133,7 +133,7 @@ spec: - mountPath: /ssl name: ssl {{- end }} - {{- if .Values.ssl.customCert }} + {{- if .Values.ssl.caSecretName }} - mountPath: /custom-ssl name: custom-ssl {{- end }} @@ -188,10 +188,15 @@ spec: secret: secretName: {{ template "traefik.fullname" . }}-certificate {{- end }} - {{- if .Values.ssl.customCert }} + {{- if .Values.ssl.caSecretName }} - name: custom-ssl secret: - secretName: {{ template "traefik.fullname" . }}-custom-certificate + secretName: {{ .Values.ssl.caSecretName }} + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key {{- end }} {{- if .Values.acme.enabled }} - name: acme diff --git a/staging/traefik/values.yaml b/staging/traefik/values.yaml index 1392ae4b5..6d7c4fa97 100644 --- a/staging/traefik/values.yaml +++ b/staging/traefik/values.yaml @@ -136,7 +136,7 @@ ssl: # tlsMinVersion: VersionTLS12 # https://docs.traefik.io/configuration/entrypoints/#strict-sni-checking # sniStrict: false - customCert: false + caSecretName: # for custom certificate defaultCert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVtekNDQTRPZ0F3SUJBZ0lKQUpBR1FsTW1DMGt5TUEwR0NTcUdTSWIzRFFFQkJRVUFNSUdQTVFzd0NRWUQKVlFRR0V3SlZVekVSTUE4R0ExVUVDQk1JUTI5c2IzSmhaRzh4RURBT0JnTlZCQWNUQjBKdmRXeGtaWEl4RkRBUwpCZ05WQkFvVEMwVjRZVzF3YkdWRGIzSndNUXN3Q1FZRFZRUUxFd0pKVkRFV01CUUdBMVVFQXhRTktpNWxlR0Z0CmNHeGxMbU52YlRFZ01CNEdDU3FHU0liM0RRRUpBUllSWVdSdGFXNUFaWGhoYlhCc1pTNWpiMjB3SGhjTk1UWXgKTURJME1qRXdPVFV5V2hjTk1UY3hNREkwTWpFd09UVXlXakNCanpFTE1Ba0dBMVVFQmhNQ1ZWTXhFVEFQQmdOVgpCQWdUQ0VOdmJHOXlZV1J2TVJBd0RnWURWUVFIRXdkQ2IzVnNaR1Z5TVJRd0VnWURWUVFLRXd0RmVHRnRjR3hsClEyOXljREVMTUFrR0ExVUVDeE1DU1ZReEZqQVVCZ05WQkFNVURTb3VaWGhoYlhCc1pTNWpiMjB4SURBZUJna3EKaGtpRzl3MEJDUUVXRVdGa2JXbHVRR1Y0WVcxd2JHVXVZMjl0TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQwpBUThBTUlJQkNnS0NBUUVBdHVKOW13dzlCYXA2SDROdUhYTFB6d1NVZFppNGJyYTFkN1ZiRUJaWWZDSStZNjRDCjJ1dThwdTNhVTVzYXVNYkQ5N2pRYW95VzZHOThPUHJlV284b3lmbmRJY3RFcmxueGpxelUyVVRWN3FEVHk0bkEKNU9aZW9SZUxmZXFSeGxsSjE0VmlhNVFkZ3l3R0xoRTlqZy9jN2U0WUp6bmg5S1dZMnFjVnhEdUdEM2llaHNEbgphTnpWNFdGOWNJZm1zOHp3UHZPTk5MZnNBbXc3dUhUKzNiSzEzSUloeDI3ZmV2cXVWcENzNDFQNnBzdStWTG4yCjVIRHk0MXRoQkN3T0wrTithbGJ0ZktTcXM3TEFzM25RTjFsdHpITHZ5MGE1RGhkakpUd2tQclQrVXhwb0tCOUgKNFpZazErRUR0N09QbGh5bzM3NDFRaE4vSkNZK2RKbkFMQnNValFJREFRQUJvNEgzTUlIME1CMEdBMVVkRGdRVwpCQlJwZVc1dFhMdHh3TXJvQXM5d2RNbTUzVVVJTERDQnhBWURWUjBqQklHOE1JRzVnQlJwZVc1dFhMdHh3TXJvCkFzOXdkTW01M1VVSUxLR0JsYVNCa2pDQmp6RUxNQWtHQTFVRUJoTUNWVk14RVRBUEJnTlZCQWdUQ0VOdmJHOXkKWVdSdk1SQXdEZ1lEVlFRSEV3ZENiM1ZzWkdWeU1SUXdFZ1lEVlFRS0V3dEZlR0Z0Y0d4bFEyOXljREVMTUFrRwpBMVVFQ3hNQ1NWUXhGakFVQmdOVkJBTVVEU291WlhoaGJYQnNaUzVqYjIweElEQWVCZ2txaGtpRzl3MEJDUUVXCkVXRmtiV2x1UUdWNFlXMXdiR1V1WTI5dGdna0FrQVpDVXlZTFNUSXdEQVlEVlIwVEJBVXdBd0VCL3pBTkJna3EKaGtpRzl3MEJBUVVGQUFPQ0FRRUFjR1hNZms4TlpzQit0OUtCemwxRmw2eUlqRWtqSE8wUFZVbEVjU0QyQjRiNwpQeG5NT2pkbWdQcmF1SGI5dW5YRWFMN3p5QXFhRDZ0YlhXVTZSeENBbWdMYWpWSk5aSE93NDVOMGhyRGtXZ0I4CkV2WnRRNTZhbW13QzFxSWhBaUE2MzkwRDNDc2V4N2dMNm5KbzdrYnIxWVdVRzN6SXZveGR6OFlEclpOZVdLTEQKcFJ2V2VuMGxNYnBqSVJQNFhac25DNDVDOWdWWGRoM0xSZTErd3lRcTZoOVFQaWxveG1ENk5wRTlpbVRPbjJBNQovYkozVktJekFNdWRlVTZrcHlZbEpCemRHMXVhSFRqUU9Xb3NHaXdlQ0tWVVhGNlV0aXNWZGRyeFF0aDZFTnlXCnZJRnFhWng4NCtEbFNDYzkzeWZrL0dsQnQrU0tHNDZ6RUhNQjlocVBiQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K defaultKey: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBdHVKOW13dzlCYXA2SDROdUhYTFB6d1NVZFppNGJyYTFkN1ZiRUJaWWZDSStZNjRDCjJ1dThwdTNhVTVzYXVNYkQ5N2pRYW95VzZHOThPUHJlV284b3lmbmRJY3RFcmxueGpxelUyVVRWN3FEVHk0bkEKNU9aZW9SZUxmZXFSeGxsSjE0VmlhNVFkZ3l3R0xoRTlqZy9jN2U0WUp6bmg5S1dZMnFjVnhEdUdEM2llaHNEbgphTnpWNFdGOWNJZm1zOHp3UHZPTk5MZnNBbXc3dUhUKzNiSzEzSUloeDI3ZmV2cXVWcENzNDFQNnBzdStWTG4yCjVIRHk0MXRoQkN3T0wrTithbGJ0ZktTcXM3TEFzM25RTjFsdHpITHZ5MGE1RGhkakpUd2tQclQrVXhwb0tCOUgKNFpZazErRUR0N09QbGh5bzM3NDFRaE4vSkNZK2RKbkFMQnNValFJREFRQUJBb0lCQUhrTHhka0dxNmtCWWQxVAp6MkU4YWFENnhneGpyY2JSdGFCcTc3L2hHbVhuQUdaWGVWcE81MG1SYW8wbHZ2VUgwaE0zUnZNTzVKOHBrdzNmCnRhWTQxT1dDTk1PMlYxb1MvQmZUK3Zsblh6V1hTemVQa0pXd2lIZVZMdVdEaVVMQVBHaWl4emF2RFMyUnlQRmEKeGVRdVNhdE5pTDBGeWJGMG5Zd3pST3ZoL2VSa2NKVnJRZlZudU1melFkOGgyMzZlb1UxU3B6UnhSNklubCs5UApNc1R2Wm5OQmY5d0FWcFo5c1NMMnB1V1g3SGNSMlVnem5oMDNZWUZJdGtDZndtbitEbEdva09YWHBVM282aWY5ClRIenBleHdubVJWSmFnRG85bTlQd2t4QXowOW80cXExdHJoU1g1U2p1K0xyNFJvOHg5bytXdUF1VnVwb0lHd0wKMWVseERFRUNnWUVBNzVaWGp1enNJR09PMkY5TStyYVFQcXMrRHZ2REpzQ3gyZnRudk1WWVJKcVliaGt6YnpsVQowSHBCVnk3NmE3WmF6Umxhd3RGZ3ljMlpyQThpM0F3K3J6d1pQclNJeWNieC9nUVduRzZlbFF1Y0FFVWdXODRNCkdSbXhKUGlmOGRQNUxsZXdRalFjUFJwZVoxMzlYODJreGRSSEdma1pscHlXQnFLajBTWExRSEVDZ1lFQXcybkEKbUVXdWQzZFJvam5zbnFOYjBlYXdFUFQrbzBjZ2RyaENQOTZQK1pEekNhcURUblZKV21PeWVxRlk1eVdSSEZOLwpzbEhXU2lTRUFjRXRYZys5aGlMc0RXdHVPdzhUZzYyN2VrOEh1UUtMb2tWWEFUWG1NZG9xOWRyQW9INU5hV2lECmRSY3dEU2EvamhIN3RZV1hKZDA4VkpUNlJJdU8vMVZpbDBtbEk5MENnWUVBb2lsNkhnMFNUV0hWWDNJeG9raEwKSFgrK1ExbjRYcFJ5VEg0eldydWY0TjlhYUxxNTY0QThmZGNodnFiWGJHeEN6U3RxR1E2cW1peUU1TVpoNjlxRgoyd21zZEpxeE14RnEzV2xhL0lxSzM0cTZEaHk3cUNld1hKVGRKNDc0Z3kvY0twZkRmeXZTS1RGZDBFejNvQTZLCmhqUUY0L2lNYnpxUStQREFQR0YrVHFFQ2dZQmQ1YnZncjJMMURzV1FJU3M4MHh3MDBSZDdIbTRaQVAxdGJuNk8KK0IvUWVNRC92UXBaTWV4c1hZbU9lV2Noc3FCMnJ2eW1MOEs3WDY1NnRWdGFYay9nVzNsM3ZVNTdYSFF4Q3RNUwpJMVYvcGVSNHRiN24yd0ZncFFlTm1XNkQ4QXk4Z0xiaUZhRkdRSDg5QWhFa0dTd1d5cWJKc2NoTUZZOUJ5OEtUCkZaVWZsUUtCZ0V3VzJkVUpOZEJMeXNycDhOTE1VbGt1ZnJxbllpUTNTQUhoNFZzWkg1TXU0MW55Yi95NUUyMW4KMk55d3ltWGRlb3VJcFZjcUlVTXl0L3FKRmhIcFJNeVEyWktPR0QyWG5YaENNVlRlL0FQNDJod294Nm02QkZpQgpvemZFa2wwak5uZmREcjZrL1p2MlQ1TnFzaWxaRXJBQlZGOTBKazdtUFBIa0Q2R1ZMUUJ4Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== # Basic auth to protect all the routes. Can use htpasswd to generate passwords