diff --git a/imghost/templates/configmap-oauth2.yaml b/imghost/templates/configmap-oauth2.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..feabf7363ca558374212d0fe04ae5842dd0aca3b
--- /dev/null
+++ b/imghost/templates/configmap-oauth2.yaml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "imghost-helm.fullname" . }}-oauth2
+  labels:
+    component: oauth2
+    {{- include "imghost-helm.labels" . | nindent 4 }}
+stringData:
+  config: |-
+    {{ .Values.oauth2.config | toYaml | nindent 4 }}
diff --git a/imghost/templates/deployment-oauth.yaml b/imghost/templates/deployment-oauth.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..74e7fb7eeeda433277e13bddc6155b7d377c4f2d
--- /dev/null
+++ b/imghost/templates/deployment-oauth.yaml
@@ -0,0 +1,105 @@
+{{- $defaultName := printf "%s-%s" "frontend"  -}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "imghost-helm.fullname" . }}-oauth2
+  labels:
+    component: oauth2
+    {{- include "imghost-helm.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      component: oauth2
+      {{- include "imghost-helm.selectorLabels" . | nindent 6 }}
+  template:
+    metadata:
+      {{- with .Values.podAnnotations }}
+      annotations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      labels:
+        component: oauth2
+        {{- include "imghost-helm.selectorLabels" . | nindent 8 }}
+    spec:
+      {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      volumes:
+        - name: config
+          configMap:
+            name: "{{ include "imghost-helm.fullname" . }}-oauth2"
+      containers:
+        - name: {{ .Chart.Name }}-oauth2
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.oauth2.repository }}:{{ .Values.frontend.tag | default .Values.oauth2.tag }}"
+          imagePullPolicy: {{ .Values.frontend.pullPolicy }}
+          env:
+            - name: PROXY_CLIENT_ID
+              valueFrom:
+                secretKeyRef:
+                  name: "{{ include "imghost-helm.fullname" . }}-oauth2"
+                  key: "client-id"
+            - name: PROXY_CLIENT_SECRET
+              valueFrom:
+                secretKeyRef:
+                  name: "{{ include "imghost-helm.fullname" . }}-oauth2"
+                  key: "client-secret"
+            - name: PROXY_ENCRYPTION_KEY
+              valueFrom:
+                secretKeyRef:
+                  name: "{{ include "imghost-helm.fullname" . }}-oauth2"
+                  key: "cookie-secret"
+          args:
+          - "--config=${local.proxy_config_path}"
+          - "--listen=0.0.0.0:4180"
+          - "--enable-refresh-tokens=true"
+          - "--discovery-url={{ .Values.oauth2.discoveryUrl }}"
+          - "--redirection-url=https://{{ .Values.ingress.host }}{{ .Values.ingress.path }}"
+          - "--upstream-url=http://{{ include "imghost-helm.fullname" . }}-frontend.{{ .Release.Namespace }}.svc.cluster.local/"
+          - "--add-claims=id"
+          - "--upstream-timeout=120s"
+          - "--upstream-response-header-timeout=120s"
+          - "--upstream-expect-continue-timeout=120s"
+          - "--server-read-timeout=120s"
+          - "--server-write-timeout=120s"
+          - "--server-idle-timeout=120s"
+          - "--enable-default-deny=false"
+          ports:
+            - name: http
+              containerPort: 4180
+              protocol: TCP
+          startupProbe:
+            httpGet:
+              path: /healthz
+              port: http
+          livenessProbe:
+            httpGet:
+              path: /healthz
+              port: http
+          readinessProbe:
+            httpGet:
+              path: /healthz
+              port: http
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+          volumeMounts:
+            - mountPath: "/proxy_config.yaml"
+              name: config
+              subPath: "proxy-config"
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
diff --git a/imghost/templates/ingress.yaml b/imghost/templates/ingress.yaml
index 7b0c9b35a2fe9b4db57cb518138ecf95ff572f8e..a785c9b5253ea85396bf2fe8fefbff96efd0ac07 100644
--- a/imghost/templates/ingress.yaml
+++ b/imghost/templates/ingress.yaml
@@ -1,9 +1,8 @@
 apiVersion: networking.k8s.io/v1
 kind: Ingress
 metadata:
-  name: {{ include "imghost-helm.fullname" . }}-frontend
+  name: {{ include "imghost-helm.fullname" . }}
   labels:
-    component: frontend
     {{- include "imghost-helm.labels" . | nindent 4 }}
   annotations:
     {{- .Values.ingress.annotations | toYaml | nindent 4 }}
@@ -15,7 +14,7 @@ spec:
           - path: "{{ .Values.ingress.path }}"
             backend:
               service:
-                name: {{ include "imghost-helm.fullname" . }}-frontend
+                name: {{ include "imghost-helm.fullname" . }}-oauth2
                 port:
                   name: http
             pathType: Prefix
diff --git a/imghost/templates/secret-oauth2.yaml b/imghost/templates/secret-oauth2.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..255bb5a80cb3d3e4626a30122809943c58180b99
--- /dev/null
+++ b/imghost/templates/secret-oauth2.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "imghost-helm.fullname" . }}-oauth2
+  labels:
+    component: oauth2
+    {{- include "imghost-helm.labels" . | nindent 4 }}
+stringData:
+  client-id: {{ .Values.oauth2.clientId }}
+  client-secret: {{ .Values.oauth2.clientSecret }}
+  cookie-secret: {{ .Values.oauth2.cookieSecret }}
diff --git a/imghost/templates/service-oauth2.yaml b/imghost/templates/service-oauth2.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9fb3a39916efc5db2cdc9a538e6526be76fa291a
--- /dev/null
+++ b/imghost/templates/service-oauth2.yaml
@@ -0,0 +1,17 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "imghost-helm.fullname" . }}-oauth2
+  labels:
+    component: oauth2
+    {{- include "imghost-helm.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: 80
+      targetPort: http
+      protocol: TCP
+      name: http
+  selector:
+    component: oauth2
+    {{- include "imghost-helm.selectorLabels" . | nindent 4 }}
diff --git a/imghost/values.yaml b/imghost/values.yaml
index 161f39e8d5b7e4516f148fdd0fd7351e7f7763f3..cd7bb757e4134d5eaff9b04a4e07cb7c0d1c018e 100644
--- a/imghost/values.yaml
+++ b/imghost/values.yaml
@@ -14,6 +14,17 @@ backend:
   pullPolicy: IfNotPresent
   tag: ""
 
+oauth2:
+  repository: k8r.eu/justjanne/keycloak-proxy
+  pullPolicy: IfNotPresent
+  tag: "v2.3.0-53-g88ed211"
+  clientId: ""
+  clientSecret: ""
+  cookieSecret: ""
+  discoveryUrl: "https://example.com/auth/realm/main"
+  config:
+    resources: [ ]
+
 config:
   sizes:
     - suffix: "s"