Skip to content

Commit

Permalink
BACK-2077, BACK-2335: add abac inbound mode and simplify charts (#175)
Browse files Browse the repository at this point in the history
* Add `inbound abac-encrypt` and `outbound abac-decrypt` modes
* Only include secrets, and config values if they will wind up in a chart
* Pull the CAs back into the base chart so that they can be referenced by both ABAC charts
  • Loading branch information
mkleene authored Oct 30, 2024
1 parent ce70ad2 commit 08db98e
Show file tree
Hide file tree
Showing 27 changed files with 511 additions and 108 deletions.
Binary file added gateway-2.3.0.tgz
Binary file not shown.
4 changes: 2 additions & 2 deletions gateway/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ apiVersion: v2
name: gateway
description: A Helm chart for Kubernetes
type: application
version: 2.2.2
appVersion: v2.53.0
version: 2.3.0
appVersion: v2.54.0
8 changes: 8 additions & 0 deletions gateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,14 @@ A full list of Virtru-specific variables in `values.yaml` can be found below:
| `cacheSmtpConnections.connectionCacheTimeLimit` | `GATEWAY_SMTP_CONNECTION_CACHE_TIME_LIMIT` |
| `dkimSigning.enabled` | N/A, toggles on `GATEWAY_DKIM_DOMAINS` |
| `dkimSigning.selector` | Generates the subdomain for `GATEWAY_DKIM_DOMAINS` (`<dkimSigning.selector>._domainkey.primaryMailingDomain`)
| `abac.oidcClientId` | The client id that gateway should use to communicate with the DSP platform. |
| `abac.platformEndpoint` | The endpoint where the DSP platform is deployed. |
| `abac.taggingPdpEndpoint` | The endpoint where the tagging PDP is deployed. |
| `abac.taggingPdpAssertionType` | The assertion type to use with the tagging pdp; either `urn:us:gov:ic:ed` or `urn:nato:stanag:5636:A:1:elements:json`. |
| `abac.trimBlockedRecipients` | Whether we should remove header recipients that are not entitled to receive an email. |
| `abac.plaintextConnection` | Whether we should communicate with the platform and the tagging PDP over a plaintext connection. |
| `abac.encryptEmail` | Whether we should encrypt all email sent through this mode. |
| `abac.extraCas` | A list of extra CAs to trust. Usually the cert for the DSP platform. |

### `inboundRelayAddresses` values for Gmail and Office 365

Expand Down
11 changes: 11 additions & 0 deletions gateway/templates/configmap-abac-ie.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{- if .Values.gatewayModes.inboundAbacEncrypt.enabled }}
kind: ConfigMap
apiVersion: v1
metadata:
labels:
app: gateway
name: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
data:
GATEWAY_MODE: "abac-encrypt"
GATEWAY_TOPOLOGY: "inbound"
{{- end }}
11 changes: 11 additions & 0 deletions gateway/templates/configmap-abac-od.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{- if .Values.gatewayModes.outboundAbacDecrypt.enabled }}
kind: ConfigMap
apiVersion: v1
metadata:
labels:
app: gateway
name: {{ .Chart.Name }}-{{ .Values.gatewayModes.outboundAbacDecrypt.name }}
data:
GATEWAY_MODE: "abac-decrypt"
GATEWAY_TOPOLOGY: "outbound"
{{- end }}
20 changes: 14 additions & 6 deletions gateway/templates/configmap-base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,24 @@ data:
GATEWAY_PROXY_PROTOCOL: {{ .Values.additionalConfig.proxyProtocol | quote }}
GATEWAY_VERBOSE_LOGGING: {{ .Values.additionalConfig.verboseLogging | quote }}
GATEWAY_DLP_CACHE_DURATION: {{ .Values.additionalConfig.dlpRuleCache | quote }}
{{- if eq .Values.additionalConfig.abac.enabled true }}
{{- if or .Values.gatewayModes.outboundAbacDecrypt.enabled .Values.gatewayModes.inboundAbacEncrypt.enabled }}
# ABAC operation. Get tags from the tagging service and access decisions from the access service
GATEWAY_ABAC_OIDC_CLIENT_ID: {{ .Values.additionalConfig.abac.oidcClientId | quote }}
GATEWAY_ABAC_PLATFORM_ENDPOINT: {{ .Values.additionalConfig.abac.platformEndpoint | quote }}
GATEWAY_ABAC_TAGGING_PDP_ENDPOINT: {{ .Values.additionalConfig.abac.taggingPdpEndpoint | quote }}
GATEWAY_ABAC_OIDC_CLIENT_ID: {{ .Values.additionalConfig.abac.oidcClientId }}
GATEWAY_ABAC_PLATFORM_ENDPOINT: {{ .Values.additionalConfig.abac.platformEndpoint }}
GATEWAY_ABAC_TAGGING_PDP_ENDPOINT: {{ .Values.additionalConfig.abac.taggingPdpEndpoint }}
GATEWAY_ABAC_TRIM_BLOCKED_RECIPIENTS: {{ .Values.additionalConfig.abac.trimBlockedRecipients | quote }}
GATEWAY_ABAC_PLAINTEXT_CONNECTION: {{ .Values.additionalConfig.abac.plaintextConnection | quote }}
GATEWAY_ABAC_ENCRYPT_EMAIL: {{ .Values.additionalConfig.abac.encryptEmail | quote }}
GATEWAY_ABAC_TAGGING_PDP_ASSERTION_TYPE: {{ .Values.additionalConfig.abac.taggingPdpAssertionType | quote }}
{{- else }}
GATEWAY_ABAC_TAGGING_PDP_ASSERTION_TYPE: {{ .Values.additionalConfig.abac.taggingPdpAssertionType }}
{{- if .Values.additionalConfig.abac.extraCas }}
GATEWAY_ABAC_SDK_TRUSTED_CERT_DIRECTORY: /etc/virtru-gateway/abac-cas
{{- range $index, $value := .Values.additionalConfig.abac.extraCas }}
ABAC_CA_{{ $index }}: {{ toJson $value }}
{{- end }}
{{- end }}
{{- end }}
{{- if or .Values.gatewayModes.outboundEncrypt.enabled .Values.gatewayModes.inboundEncrypt.enabled
.Values.gatewayModes.outboundDecrypt.enabled .Values.gatewayModes.inboundDecrypt.enabled .Values.gatewayModes.outboundDlp.enabled }}
# normal DLP/Encryption operation. get settings and DLP rules from gateway accounts services and create policies using ACM
GATEWAY_ACCOUNTS_URL: {{ .Values.gatewayAccountsUrl }}
GATEWAY_ACM_URL: {{ .Values.gatewayAcmUrl }}
Expand Down
6 changes: 0 additions & 6 deletions gateway/templates/configmap-dlpout.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,4 @@ metadata:
data:
GATEWAY_MODE: "dlp"
GATEWAY_TOPOLOGY: "outbound"
{{- if .Values.additionalConfig.abac.extraCas }}
GATEWAY_ABAC_SDK_TRUSTED_CERT_DIRECTORY: /etc/virtru-gateway/abac-cas
{{- end }}
{{- range $index, $value := .Values.additionalConfig.abac.extraCas }}
ABAC_CA_{{ $index }}: {{ toJson $value }}
{{- end }}
{{- end }}
2 changes: 1 addition & 1 deletion gateway/templates/configmap-id.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.gatewayModes.inboundDecrypt.enabled (not .Values.additionalConfig.abac.enabled) }}
{{- if .Values.gatewayModes.inboundDecrypt.enabled }}
kind: ConfigMap
apiVersion: v1
metadata:
Expand Down
2 changes: 1 addition & 1 deletion gateway/templates/configmap-ie.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.gatewayModes.inboundEncrypt.enabled (not .Values.additionalConfig.abac.enabled) }}
{{- if .Values.gatewayModes.inboundEncrypt.enabled }}
kind: ConfigMap
apiVersion: v1
metadata:
Expand Down
2 changes: 1 addition & 1 deletion gateway/templates/configmap-od.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.gatewayModes.outboundDecrypt.enabled (not .Values.additionalConfig.abac.enabled) }}
{{- if .Values.gatewayModes.outboundDecrypt.enabled }}
kind: ConfigMap
apiVersion: v1
metadata:
Expand Down
2 changes: 1 addition & 1 deletion gateway/templates/configmap-oe.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.gatewayModes.outboundEncrypt.enabled (not .Values.additionalConfig.abac.enabled) }}
{{- if .Values.gatewayModes.outboundEncrypt.enabled }}
kind: ConfigMap
apiVersion: v1
metadata:
Expand Down
7 changes: 7 additions & 0 deletions gateway/templates/secret.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ data:
{{- if eq .Values.additionalConfig.saslAuth.smtpDownstream.enabled true }}
gateway-sasl-auth-downstream: {{ .Values.appSecrets.saslAuth.smtpDownstream.accounts | b64enc | quote }}
{{- end }}
{{- if or .Values.gatewayModes.outboundAbacDecrypt.enabled .Values.gatewayModes.inboundAbacEncrypt.enabled }}
# include these if we are in ABAC mode
gateway-abac-oidc-client-secret: {{ .Values.appSecrets.abac.oidcClientSecret | b64enc | quote }}
{{- end }}
{{- if or .Values.gatewayModes.outboundEncrypt.enabled .Values.gatewayModes.inboundEncrypt.enabled
.Values.gatewayModes.outboundDecrypt.enabled .Values.gatewayModes.inboundDecrypt.enabled .Values.gatewayModes.outboundDlp.enabled }}
# include these if we are using a mode that needs to talk to Virtru SaaS
gateway-api-token-name: {{ .Values.appSecrets.gatewayApiTokenName | b64enc | quote }}
gateway-api-token-secret: {{ .Values.appSecrets.gatewayApiSecret | b64enc | quote }}
{{- end }}
26 changes: 26 additions & 0 deletions gateway/templates/service-abac-ie.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{- if .Values.gatewayModes.inboundAbacEncrypt.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
labels:
{{- include "gateway.labels" . | nindent 4 }}
app.kubernetes.io/name: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
app.kubernetes.io/instance: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
{{- if .Values.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
{{- end }}
ports:
- port: {{ .Values.gatewayModes.inboundAbacEncrypt.port }}
targetPort: {{ .Values.service.port }}
protocol: TCP
selector:
app.kubernetes.io/name: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
app.kubernetes.io/instance: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
{{- end }}
26 changes: 26 additions & 0 deletions gateway/templates/service-abac-od.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{- if .Values.gatewayModes.outboundAbacDecrypt.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ .Chart.Name }}-{{ .Values.gatewayModes.outboundAbacDecrypt.name }}
labels:
{{- include "gateway.labels" . | nindent 4 }}
app.kubernetes.io/name: {{ .Chart.Name }}-{{ .Values.gatewayModes.outboundAbacDecrypt.name }}
app.kubernetes.io/instance: {{ .Chart.Name }}-{{ .Values.gatewayModes.outboundAbacDecrypt.name }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
{{- if .Values.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
{{- end }}
ports:
- port: {{ .Values.gatewayModes.outboundAbacDecrypt.port }}
targetPort: {{ .Values.service.port }}
protocol: TCP
selector:
app.kubernetes.io/name: {{ .Chart.Name }}-{{ .Values.gatewayModes.outboundAbacDecrypt.name }}
app.kubernetes.io/instance: {{ .Chart.Name }}-{{ .Values.gatewayModes.outboundAbacDecrypt.name }}
{{- end }}
2 changes: 1 addition & 1 deletion gateway/templates/service-id.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.gatewayModes.inboundDecrypt.enabled (not .Values.additionalConfig.abac.enabled) }}
{{- if .Values.gatewayModes.inboundDecrypt.enabled }}
apiVersion: v1
kind: Service
metadata:
Expand Down
2 changes: 1 addition & 1 deletion gateway/templates/service-ie.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.gatewayModes.inboundEncrypt.enabled (not .Values.additionalConfig.abac.enabled) }}
{{- if .Values.gatewayModes.inboundEncrypt.enabled }}
apiVersion: v1
kind: Service
metadata:
Expand Down
2 changes: 1 addition & 1 deletion gateway/templates/service-od.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.gatewayModes.outboundDecrypt.enabled (not .Values.additionalConfig.abac.enabled) }}
{{- if .Values.gatewayModes.outboundDecrypt.enabled }}
apiVersion: v1
kind: Service
metadata:
Expand Down
2 changes: 1 addition & 1 deletion gateway/templates/service-oe.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- if and .Values.gatewayModes.outboundEncrypt.enabled (not .Values.additionalConfig.abac.enabled) }}
{{- if .Values.gatewayModes.outboundEncrypt.enabled }}
apiVersion: v1
kind: Service
metadata:
Expand Down
159 changes: 159 additions & 0 deletions gateway/templates/workload-abac-ie.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
{{- if .Values.gatewayModes.inboundAbacEncrypt.enabled }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
labels:
{{- include "gateway.labels" . | nindent 4 }}
app.kubernetes.io/name: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
app.kubernetes.io/instance: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
spec:
selector:
matchLabels:
app.kubernetes.io/name: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
app.kubernetes.io/instance: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
serviceName: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
replicas: {{ .Values.replicas }}
volumeClaimTemplates:
- metadata:
name: postfix-dir
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: {{ .Values.persistentVolumes.storageClassName }}
resources:
requests:
storage: {{ .Values.persistentVolumes.volumeSize }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
app.kubernetes.io/name: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
app.kubernetes.io/instance: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
spec:
{{- with .Values.imagePullSecrets }}
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "gateway.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
initContainers:
- name: cert-generator
image: alpine:latest
# todo move this into a bash script? or remove apk add bash from the below line
command: ['sh', '-c', "apk update && apk upgrade && apk add bash openssl && openssl genrsa -out /etc/postfix/tls/{{ .Values.standardConfig.gatewayHostname }}/client.key 2048 && openssl req -new -key /etc/postfix/tls/{{ .Values.standardConfig.gatewayHostname }}/client.key -x509 -subj /CN={{ .Values.standardConfig.gatewayHostname }} -days 3650 -out /etc/postfix/tls/{{ .Values.standardConfig.gatewayHostname }}/client.pem"]
volumeMounts:
- name: cert-dir
mountPath: /etc/postfix/tls/{{ .Values.standardConfig.gatewayHostname }}
containers:
- name: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }} # Gateway Container
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
volumeMounts:
- name: cert-dir
mountPath: /etc/postfix/tls/{{ .Values.standardConfig.gatewayHostname }}
{{- if eq .Values.additionalConfig.dkimSigning.enabled true }}
- name: dkim-dir
mountPath: /etc/opendkim/keys
{{- end }}
{{- if .Values.additionalConfig.abac.extraCas }}
- name: abac-cas
mountPath: /etc/virtru-gateway/abac-cas
readOnly: true
{{- end }}
- name: postfix-dir
mountPath: /var/spool/postfix
ports:
- containerPort: {{ .Values.service.port }}
protocol: TCP
envFrom:
- configMapRef:
name: {{ .Chart.Name }}-{{ .Values.gatewayModes.inboundAbacEncrypt.name }}
- configMapRef:
name: {{ .Chart.Name }}-base-configs
env:
- name: GATEWAY_AMPLITUDE_API_KEY
valueFrom:
secretKeyRef:
key: gateway-amplitude-api-key
name: {{ .Release.Name }}-secrets
{{- if eq .Values.additionalConfig.saslAuth.smtpDownstream.enabled true }}
- name: GATEWAY_SMTP_SASL_ACCOUNTS
valueFrom:
secretKeyRef:
key: gateway-sasl-auth-downstream
name: {{ .Release.Name }}-secrets
{{- end }}
{{- if eq .Values.additionalConfig.saslAuth.smtpdUpstream.enabled true }}
- name: GATEWAY_SMTPD_SASL_ACCOUNTS
valueFrom:
secretKeyRef:
key: gateway-sasl-auth-upstream
name: {{ .Release.Name }}-secrets
{{- end }}
{{- if eq .Values.standardConfig.headers.xHeaderAuthEnabled true }}
- name: GATEWAY_XHEADER_AUTH_SECRET
valueFrom:
secretKeyRef:
key: gateway-xheader-auth-secret
name: {{ .Release.Name }}-secrets
{{- end }}
- name: GATEWAY_ABAC_OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
key: gateway-abac-oidc-client-secret
name: {{ .Release.Name }}-secrets
readinessProbe:
tcpSocket:
port: 25
initialDelaySeconds: 30
periodSeconds: 5
successThreshold: 1
failureThreshold: 3
timeoutSeconds: 20
livenessProbe:
tcpSocket:
port: 25
initialDelaySeconds: 60
periodSeconds: 5
successThreshold: 1
failureThreshold: 2
timeoutSeconds: 60
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
{{- if .Values.additionalConfig.abac.extraCas }}
- name: abac-cas
configMap:
name: {{ .Chart.Name }}-base-configs
items:
{{- range $index, $unused := .Values.additionalConfig.abac.extraCas }}
- key: ABAC_CA_{{ $index }}
path: abac-ca-{{ $index }}.crt
{{- end }}
{{- end }}
- name: cert-dir
emptyDir: {}
{{- if eq .Values.additionalConfig.dkimSigning.enabled true }}
- name: dkim-dir
secret:
defaultMode: 420
secretName: {{ .Release.Name }}-dkim-secrets
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
Loading

0 comments on commit 08db98e

Please sign in to comment.