diff --git a/infrastructure/environments/common/configs/configmap.yaml b/infrastructure/environments/common/configs/configmap.yaml index 148f45f4..1d5b7513 100644 --- a/infrastructure/environments/common/configs/configmap.yaml +++ b/infrastructure/environments/common/configs/configmap.yaml @@ -176,9 +176,12 @@ data: # ================================================================ # EMAIL CONFIGURATION # ================================================================ - SMTP_HOST: "mailu-postfix.bakery-ia.svc.cluster.local" + # Use mailu-front port 25 for internal relay (no auth needed from trusted subnet) + # Mailu is configured with subnet: "10.1.0.0/16" which allows unauthenticated relay + # TLS is disabled because Mailu is configured with TLS_FLAVOR: "notls" + SMTP_HOST: "mailu-front.bakery-ia.svc.cluster.local" SMTP_PORT: "25" - SMTP_TLS: "true" + SMTP_TLS: "false" SMTP_SSL: "false" DEFAULT_FROM_EMAIL: "noreply@bakewise.ai" DEFAULT_FROM_NAME: "Bakery-Forecast" diff --git a/infrastructure/platform/security/network-policies/allow-notification-to-mailu.yaml b/infrastructure/platform/security/network-policies/allow-notification-to-mailu.yaml index bc9092b4..efceccf4 100644 --- a/infrastructure/platform/security/network-policies/allow-notification-to-mailu.yaml +++ b/infrastructure/platform/security/network-policies/allow-notification-to-mailu.yaml @@ -1,8 +1,9 @@ # Network Policy to allow notification service to send emails via Mailu -# This policy allows egress from notification-service to mailu-postfix on SMTP ports +# This policy allows egress from notification-service to mailu-front on SMTP port 25 # -# NOTE: Postfix only listens on port 25 (and 10025 internally), NOT 587 -# Port 587 (submission) is handled by mailu-front which proxies to postfix +# NOTE: Mailu is configured with TLS_FLAVOR: "notls" and subnet: "10.1.0.0/16" +# This allows unauthenticated relay from trusted pod network on port 25 +# mailu-front (nginx) handles SMTP and proxies to postfix internally apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: @@ -19,19 +20,17 @@ spec: policyTypes: - Egress egress: - # Allow SMTP traffic to mailu-postfix (port 25) + # Allow SMTP traffic to mailu-front (port 25, no TLS) - to: - podSelector: matchLabels: app.kubernetes.io/instance: mailu - app.kubernetes.io/component: postfix + app.kubernetes.io/component: front ports: - port: 25 protocol: TCP - - port: 10025 - protocol: TCP --- -# Allow ingress TO mailu-postfix FROM any pod in bakery-ia namespace +# Allow ingress TO mailu-front FROM any pod in bakery-ia namespace # This is needed because mailu-allow-internal only allows traffic from mailu pods apiVersion: networking.k8s.io/v1 kind: NetworkPolicy @@ -46,7 +45,7 @@ spec: podSelector: matchLabels: app.kubernetes.io/instance: mailu - app.kubernetes.io/component: postfix + app.kubernetes.io/component: front policyTypes: - Ingress ingress: @@ -58,5 +57,3 @@ spec: ports: - port: 25 protocol: TCP - - port: 10025 - protocol: TCP diff --git a/services/notification/app/services/email_service.py b/services/notification/app/services/email_service.py index 5422f57d..3c297ed6 100644 --- a/services/notification/app/services/email_service.py +++ b/services/notification/app/services/email_service.py @@ -72,9 +72,7 @@ class EmailService: logger.info("Email notifications disabled") return True # Return success to avoid blocking workflow - if not self.smtp_user or not self.smtp_password: - logger.error("SMTP credentials not configured") - return False + # Note: Authentication is optional for trusted relay (e.g., internal Mailu with subnet trust) # Validate email address if not to_email or "@" not in to_email: @@ -270,34 +268,28 @@ class EmailService: if not settings.ENABLE_EMAIL_NOTIFICATIONS: return True # Service is "healthy" if disabled - if not self.smtp_user or not self.smtp_password: - logger.warning("SMTP credentials not configured") - return False - # Test SMTP connection if self.smtp_ssl: # Use implicit TLS/SSL connection (port 465 typically) server = aiosmtplib.SMTP(hostname=self.smtp_host, port=self.smtp_port, use_tls=True) await server.connect() - # No need for starttls() when using implicit TLS else: # Use plain connection, optionally upgrade with STARTTLS server = aiosmtplib.SMTP(hostname=self.smtp_host, port=self.smtp_port) await server.connect() - + if self.smtp_tls: - # Try STARTTLS, but handle case where connection is already secure try: await server.starttls() except Exception as starttls_error: - # If STARTTLS fails because connection is already using TLS, that's okay if "already using TLS" in str(starttls_error) or "already secure" in str(starttls_error): logger.debug("SMTP connection already secure, skipping STARTTLS") else: - # Re-raise other STARTTLS errors raise starttls_error - - await server.login(self.smtp_user, self.smtp_password) + + # Login only if credentials are provided (optional for trusted relay) + if self.smtp_user and self.smtp_password: + await server.login(self.smtp_user, self.smtp_password) await server.quit() logger.info("Email service health check passed") @@ -335,8 +327,9 @@ class EmailService: if self.smtp_tls and not self.smtp_ssl: await server.starttls() - # Login - await server.login(self.smtp_user, self.smtp_password) + # Login only if credentials are provided (optional for trusted relay) + if self.smtp_user and self.smtp_password: + await server.login(self.smtp_user, self.smtp_password) # Send email await server.send_message(message, from_addr=from_email, to_addrs=[to_email])