Skip to main content

Securing Outbound Email on Pantheon Drupal 10 with Symfony Mailer Lite + Pantheon Secrets

If you’re hosting Drupal on Pantheon and still using the old SMTP module, it’s time to modernize. By switching to Symfony Mailer Lite and leveraging Pantheon Secrets, you can keep mail relay credentials encrypted and completely out of your codebase.

Why the change

The old SMTP module had a simple UI but stored credentials in Drupal’s configuration—meaning anyone with access to the config files or repository could see the relay username and password in plain text.

About the MailSystem module

Drupal’s MailSystem module acts as a bridge between Drupal core and whatever mailer you use. It lets you define which plugin sends email (“sender”) and which formats it (“formatter”)—either globally or per module. In our setup, MailSystem routes all outgoing messages through Symfony Mailer Lite, replacing the legacy SMTP mailer. This layer keeps Drupal flexible: you can swap mail transports or add rerouting without changing any module code.

The new approach

We adopted a DSN-based configuration with Symfony Mailer Lite.
Instead of multiple fields, a single DSN string describes the SMTP connection, e.g.

smtp://USERNAME:PASSWORD@mail-relay.university.edu:25?encryption=starttls&auth_mode=login

Then we moved credentials out of configuration entirely:

if (function_exists('pantheon_get_secret') && ($dsn = pantheon_get_secret('MAILER_DSN'))) {
$config['symfony_mailer_lite.settings']['transports'] = ['relay' => ['dsn' => $dsn]];
$config['symfony_mailer_lite.settings']['default_transport'] = 'relay';
$config['symfony_mailer_lite.settings']['from_address'] = 'team@university.edu';
$config['symfony_mailer_lite.settings']['from_name'] = 'University Web Team'; }

From our settings.php :

if (function_exists('pantheon_get_secret') && ($dsn = pantheon_get_secret('MAILER_DSN'))) {
$config['mailsystem.settings']['defaults']['sender'] = 'symfony_mailer_lite';
$config['mailsystem.settings']['defaults']['formatter'] = 'symfony_mailer_lite';
$config['symfony_mailer_lite.settings']['default_transport'] = 'relay';
$parts = parse_url($dsn);
$query = [];
if (!empty($parts['query'])) {
parse_str($parts['query'], $query);
}
$config['symfony_mailer_lite.symfony_mailer_lite_transport.relay']['plugin'] = 'smtp';
$config['symfony_mailer_lite.symfony_mailer_lite_transport.relay']['configuration']['user'] = isset($parts['user']) ? rawurldecode($parts['user']) : '';   
$config['symfony_mailer_lite.symfony_mailer_lite_transport.relay']['configuration']['pass'] = isset($parts['pass']) ? rawurldecode($parts['pass']) : '';
$config['symfony_mailer_lite.symfony_mailer_lite_transport.relay']['configuration']['host'] = $parts['host'] ?? 'localhost';
$config['symfony_mailer_lite.symfony_mailer_lite_transport.relay']['configuration']['port'] = (string)($parts['port'] ?? '25');
$config['symfony_mailer_lite.symfony_mailer_lite_transport.relay']['configuration']['query'] = $query;
$config['symfony_mailer_lite.settings']['from_address'] = 'web@university.edu';
$config['symfony_mailer_lite.settings']['from_name'] = 'University Web Services';
}

The MAILER_DSN value itself is stored as a Pantheon Secret, managed through the Terminus CLI:

terminus secret:site:set <site> MAILER_DSN "smtp://ENCODED_USER:ENCODED_PASS@mail-relay.university.edu:25?encryption=starttls&auth_mode=login" --type=runtime --scope=web

Pantheon injects this at runtime, so no password ever appears in Git, the database, or exported configuration.
See the documentation for how to escape special characters used in passwords.

Testing with Terminus
terminus drush university.dev -- php:eval "\$p=['subject'=>'Symfony Lite Email Test','message'=>'Hello via Lite','context'=>[]]; \$r=\Drupal::service('plugin.manager.mail')->mail('system','test_mail','web_team@univestity.edu','en',\$p); var_export(\$r); echo PHP_EOL;"

Keeping test environments safe

We also re-enabled the Reroute Email module so Dev / Test sites can’t accidentally send mail to real users.
Our settings.php enforces it automatically:

 
if (!defined('PANTHEON_ENVIRONMENT') || PANTHEON_ENVIRONMENT !== 'live') {  $config['reroute_email.settings']['enable'] = TRUE;
$config['reroute_email.settings']['address'] = 'web_dev_team@university.edu';
$config['reroute_email.settings']['message'] = TRUE;
$config['reroute_email.settings']['description'] = TRUE; } else 
{  $config['reroute_email.settings']['enable'] = FALSE; }

Results

No plaintext passwords in config or Git.

Outbound mail now uses a DSN string pulled securely from Pantheon Secrets.

Panthoen Dev/Test environments safely reroute all email.

The mailer setup is ready for future Drupal 11 + Symfony Mailer core improvements.