How to Configure SMTP for Notifications in OpenCTI: Complete Setup Guide

Configure SMTP in OpenCTI by setting environment variables such as SMTP__HOSTNAME, SMTP__PORT, and SMTP__USERNAME in your Docker Compose or .env file, which the platform uses to initialize a nodemailer transport in src/database/smtp.js for sending password resets and ingestion alerts.

OpenCTI relies on a centralized SMTP transport layer to deliver critical email notifications, including user password resets and automated ingestion alerts. The platform implements this functionality using nodemailer within the src/database/smtp.js module, reading configuration parameters from environment variables during the initialization process defined in src/initialization.js.

Understanding the SMTP Architecture in OpenCTI

Core SMTP Transport Layer (src/database/smtp.js)

The core SMTP logic resides in src/database/smtp.js, where the smtpOptions object is assembled from environment variables (lines 15-25). This configuration object is passed to nodemailer's createTransport method to establish the connection. The module exports sendMail(), which wraps the native nodemailer method and records metrics via MeterManager (lines 59-65).

Startup Health Verification (src/initialization.js)

During platform startup, src/initialization.js invokes smtpIsAlive() (lines 53-55) to verify SMTP connectivity before marking the service as ready. If the check fails, the logs display "SMTP seems down, e-mail notification may not work" (lines 48-55 in smtp.js), alerting administrators to configuration errors.

Environment Variables for SMTP Configuration

OpenCTI uses double-underscore notation to map environment variables to nested configuration keys. The following variables control the SMTP transport:

  • SMTP__HOSTNAME – SMTP server hostname (default: localhost)
  • SMTP__PORT – Server port (default: 25)
  • SMTP__USE_SSL – Enable TLS/SSL (default: false)
  • SMTP__REJECT_UNAUTHORIZED – Reject unauthorized certificates (default: true)
  • SMTP__USERNAME – Authentication username
  • SMTP__PASSWORD – Authentication password
  • SMTP__ENABLED – Master toggle for SMTP functionality (default: true)
  • SMTP__FORCED_SENDER_EMAIL – Override all sender addresses (optional)

Step-by-Step SMTP Configuration Guide

Configure Basic SMTP Connectivity

Set the required environment variables in your Docker Compose file or .env file. For a typical TLS configuration on port 587:

SMTP__HOSTNAME=smtp.mailgun.org
SMTP__PORT=587
SMTP__USE_SSL=false
SMTP__REJECT_UNAUTHORIZED=true
SMTP__USERNAME=postmaster@mydomain.com
SMTP__PASSWORD=your_secure_password
SMTP__ENABLED=true

Set a Forced Sender Email Address

To ensure all notifications originate from a single address regardless of UI settings, configure the forced sender option. In src/database/smtp.js (lines 9-12, 36-38), setting SMTP__FORCED_SENDER_EMAIL disables the ALLOW_EMAIL_REWRITE flag and forces smtpConfiguredEmail() to return the specified value.

SMTP__FORCED_SENDER_EMAIL=security-alerts@myorg.com

Configure Platform Email in the UI

When not using a forced sender, administrators can set the default sender address via the web interface. Navigate to Settings → Platform → Platform email to define the address used by smtpComputeFrom() (lines 40-46 in src/database/smtp.js) when constructing the From: header.

Verify SMTP Connectivity

After restarting the platform, monitor the startup logs for the "SMTP alive" message generated by smtpIsAlive() in src/initialization.js (lines 53-55). Alternatively, use the test functionality in Settings → Platform by entering an address in the "Test e-mail address" field and clicking the test button, which invokes the GraphQL settingsTestMail mutation.

Sending Custom Notifications Programmatically

Developers building connectors or custom scripts can leverage the sendMail function exported from src/database/smtp.js. The function accepts a nodemailer-compatible mail object and an optional metrics context.

import { sendMail, smtpComputeFrom } from '../../src/database/smtp.js';

// Build the email payload
const buildMail = async (to, subject, html) => ({
  from: await smtpComputeFrom('OpenCTI Connector'),
  to,
  subject,
  html,
});

// Example usage inside a connector
const notifyUser = async (userEmail, indicatorName) => {
  const mail = await buildMail(
    userEmail,
    'New Indicator Ingestion',
    `<p>The indicator <strong>${indicatorName}</strong> has been ingested.</p>`
  );
  await sendMail(mail, { name: 'custom_ingestion_alert' });
};

Troubleshooting Common SMTP Issues

  • Connection timeouts: Verify that SMTP__HOSTNAME and SMTP__PORT match your provider's settings. For port 587, set SMTP__USE_SSL=false to allow STARTTLS negotiation.
  • Authentication failures: Ensure SMTP__USERNAME and SMTP__PASSWORD are correctly encoded without quotes in the environment file.
  • Certificate errors: Set SMTP__REJECT_UNAUTHORIZED=false only in development environments to bypass self-signed certificate validation.
  • Forced email not applied: Check that SMTP__FORCED_SENDER_EMAIL is set as an environment variable; the configuration file config/default.json entry smtp:forced_sender_email is also valid but environment variables take precedence in containerized deployments.

Summary

  • OpenCTI uses nodemailer in src/database/smtp.js to manage SMTP connections and send notifications.
  • Configuration is driven by environment variables using double-underscore notation (e.g., SMTP__HOSTNAME, SMTP__PORT).
  • The forced sender email (SMTP__FORCED_SENDER_EMAIL) overrides all UI settings and ensures consistent sender addresses.
  • Health checks occur during startup in src/initialization.js via smtpIsAlive().
  • Developers can import sendMail and smtpComputeFrom from src/database/smtp.js to send custom notifications from connectors.

Frequently Asked Questions

What environment variables are required to configure SMTP in OpenCTI?

At minimum, you must set SMTP__HOSTNAME and SMTP__PORT to define the server endpoint. If authentication is required, provide SMTP__USERNAME and SMTP__PASSWORD. For TLS configurations, set SMTP__USE_SSL=true (port 465) or false with SMTP__REJECT_UNAUTHORIZED for STARTTLS on port 587.

How do I set a fixed sender email address for all OpenCTI notifications?

Set the SMTP__FORCED_SENDER_EMAIL environment variable (or smtp:forced_sender_email in config/default.json). According to the source code in src/database/smtp.js (lines 9-12, 36-38), this disables the ALLOW_EMAIL_REWRITE flag and forces every notification to use the specified address, overriding any UI-configured platform email.

Where does OpenCTI verify SMTP connectivity during startup?

The platform calls smtpIsAlive() from src/database/smtp.js during the initialization sequence defined in src/initialization.js (lines 53-55). This health check verifies that the nodemailer transport can reach the configured SMTP server before the platform finishes booting, logging "SMTP alive" on success or a warning if the server is unreachable.

Can I send custom email notifications from an OpenCTI connector?

Yes. Import sendMail and smtpComputeFrom from src/database/smtp.js in your connector code. Build a nodemailer-compatible mail object with from, to, subject, and html fields, then call await sendMail(mail, { name: 'metric_name' }). The function handles the transport connection and records metrics automatically, as implemented in lines 59-65 of src/database/smtp.js.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →