From 3cbc9c1b5c3b5075b2c7388014bcfd1cfaf33728 Mon Sep 17 00:00:00 2001 From: Maidul Islam Date: Wed, 5 Jul 2023 17:54:29 -0400 Subject: [PATCH] update helm chart to include git app --- docker-compose.yml | 14 ++++ helm-charts/infisical/templates/_helpers.tpl | 28 ++++++++ helm-charts/infisical/templates/ingress.yaml | 7 ++ .../secret-scanning-git-app-deployment.yaml | 67 +++++++++++++++++++ helm-charts/infisical/values.yaml | 52 ++++++++++++++ nginx/default.conf | 14 ++++ secret-engine/Dockerfile.dev | 2 +- secret-engine/src/index.ts | 29 +++++--- 8 files changed, 204 insertions(+), 9 deletions(-) create mode 100644 helm-charts/infisical/templates/secret-scanning-git-app-deployment.yaml diff --git a/docker-compose.yml b/docker-compose.yml index 16f0bd128..bc1a24dd8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,6 +41,20 @@ services: networks: - infisical + secret-scanning-git-app: + container_name: infisical-secret-scanning-git-app + restart: unless-stopped + depends_on: + - backend + - frontend + - mongo + ports: + - "3000:3001" + image: infisical/staging_deployment_secret-scanning-git-app + env_file: .env + networks: + - infisical + mongo: container_name: infisical-mongo image: mongo diff --git a/helm-charts/infisical/templates/_helpers.tpl b/helm-charts/infisical/templates/_helpers.tpl index 500edea33..ac07d327c 100644 --- a/helm-charts/infisical/templates/_helpers.tpl +++ b/helm-charts/infisical/templates/_helpers.tpl @@ -51,6 +51,16 @@ component: {{ .Values.frontend.name | quote }} {{ include "infisical.common.matchLabels" . }} {{- end -}} +{{- define "infisical.secretScanningGitApp.labels" -}} +{{ include "infisical.secretScanningGitApp.matchLabels" . }} +{{ include "infisical.common.metaLabels" . }} +{{- end -}} + +{{- define "infisical.secretScanningGitApp.matchLabels" -}} +component: {{ .Values.secretScanningGitApp.name | quote }} +{{ include "infisical.common.matchLabels" . }} +{{- end -}} + {{- define "infisical.mongodb.labels" -}} {{ include "infisical.mongodb.matchLabels" . }} {{ include "infisical.common.metaLabels" . }} @@ -112,6 +122,24 @@ We truncate at 63 chars because some Kubernetes name fields are limited to this {{- end -}} {{- end -}} + +{{/* +Create a fully qualified secretScanningGitApp name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "infisical.secretScanningGitApp.fullname" -}} +{{- if .Values.secretScanningGitApp.fullnameOverride -}} +{{- .Values.secretScanningGitApp.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- printf "%s-%s" .Release.Name .Values.secretScanningGitApp.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s-%s" .Release.Name $name .Values.secretScanningGitApp.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + {{/* Create the mongodb connection string. */}} diff --git a/helm-charts/infisical/templates/ingress.yaml b/helm-charts/infisical/templates/ingress.yaml index a675fa2ff..c27703956 100644 --- a/helm-charts/infisical/templates/ingress.yaml +++ b/helm-charts/infisical/templates/ingress.yaml @@ -44,6 +44,13 @@ spec: name: {{ include "infisical.backend.fullname" . }} port: number: 4000 + - path: {{ $ingress.secretScanningGitApp.path }} + pathType: {{ $ingress.secretScanningGitApp.pathType }} + backend: + service: + name: {{ include "infisical.secretScanningGitApp.fullname" . }} + port: + number: 3001 {{- if $ingress.hostName }} host: {{ $ingress.hostName }} {{- end }} diff --git a/helm-charts/infisical/templates/secret-scanning-git-app-deployment.yaml b/helm-charts/infisical/templates/secret-scanning-git-app-deployment.yaml new file mode 100644 index 000000000..cc426049f --- /dev/null +++ b/helm-charts/infisical/templates/secret-scanning-git-app-deployment.yaml @@ -0,0 +1,67 @@ +{{- $secretScanningGitApp := .Values.secretScanningGitApp }} +{{- $backend := .Values.backend }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "infisical.secretScanningGitApp.fullname" . }} + annotations: + updatedAt: {{ now | date "2006-01-01 MST 15:04:05" | quote }} + {{- with $secretScanningGitApp.deploymentAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "infisical.secretScanningGitApp.labels" . | nindent 4 }} +spec: + replicas: {{ $secretScanningGitApp.replicaCount }} + selector: + matchLabels: + {{- include "infisical.secretScanningGitApp.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "infisical.secretScanningGitApp.matchLabels" . | nindent 8 }} + annotations: + updatedAt: {{ now | date "2006-01-01 MST 15:04:05" | quote }} + {{- with $secretScanningGitApp.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + containers: + - name: {{ template "infisical.name" . }}-{{ $secretScanningGitApp.name }} + image: "{{ $secretScanningGitApp.image.repository }}:{{ $secretScanningGitApp.image.tag | default "latest" }}" + imagePullPolicy: {{ $secretScanningGitApp.image.pullPolicy }} + readinessProbe: + httpGet: + path: / + port: 3000 + initialDelaySeconds: 10 + periodSeconds: 10 + ports: + - containerPort: 3000 + envFrom: + - secretRef: + name: {{ $backend.kubeSecretRef | default (include "infisical.backend.fullname" .) }} + +--- + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "infisical.secretScanningGitApp.fullname" . }} + labels: + {{- include "infisical.secretScanningGitApp.labels" . | nindent 4 }} + {{- with $secretScanningGitApp.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ $secretScanningGitApp.service.type }} + selector: + {{- include "infisical.secretScanningGitApp.matchLabels" . | nindent 8 }} + ports: + - protocol: TCP + port: 3001 + targetPort: 3000 # container port + {{- if eq $secretScanningGitApp.service.type "NodePort" }} + nodePort: {{ $secretScanningGitApp.service.nodePort }} + {{- end }} diff --git a/helm-charts/infisical/values.yaml b/helm-charts/infisical/values.yaml index a65f59223..ac9630389 100644 --- a/helm-charts/infisical/values.yaml +++ b/helm-charts/infisical/values.yaml @@ -169,6 +169,53 @@ backendEnvironmentVariables: ## MONGO_URL: "" +secretScanningGitApp: + ## @param backend.enabled Enable git scanning app + ## + enabled: true + ## @param backend.name Backend name + ## + name: secret-scanning-git-app + ## @param backend.fullnameOverride Backend fullnameOverride + ## + fullnameOverride: "" + ## @param backend.podAnnotations Backend pod annotations + ## + podAnnotations: {} + ## @param backend.deploymentAnnotations Backend deployment annotations + ## + deploymentAnnotations: {} + ## @param backend.replicaCount Backend replica count + ## + replicaCount: 2 + ## Backend image parameters + ## + image: + ## @param backend.image.repository Backend image repository + ## + repository: infisical/staging_deployment_secret-scanning-git-app + ## @param backend.image.tag Backend image tag + ## + tag: "latest" + ## @param backend.image.pullPolicy Backend image pullPolicy + ## + pullPolicy: IfNotPresent + ## @param backend.kubeSecretRef Backend secret resource reference name (containing required [backend configuration variables](https://infisical.com/docs/self-hosting/configuration/envars)) + ## + kubeSecretRef: "" + ## Backend service + ## + service: + ## @param backend.service.annotations Backend service annotations + ## + annotations: {} + ## @param backend.service.type Backend service type + ## + type: ClusterIP + ## @param backend.service.nodePort Backend service nodePort (used if above type is `NodePort`) + ## + nodePort: "" + ## @section MongoDB(®) parameters ## Documentation : https://github.com/bitnami/charts/blob/main/bitnami/mongodb/values.yaml ## @@ -327,6 +374,11 @@ ingress: backend: path: /api pathType: Prefix + ## @skip ingress.backend + ## + secretScanningGitApp: + path: /git-app-api + pathType: Prefix ## @param ingress.tls Ingress TLS hosts (matching above hostName) ## Replace with your own domain ## diff --git a/nginx/default.conf b/nginx/default.conf index 4c0e2434d..f824372be 100644 --- a/nginx/default.conf +++ b/nginx/default.conf @@ -15,6 +15,20 @@ server { proxy_cookie_path / "/; HttpOnly; SameSite=strict"; } + location /git-app-api { + proxy_set_header X-Real-RIP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + + proxy_pass http://git-app:3000/; + proxy_redirect off; + # proxy_redirect http://localhost:8080/ http://frontend.example.com/; + + proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict"; + } + location / { include /etc/nginx/mime.types; diff --git a/secret-engine/Dockerfile.dev b/secret-engine/Dockerfile.dev index b40ba2365..52745d9ce 100644 --- a/secret-engine/Dockerfile.dev +++ b/secret-engine/Dockerfile.dev @@ -10,4 +10,4 @@ RUN apt-get update && apt-get install -y bash curl && curl -1sLf \ && apt-get update && apt-get install -y infisical=0.8.1 -CMD [ "npm", "start" ] +CMD [ "npm", "run", "start:dev" ] diff --git a/secret-engine/src/index.ts b/secret-engine/src/index.ts index 067efcfac..09dfedd44 100644 --- a/secret-engine/src/index.ts +++ b/secret-engine/src/index.ts @@ -4,7 +4,7 @@ import { writeFile, readFile, rm, mkdir, } from "fs"; import { tmpdir } from "os"; import { join } from "path" import mongoose from "mongoose"; -import GitRisks from "./models/gitRisks"; +import GitRisks, { STATUS_RESOLVED_FALSE_POSITIVE } from "./models/gitRisks"; import GitAppOrganizationInstallation from "./models/gitAppOrganizationInstallation"; import { sendMail, setTransporter } from "./helper/nodemailer"; import { initSmtp } from "./service/smtp"; @@ -66,7 +66,7 @@ export = async (app: Probot) => { return } - const findingsByFingerprint: { [key: string]: SecretMatch; } = {} + const allFindingsByFingerprint: { [key: string]: SecretMatch; } = {} for (const commit of commits) { for (const filepath of [...commit.added, ...commit.modified]) { @@ -89,7 +89,7 @@ export = async (app: Probot) => { finding.File = filepath finding.Author = commit.author.name finding.Email = commit.author.email - findingsByFingerprint[fingerPrint] = finding + allFindingsByFingerprint[fingerPrint] = finding } } catch (error) { @@ -98,18 +98,27 @@ export = async (app: Probot) => { } } + + // change to update - for (const key in findingsByFingerprint) { - await GitRisks.findOneAndUpdate({ fingerprint: findingsByFingerprint[key].Fingerprint }, + const noneFalsePositiveFindings = {} + + for (const key in allFindingsByFingerprint) { + const risk = await GitRisks.findOneAndUpdate({ fingerprint: allFindingsByFingerprint[key].Fingerprint }, { - ...convertKeysToLowercase(findingsByFingerprint[key]), + ...convertKeysToLowercase(allFindingsByFingerprint[key]), installationId: installation.id, organization: installationLinkToOrgExists.organizationId, repositoryFullName: repository.full_name, repositoryId: repository.id }, { upsert: true - }) + }).lean() + + if (risk.status != STATUS_RESOLVED_FALSE_POSITIVE) { + noneFalsePositiveFindings[key] = { ...convertKeysToLowercase(allFindingsByFingerprint[key]) } + } + } // get emails of admins const adminsOfWork = await MembershipOrg.find({ @@ -128,12 +137,16 @@ export = async (app: Probot) => { const adminOrOwnerEmails = userEmails.map(userObject => userObject.email) + + // TODO + // don't notify if the risk is marked as false positive + await sendMail({ template: "secretLeakIncident.handlebars", subjectLine: `Incident alert: leaked secrets found in Github repository ${repository.full_name}`, recipients: [pusher.email, ...adminOrOwnerEmails], substitutions: { - numberOfSecrets: Object.keys(findingsByFingerprint).length, + numberOfSecrets: Object.keys(allFindingsByFingerprint).length, pusher_email: pusher.email, pusher_name: pusher.name }