From a78b9656b338d864777a03420e69451fd0a1d44f Mon Sep 17 00:00:00 2001 From: codens-agent Date: Sun, 28 Jun 2026 09:31:03 +0000 Subject: [PATCH 1/2] chore: Add helm/templates/secret.yaml (lookup-idempotent), serviceaccount.yaml, rbac.yaml; update deployment.yaml and worker-deployment.yaml with SecurityContext and secret injection --- helm/templates/_helpers.tpl | 22 +++++++++ helm/templates/deployment.yaml | 69 ++++++++++++++++++++++++++- helm/templates/rbac.yaml | 27 +++++++++++ helm/templates/secret.yaml | 23 +++++++++ helm/templates/serviceaccount.yaml | 13 +++++ helm/templates/worker-deployment.yaml | 20 ++++++++ 6 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 helm/templates/rbac.yaml create mode 100644 helm/templates/secret.yaml create mode 100644 helm/templates/serviceaccount.yaml diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl index 9af06f31..413ce85e 100644 --- a/helm/templates/_helpers.tpl +++ b/helm/templates/_helpers.tpl @@ -47,3 +47,25 @@ Chart label {{- define "open-git.chart" -}} {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} {{- end }} + +{{/* +Secret name — existingSecret if set, otherwise auto-generated name. +*/}} +{{- define "open-git.secretName" -}} +{{- if .Values.secrets.existingSecret }} +{{- .Values.secrets.existingSecret }} +{{- else }} +{{- printf "%s-secrets" (include "open-git.fullname" .) }} +{{- end }} +{{- end }} + +{{/* +ServiceAccount name +*/}} +{{- define "open-git.serviceAccountName" -}} +{{- if .Values.serviceAccount.name }} +{{- .Values.serviceAccount.name }} +{{- else }} +{{- include "open-git.fullname" . }} +{{- end }} +{{- end }} diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index 090fa8bf..86da934b 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -17,10 +17,20 @@ spec: {{- include "open-git.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: backend spec: + serviceAccountName: {{ include "open-git.serviceAccountName" . }} + imagePullSecrets: + {{- toYaml .Values.imagePullSecrets | nindent 8 }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + fsGroup: 1000 containers: - name: backend image: "{{ .Values.image.backend.repository }}:{{ .Values.image.backend.tag }}" imagePullPolicy: {{ .Values.image.backend.pullPolicy }} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false ports: - name: http containerPort: 8080 @@ -63,16 +73,31 @@ spec: - name: MINIO_BUCKET value: {{ .Values.minio.bucket | quote }} {{- end }} + - name: JWT_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: jwt-secret + - name: OAUTH_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: oauth-client-secret + - name: WEBHOOK_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: webhook-secret readinessProbe: httpGet: - path: /health + path: /readyz port: 8080 initialDelaySeconds: 5 periodSeconds: 10 failureThreshold: 3 livenessProbe: httpGet: - path: /health + path: /healthz port: 8080 initialDelaySeconds: 15 periodSeconds: 20 @@ -111,13 +136,53 @@ spec: {{- include "open-git.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: frontend spec: + serviceAccountName: {{ include "open-git.serviceAccountName" . }} + imagePullSecrets: + {{- toYaml .Values.imagePullSecrets | nindent 8 }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + fsGroup: 1000 containers: - name: frontend image: "{{ .Values.image.frontend.repository }}:{{ .Values.image.frontend.tag }}" imagePullPolicy: {{ .Values.image.frontend.pullPolicy }} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false ports: - name: http containerPort: 3000 protocol: TCP + env: + - name: JWT_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: jwt-secret + - name: OAUTH_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: oauth-client-secret + - name: WEBHOOK_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: webhook-secret + readinessProbe: + httpGet: + path: /readyz + port: 3000 + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 3 + livenessProbe: + httpGet: + path: /healthz + port: 3000 + initialDelaySeconds: 15 + periodSeconds: 20 + failureThreshold: 3 resources: {{- toYaml .Values.resources | nindent 12 }} diff --git a/helm/templates/rbac.yaml b/helm/templates/rbac.yaml new file mode 100644 index 00000000..438f3f93 --- /dev/null +++ b/helm/templates/rbac.yaml @@ -0,0 +1,27 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "open-git.fullname" . }} + labels: + {{- include "open-git.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["configmaps", "secrets"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "open-git.fullname" . }} + labels: + {{- include "open-git.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "open-git.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "open-git.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/templates/secret.yaml b/helm/templates/secret.yaml new file mode 100644 index 00000000..86cab582 --- /dev/null +++ b/helm/templates/secret.yaml @@ -0,0 +1,23 @@ +{{- if not .Values.secrets.existingSecret }} +{{- $secret := lookup "v1" "Secret" .Release.Namespace (include "open-git.secretName" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "open-git.secretName" . }} + labels: + {{- include "open-git.labels" . | nindent 4 }} + app.kubernetes.io/component: secrets +type: Opaque +data: + {{- if $secret }} + db-password: {{ index $secret.data "db-password" }} + jwt-secret: {{ index $secret.data "jwt-secret" }} + oauth-client-secret: {{ index $secret.data "oauth-client-secret" }} + webhook-secret: {{ index $secret.data "webhook-secret" }} + {{- else }} + db-password: {{ randAlphaNum 32 | b64enc | quote }} + jwt-secret: {{ randAlphaNum 32 | b64enc | quote }} + oauth-client-secret: {{ randAlphaNum 32 | b64enc | quote }} + webhook-secret: {{ randAlphaNum 32 | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/helm/templates/serviceaccount.yaml b/helm/templates/serviceaccount.yaml new file mode 100644 index 00000000..0a9105ed --- /dev/null +++ b/helm/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "open-git.serviceAccountName" . }} + labels: + {{- include "open-git.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: false +{{- end }} diff --git a/helm/templates/worker-deployment.yaml b/helm/templates/worker-deployment.yaml index 59b1f03f..32cd0f27 100644 --- a/helm/templates/worker-deployment.yaml +++ b/helm/templates/worker-deployment.yaml @@ -17,10 +17,20 @@ spec: {{- include "open-git.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: worker spec: + serviceAccountName: {{ include "open-git.serviceAccountName" . }} + imagePullSecrets: + {{- toYaml .Values.imagePullSecrets | nindent 8 }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + fsGroup: 1000 containers: - name: worker image: "{{ .Values.image.backend.repository }}:{{ .Values.image.backend.tag }}" imagePullPolicy: {{ .Values.image.backend.pullPolicy }} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false args: - "--worker-only" env: @@ -59,6 +69,16 @@ spec: - name: MINIO_BUCKET value: {{ .Values.minio.bucket | quote }} {{- end }} + - name: JWT_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: jwt-secret + - name: WEBHOOK_SECRET + valueFrom: + secretKeyRef: + name: {{ include "open-git.secretName" . }} + key: webhook-secret resources: {{- toYaml .Values.resources | nindent 12 }} {{- with .Values.nodeSelector }} From dd43f9757af1b48a4dc5fdbccb2f9e87472e6d2a Mon Sep 17 00:00:00 2001 From: codens-agent Date: Sun, 28 Jun 2026 09:33:03 +0000 Subject: [PATCH 2/2] chore: Add helm/templates/secret.yaml (lookup-idempotent), serviceaccount.yaml, rbac.yaml; update deployment.yaml and worker-deployment.yaml with SecurityContext and secret injection --- helm/templates/_helpers.tpl | 21 ++++++++++- helm/templates/deployment.yaml | 50 ++++++++++++--------------- helm/templates/rbac.yaml | 16 +++++++-- helm/templates/secret.yaml | 8 ++--- helm/templates/worker-deployment.yaml | 17 +++++---- 5 files changed, 71 insertions(+), 41 deletions(-) diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl index 413ce85e..3fbe0b08 100644 --- a/helm/templates/_helpers.tpl +++ b/helm/templates/_helpers.tpl @@ -65,7 +65,26 @@ ServiceAccount name {{- define "open-git.serviceAccountName" -}} {{- if .Values.serviceAccount.name }} {{- .Values.serviceAccount.name }} -{{- else }} +{{- else if .Values.serviceAccount.create }} {{- include "open-git.fullname" . }} +{{- else }} +{{- "default" }} +{{- end }} +{{- end }} + +{{/* +Pod-level security context +*/}} +{{- define "open-git.podSecurityContext" -}} +runAsNonRoot: {{ .Values.securityContext.runAsNonRoot | default true }} +runAsUser: {{ .Values.securityContext.runAsUser | default 1000 }} +fsGroup: {{ .Values.securityContext.fsGroup | default (.Values.securityContext.runAsUser | default 1000) }} {{- end }} + +{{/* +Container-level security context +*/}} +{{- define "open-git.containerSecurityContext" -}} +allowPrivilegeEscalation: false +readOnlyRootFilesystem: true {{- end }} diff --git a/helm/templates/deployment.yaml b/helm/templates/deployment.yaml index 86da934b..e0e068ba 100644 --- a/helm/templates/deployment.yaml +++ b/helm/templates/deployment.yaml @@ -18,19 +18,21 @@ spec: app.kubernetes.io/component: backend spec: serviceAccountName: {{ include "open-git.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} imagePullSecrets: - {{- toYaml .Values.imagePullSecrets | nindent 8 }} + {{- toYaml . | nindent 8 }} + {{- end }} securityContext: - runAsNonRoot: true - runAsUser: 1000 - fsGroup: 1000 + {{- include "open-git.podSecurityContext" . | nindent 8 }} containers: - name: backend image: "{{ .Values.image.backend.repository }}:{{ .Values.image.backend.tag }}" imagePullPolicy: {{ .Values.image.backend.pullPolicy }} securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: false + {{- include "open-git.containerSecurityContext" . | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp ports: - name: http containerPort: 8080 @@ -104,6 +106,9 @@ spec: failureThreshold: 3 resources: {{- toYaml .Values.resources | nindent 12 }} + volumes: + - name: tmp + emptyDir: {} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} @@ -137,39 +142,25 @@ spec: app.kubernetes.io/component: frontend spec: serviceAccountName: {{ include "open-git.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} imagePullSecrets: - {{- toYaml .Values.imagePullSecrets | nindent 8 }} + {{- toYaml . | nindent 8 }} + {{- end }} securityContext: - runAsNonRoot: true - runAsUser: 1000 - fsGroup: 1000 + {{- include "open-git.podSecurityContext" . | nindent 8 }} containers: - name: frontend image: "{{ .Values.image.frontend.repository }}:{{ .Values.image.frontend.tag }}" imagePullPolicy: {{ .Values.image.frontend.pullPolicy }} securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: false + {{- include "open-git.containerSecurityContext" . | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp ports: - name: http containerPort: 3000 protocol: TCP - env: - - name: JWT_SECRET - valueFrom: - secretKeyRef: - name: {{ include "open-git.secretName" . }} - key: jwt-secret - - name: OAUTH_CLIENT_SECRET - valueFrom: - secretKeyRef: - name: {{ include "open-git.secretName" . }} - key: oauth-client-secret - - name: WEBHOOK_SECRET - valueFrom: - secretKeyRef: - name: {{ include "open-git.secretName" . }} - key: webhook-secret readinessProbe: httpGet: path: /readyz @@ -186,3 +177,6 @@ spec: failureThreshold: 3 resources: {{- toYaml .Values.resources | nindent 12 }} + volumes: + - name: tmp + emptyDir: {} diff --git a/helm/templates/rbac.yaml b/helm/templates/rbac.yaml index 438f3f93..295bf6bf 100644 --- a/helm/templates/rbac.yaml +++ b/helm/templates/rbac.yaml @@ -3,12 +3,24 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ include "open-git.fullname" . }} + namespace: {{ .Release.Namespace }} labels: {{- include "open-git.labels" . | nindent 4 }} rules: - apiGroups: [""] - resources: ["configmaps", "secrets"] - verbs: ["get", "list", "watch"] + resources: ["secrets"] + resourceNames: + - {{ include "open-git.secretName" . | quote }} + {{- if eq .Values.db.type "postgres" }} + - {{ printf "%s-db" (include "open-git.fullname" .) | quote }} + {{- end }} + {{- if .Values.minio.enabled }} + - {{ printf "%s-minio" (include "open-git.fullname" .) | quote }} + {{- end }} + verbs: ["get"] + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding diff --git a/helm/templates/secret.yaml b/helm/templates/secret.yaml index 86cab582..f4a0e756 100644 --- a/helm/templates/secret.yaml +++ b/helm/templates/secret.yaml @@ -10,10 +10,10 @@ metadata: type: Opaque data: {{- if $secret }} - db-password: {{ index $secret.data "db-password" }} - jwt-secret: {{ index $secret.data "jwt-secret" }} - oauth-client-secret: {{ index $secret.data "oauth-client-secret" }} - webhook-secret: {{ index $secret.data "webhook-secret" }} + db-password: {{ index $secret.data "db-password" | default (randAlphaNum 32 | b64enc) | quote }} + jwt-secret: {{ index $secret.data "jwt-secret" | default (randAlphaNum 32 | b64enc) | quote }} + oauth-client-secret: {{ index $secret.data "oauth-client-secret" | default (randAlphaNum 32 | b64enc) | quote }} + webhook-secret: {{ index $secret.data "webhook-secret" | default (randAlphaNum 32 | b64enc) | quote }} {{- else }} db-password: {{ randAlphaNum 32 | b64enc | quote }} jwt-secret: {{ randAlphaNum 32 | b64enc | quote }} diff --git a/helm/templates/worker-deployment.yaml b/helm/templates/worker-deployment.yaml index 32cd0f27..f311deb5 100644 --- a/helm/templates/worker-deployment.yaml +++ b/helm/templates/worker-deployment.yaml @@ -18,19 +18,21 @@ spec: app.kubernetes.io/component: worker spec: serviceAccountName: {{ include "open-git.serviceAccountName" . }} + {{- with .Values.imagePullSecrets }} imagePullSecrets: - {{- toYaml .Values.imagePullSecrets | nindent 8 }} + {{- toYaml . | nindent 8 }} + {{- end }} securityContext: - runAsNonRoot: true - runAsUser: 1000 - fsGroup: 1000 + {{- include "open-git.podSecurityContext" . | nindent 8 }} containers: - name: worker image: "{{ .Values.image.backend.repository }}:{{ .Values.image.backend.tag }}" imagePullPolicy: {{ .Values.image.backend.pullPolicy }} securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: false + {{- include "open-git.containerSecurityContext" . | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp args: - "--worker-only" env: @@ -81,6 +83,9 @@ spec: key: webhook-secret resources: {{- toYaml .Values.resources | nindent 12 }} + volumes: + - name: tmp + emptyDir: {} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }}