diff --git a/resources/sql/autopatches/20150602.mlist.1.sql b/resources/sql/autopatches/20150602.mlist.1.sql
new file mode 100644
index 0000000000..5479b972a6
--- /dev/null
+++ b/resources/sql/autopatches/20150602.mlist.1.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_user.user
+  ADD isMailingList BOOL NOT NULL;
diff --git a/scripts/ssh/ssh-exec.php b/scripts/ssh/ssh-exec.php
index 0eb9b4a3ad..0426a30825 100755
--- a/scripts/ssh/ssh-exec.php
+++ b/scripts/ssh/ssh-exec.php
@@ -182,11 +182,11 @@ try {
       'P' => $user->getPHID(),
     ));
 
-  if (!$user->isUserActivated()) {
+  if (!$user->canEstablishSSHSessions()) {
     throw new Exception(
       pht(
-        'Your account ("%s") is not activated. Visit the web interface '.
-        'for more information.',
+        'Your account ("%s") does not have permission to establish SSH '.
+        'sessions. Visit the web interface for more information.',
         $user->getUsername()));
   }
 
diff --git a/scripts/user/account_admin.php b/scripts/user/account_admin.php
index dc1cb50190..2fa5446648 100755
--- a/scripts/user/account_admin.php
+++ b/scripts/user/account_admin.php
@@ -125,7 +125,7 @@ if (strlen($password)) {
 
 $is_system_agent = $user->getIsSystemAgent();
 $set_system_agent = phutil_console_confirm(
-  pht('Is this user a bot/script?'),
+  pht('Is this user a bot?'),
   $default_no = !$is_system_agent);
 
 $verify_email = null;
@@ -165,7 +165,7 @@ printf($tpl, pht('Password'), null,
 
 printf(
   $tpl,
-  pht('Bot/Script'),
+  pht('Bot'),
   $original->getIsSystemAgent() ? 'Y' : 'N',
   $set_system_agent ? 'Y' : 'N');
 
diff --git a/src/applications/auth/engine/PhabricatorAuthSessionEngine.php b/src/applications/auth/engine/PhabricatorAuthSessionEngine.php
index 3d030769da..cec965f6b5 100644
--- a/src/applications/auth/engine/PhabricatorAuthSessionEngine.php
+++ b/src/applications/auth/engine/PhabricatorAuthSessionEngine.php
@@ -158,6 +158,21 @@ final class PhabricatorAuthSessionEngine extends Phobject {
         $session_dict[substr($key, 2)] = $value;
       }
     }
+
+    $user = $user_table->loadFromArray($info);
+    switch ($session_type) {
+      case PhabricatorAuthSession::TYPE_WEB:
+        // Explicitly prevent bots and mailing lists from establishing web
+        // sessions. It's normally impossible to attach authentication to these
+        // accounts, and likewise impossible to generate sessions, but it's
+        // technically possible that a session could exist in the database. If
+        // one does somehow, refuse to load it.
+        if (!$user->canEstablishWebSessions()) {
+          return null;
+        }
+        break;
+    }
+
     $session = id(new PhabricatorAuthSession())->loadFromArray($session_dict);
 
     $ttl = PhabricatorAuthSession::getSessionTypeTTL($session_type);
@@ -181,7 +196,6 @@ final class PhabricatorAuthSessionEngine extends Phobject {
       unset($unguarded);
     }
 
-    $user = $user_table->loadFromArray($info);
     $user->attachSession($session);
     return $user;
   }
diff --git a/src/applications/conduit/controller/PhabricatorConduitAPIController.php b/src/applications/conduit/controller/PhabricatorConduitAPIController.php
index 477ecdd990..cdef93919a 100644
--- a/src/applications/conduit/controller/PhabricatorConduitAPIController.php
+++ b/src/applications/conduit/controller/PhabricatorConduitAPIController.php
@@ -475,10 +475,10 @@ final class PhabricatorConduitAPIController
     ConduitAPIRequest $request,
     PhabricatorUser $user) {
 
-    if (!$user->isUserActivated()) {
+    if (!$user->canEstablishAPISessions()) {
       return array(
-        'ERR-USER-DISABLED',
-        pht('User account is not activated.'),
+        'ERR-INVALID-AUTH',
+        pht('User account is not permitted to use the API.'),
       );
     }
 
diff --git a/src/applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php b/src/applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php
index 15da1e9c05..ec47d5c087 100644
--- a/src/applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php
+++ b/src/applications/conduit/settings/PhabricatorConduitTokensSettingsPanel.php
@@ -20,6 +20,10 @@ final class PhabricatorConduitTokensSettingsPanel
   }
 
   public function isEnabled() {
+    if ($this->getUser()->getIsMailingList()) {
+      return false;
+    }
+
     return true;
   }
 
diff --git a/src/applications/diffusion/panel/DiffusionSetPasswordSettingsPanel.php b/src/applications/diffusion/panel/DiffusionSetPasswordSettingsPanel.php
index 9271056c7b..454ed01570 100644
--- a/src/applications/diffusion/panel/DiffusionSetPasswordSettingsPanel.php
+++ b/src/applications/diffusion/panel/DiffusionSetPasswordSettingsPanel.php
@@ -19,6 +19,10 @@ final class DiffusionSetPasswordSettingsPanel extends PhabricatorSettingsPanel {
   }
 
   public function isEnabled() {
+    if ($this->getUser()->getIsMailingList()) {
+      return false;
+    }
+
     return PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth');
   }
 
diff --git a/src/applications/people/conduit/UserConduitAPIMethod.php b/src/applications/people/conduit/UserConduitAPIMethod.php
index 187e28b9b3..427e7f71e5 100644
--- a/src/applications/people/conduit/UserConduitAPIMethod.php
+++ b/src/applications/people/conduit/UserConduitAPIMethod.php
@@ -18,6 +18,9 @@ abstract class UserConduitAPIMethod extends ConduitAPIMethod {
     if ($user->getIsSystemAgent()) {
       $roles[] = 'agent';
     }
+    if ($user->getIsMailingList()) {
+      $roles[] = 'list';
+    }
     if ($user->getIsAdmin()) {
       $roles[] = 'admin';
     }
diff --git a/src/applications/people/controller/PhabricatorPeopleCreateController.php b/src/applications/people/controller/PhabricatorPeopleCreateController.php
index b8852f2e42..14b11a2d2b 100644
--- a/src/applications/people/controller/PhabricatorPeopleCreateController.php
+++ b/src/applications/people/controller/PhabricatorPeopleCreateController.php
@@ -4,8 +4,6 @@ final class PhabricatorPeopleCreateController
   extends PhabricatorPeopleController {
 
   public function handleRequest(AphrontRequest $request) {
-    $this->requireApplicationCapability(
-      PeopleCreateUsersCapability::CAPABILITY);
     $admin = $request->getUser();
 
     id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
@@ -17,7 +15,7 @@ final class PhabricatorPeopleCreateController
     if ($request->isFormPost()) {
       $v_type = $request->getStr('type');
 
-      if ($v_type == 'standard' || $v_type == 'bot') {
+      if ($v_type == 'standard' || $v_type == 'bot' || $v_type == 'list') {
         return id(new AphrontRedirectResponse())->setURI(
           $this->getApplicationURI('new/'.$v_type.'/'));
       }
@@ -41,6 +39,41 @@ final class PhabricatorPeopleCreateController
     $bot_admin = pht(
       'Administrators have greater access to edit these accounts.');
 
+    $types = array();
+
+    $can_create = $this->hasApplicationCapability(
+      PeopleCreateUsersCapability::CAPABILITY);
+    if ($can_create) {
+      $types[] = array(
+        'type' => 'standard',
+        'name' => pht('Create Standard User'),
+        'help' => pht('Create a standard user account.'),
+      );
+    }
+
+    $types[] = array(
+      'type' => 'bot',
+      'name' => pht('Create Bot User'),
+      'help' => pht('Create a new user for use with automated scripts.'),
+    );
+
+    $types[] = array(
+      'type' => 'list',
+      'name' => pht('Create Mailing List User'),
+      'help' => pht(
+        'Create a mailing list user to represent an existing, external '.
+        'mailing list like a Google Group or a Mailman list.'),
+    );
+
+    $buttons = id(new AphrontFormRadioButtonControl())
+      ->setLabel(pht('Account Type'))
+      ->setName('type')
+      ->setValue($v_type);
+
+    foreach ($types as $type) {
+      $buttons->addButton($type['type'], $type['name'], $type['help']);
+    }
+
     $form = id(new AphrontFormView())
       ->setUser($admin)
       ->appendRemarkupInstructions(
@@ -49,19 +82,7 @@ final class PhabricatorPeopleCreateController
           'explanation of user account types, see [[ %s | User Guide: '.
           'Account Roles ]].',
           PhabricatorEnv::getDoclink('User Guide: Account Roles')))
-      ->appendChild(
-        id(new AphrontFormRadioButtonControl())
-          ->setLabel(pht('Account Type'))
-          ->setName('type')
-          ->setValue($v_type)
-          ->addButton(
-            'standard',
-            pht('Create Standard User'),
-            hsprintf('%s
%s', $standard_caption, $standard_admin))
-          ->addButton(
-            'bot',
-            pht('Create Bot/Script User'),
-            hsprintf('%s
%s', $bot_caption, $bot_admin)))
+      ->appendChild($buttons)
       ->appendChild(
         id(new AphrontFormSubmitControl())
           ->addCancelButton($this->getApplicationURI())
diff --git a/src/applications/people/controller/PhabricatorPeopleListController.php b/src/applications/people/controller/PhabricatorPeopleListController.php
index aa95480dbe..d4ba9aa217 100644
--- a/src/applications/people/controller/PhabricatorPeopleListController.php
+++ b/src/applications/people/controller/PhabricatorPeopleListController.php
@@ -33,20 +33,12 @@ final class PhabricatorPeopleListController
     $crumbs = parent::buildApplicationCrumbs();
     $viewer = $this->getRequest()->getUser();
 
-    $can_create = $this->hasApplicationCapability(
-      PeopleCreateUsersCapability::CAPABILITY);
-    if ($can_create) {
+    if ($viewer->getIsAdmin()) {
       $crumbs->addAction(
         id(new PHUIListItemView())
         ->setName(pht('Create New User'))
         ->setHref($this->getApplicationURI('create/'))
         ->setIcon('fa-plus-square'));
-    } else if ($viewer->getIsAdmin()) {
-      $crumbs->addAction(
-        id(new PHUIListItemView())
-        ->setName(pht('Create New Bot'))
-        ->setHref($this->getApplicationURI('new/bot/'))
-        ->setIcon('fa-plus-square'));
     }
 
     return $crumbs;
diff --git a/src/applications/people/controller/PhabricatorPeopleNewController.php b/src/applications/people/controller/PhabricatorPeopleNewController.php
index 93f9c42faa..2590129c09 100644
--- a/src/applications/people/controller/PhabricatorPeopleNewController.php
+++ b/src/applications/people/controller/PhabricatorPeopleNewController.php
@@ -7,15 +7,19 @@ final class PhabricatorPeopleNewController
     $type = $request->getURIData('type');
     $admin = $request->getUser();
 
+    $is_bot = false;
+    $is_list = false;
     switch ($type) {
       case 'standard':
         $this->requireApplicationCapability(
           PeopleCreateUsersCapability::CAPABILITY);
-        $is_bot = false;
         break;
       case 'bot':
         $is_bot = true;
         break;
+      case 'list':
+        $is_list = true;
+        break;
       default:
         return new Aphront404Response();
     }
@@ -77,8 +81,8 @@ final class PhabricatorPeopleNewController
           // Automatically approve the user, since an admin is creating them.
           $user->setIsApproved(1);
 
-          // If the user is a bot, approve their email too.
-          if ($is_bot) {
+          // If the user is a bot or list, approve their email too.
+          if ($is_bot || $is_list) {
             $email->setIsVerified(1);
           }
 
@@ -92,7 +96,13 @@ final class PhabricatorPeopleNewController
               ->makeSystemAgentUser($user, true);
           }
 
-          if ($welcome_checked && !$is_bot) {
+          if ($is_list) {
+            id(new PhabricatorUserEditor())
+              ->setActor($admin)
+              ->makeMailingListUser($user, true);
+          }
+
+          if ($welcome_checked && !$is_bot && !$is_list) {
             $user->sendWelcomeEmail($admin);
           }
 
@@ -123,7 +133,10 @@ final class PhabricatorPeopleNewController
 
     if ($is_bot) {
       $form->appendRemarkupInstructions(
-        pht('You are creating a new **bot/script** user account.'));
+        pht('You are creating a new **bot** user account.'));
+    } else if ($is_list) {
+      $form->appendRemarkupInstructions(
+        pht('You are creating a new **mailing list** user account.'));
     } else {
       $form->appendRemarkupInstructions(
         pht('You are creating a new **standard** user account.'));
@@ -150,7 +163,7 @@ final class PhabricatorPeopleNewController
           ->setCaption(PhabricatorUserEmail::describeAllowedAddresses())
           ->setError($e_email));
 
-    if (!$is_bot) {
+    if (!$is_bot && !$is_list) {
       $form->appendChild(
         id(new AphrontFormCheckboxControl())
           ->addCheckbox(
@@ -171,7 +184,7 @@ final class PhabricatorPeopleNewController
         ->appendChild(id(new AphrontFormDividerControl()))
         ->appendRemarkupInstructions(
           pht(
-            '**Why do bot/script accounts need an email address?**'.
+            '**Why do bot accounts need an email address?**'.
             "\n\n".
             'Although bots do not normally receive email from Phabricator, '.
             'they can interact with other systems which require an email '.
diff --git a/src/applications/people/customfield/PhabricatorUserRolesField.php b/src/applications/people/customfield/PhabricatorUserRolesField.php
index f4c667fd56..f68ea6c3c5 100644
--- a/src/applications/people/customfield/PhabricatorUserRolesField.php
+++ b/src/applications/people/customfield/PhabricatorUserRolesField.php
@@ -37,6 +37,9 @@ final class PhabricatorUserRolesField
     if ($user->getIsSystemAgent()) {
       $roles[] = pht('Bot');
     }
+    if ($user->getIsMailingList()) {
+      $roles[] = pht('Mailing List');
+    }
 
     if ($roles) {
       return implode(', ', $roles);
diff --git a/src/applications/people/editor/PhabricatorUserEditor.php b/src/applications/people/editor/PhabricatorUserEditor.php
index cc34696f2d..d7885ef101 100644
--- a/src/applications/people/editor/PhabricatorUserEditor.php
+++ b/src/applications/people/editor/PhabricatorUserEditor.php
@@ -278,6 +278,43 @@ final class PhabricatorUserEditor extends PhabricatorEditor {
     return $this;
   }
 
+  /**
+   * @task role
+   */
+  public function makeMailingListUser(PhabricatorUser $user, $mailing_list) {
+    $actor = $this->requireActor();
+
+    if (!$user->getID()) {
+      throw new Exception(pht('User has not been created yet!'));
+    }
+
+    $user->openTransaction();
+      $user->beginWriteLocking();
+
+        $user->reload();
+        if ($user->getIsMailingList() == $mailing_list) {
+          $user->endWriteLocking();
+          $user->killTransaction();
+          return $this;
+        }
+
+        $log = PhabricatorUserLog::initializeNewLog(
+          $actor,
+          $user->getPHID(),
+          PhabricatorUserLog::ACTION_MAILING_LIST);
+        $log->setOldValue($user->getIsMailingList());
+        $log->setNewValue($mailing_list);
+
+        $user->setIsMailingList((int)$mailing_list);
+        $user->save();
+
+        $log->save();
+
+      $user->endWriteLocking();
+    $user->saveTransaction();
+
+    return $this;
+  }
 
   /**
    * @task role
diff --git a/src/applications/people/phid/PhabricatorPeopleUserPHIDType.php b/src/applications/people/phid/PhabricatorPeopleUserPHIDType.php
index ba271e6d92..f09c75087e 100644
--- a/src/applications/people/phid/PhabricatorPeopleUserPHIDType.php
+++ b/src/applications/people/phid/PhabricatorPeopleUserPHIDType.php
@@ -44,6 +44,10 @@ final class PhabricatorPeopleUserPHIDType extends PhabricatorPHIDType {
       $handle->setFullName($user->getFullName());
       $handle->setImageURI($user->getProfileImageURI());
 
+      if ($user->getIsMailingList()) {
+        $handle->setIcon('fa-envelope-o');
+      }
+
       $availability = null;
       if (!$user->isUserActivated()) {
         $availability = PhabricatorObjectHandle::AVAILABILITY_DISABLED;
diff --git a/src/applications/people/query/PhabricatorPeopleQuery.php b/src/applications/people/query/PhabricatorPeopleQuery.php
index 8552234df9..09dfd51f6d 100644
--- a/src/applications/people/query/PhabricatorPeopleQuery.php
+++ b/src/applications/people/query/PhabricatorPeopleQuery.php
@@ -12,6 +12,7 @@ final class PhabricatorPeopleQuery
   private $dateCreatedBefore;
   private $isAdmin;
   private $isSystemAgent;
+  private $isMailingList;
   private $isDisabled;
   private $isApproved;
   private $nameLike;
@@ -67,6 +68,11 @@ final class PhabricatorPeopleQuery
     return $this;
   }
 
+  public function withIsMailingList($mailing_list) {
+    $this->isMailingList = $mailing_list;
+    return $this;
+  }
+
   public function withIsDisabled($disabled) {
     $this->isDisabled = $disabled;
     return $this;
@@ -340,6 +346,13 @@ final class PhabricatorPeopleQuery
         (int)$this->isSystemAgent);
     }
 
+    if ($this->isMailingList !== null) {
+      $where[] = qsprintf(
+        $conn_r,
+        'user.isMailingList = %d',
+        (int)$this->isMailingList);
+    }
+
     if (strlen($this->nameLike)) {
       $where[] = qsprintf(
         $conn_r,
diff --git a/src/applications/people/query/PhabricatorPeopleSearchEngine.php b/src/applications/people/query/PhabricatorPeopleSearchEngine.php
index a26c69e364..1db4140a57 100644
--- a/src/applications/people/query/PhabricatorPeopleSearchEngine.php
+++ b/src/applications/people/query/PhabricatorPeopleSearchEngine.php
@@ -33,6 +33,10 @@ final class PhabricatorPeopleSearchEngine
       'isSystemAgent',
       $this->readBoolFromRequest($request, 'isSystemAgent'));
 
+    $saved->setParameter(
+      'isMailingList',
+      $this->readBoolFromRequest($request, 'isMailingList'));
+
     $saved->setParameter(
       'needsApproval',
       $this->readBoolFromRequest($request, 'needsApproval'));
@@ -77,6 +81,7 @@ final class PhabricatorPeopleSearchEngine
     $is_admin = $saved->getParameter('isAdmin');
     $is_disabled = $saved->getParameter('isDisabled');
     $is_system_agent = $saved->getParameter('isSystemAgent');
+    $is_mailing_list = $saved->getParameter('isMailingList');
     $needs_approval = $saved->getParameter('needsApproval');
 
     if ($is_admin !== null) {
@@ -91,6 +96,10 @@ final class PhabricatorPeopleSearchEngine
       $query->withIsSystemAgent($is_system_agent);
     }
 
+    if ($is_mailing_list !== null) {
+      $query->withIsMailingList($is_mailing_list);
+    }
+
     if ($needs_approval !== null) {
       $query->withIsApproved(!$needs_approval);
     }
@@ -121,6 +130,7 @@ final class PhabricatorPeopleSearchEngine
     $is_admin = $this->getBoolFromQuery($saved, 'isAdmin');
     $is_disabled = $this->getBoolFromQuery($saved, 'isDisabled');
     $is_system_agent = $this->getBoolFromQuery($saved, 'isSystemAgent');
+    $is_mailing_list = $this->getBoolFromQuery($saved, 'isMailingList');
     $needs_approval = $this->getBoolFromQuery($saved, 'needsApproval');
 
     $form
@@ -167,6 +177,17 @@ final class PhabricatorPeopleSearchEngine
               'true' => pht('Show Only Bots'),
               'false' => pht('Hide Bots'),
             )))
+      ->appendChild(
+        id(new AphrontFormSelectControl())
+          ->setName('isMailingList')
+          ->setLabel(pht('Mailing Lists'))
+          ->setValue($is_mailing_list)
+          ->setOptions(
+            array(
+              '' => pht('(Show All)'),
+              'true' => pht('Show Only Mailing Lists'),
+              'false' => pht('Hide Mailing Lists'),
+            )))
       ->appendChild(
         id(new AphrontFormSelectControl())
           ->setName('needsApproval')
@@ -278,6 +299,10 @@ final class PhabricatorPeopleSearchEngine
         $item->addIcon('fa-desktop', pht('Bot'));
       }
 
+      if ($user->getIsMailingList()) {
+        $item->addIcon('fa-envelope-o', pht('Mailing List'));
+      }
+
       if ($viewer->getIsAdmin()) {
         $user_id = $user->getID();
         if ($is_approval) {
diff --git a/src/applications/people/storage/PhabricatorUser.php b/src/applications/people/storage/PhabricatorUser.php
index d69fa146d1..b49fe0bee0 100644
--- a/src/applications/people/storage/PhabricatorUser.php
+++ b/src/applications/people/storage/PhabricatorUser.php
@@ -38,6 +38,7 @@ final class PhabricatorUser
   protected $conduitCertificate;
 
   protected $isSystemAgent = 0;
+  protected $isMailingList = 0;
   protected $isAdmin = 0;
   protected $isDisabled = 0;
   protected $isEmailVerified = 0;
@@ -73,6 +74,8 @@ final class PhabricatorUser
         return (bool)$this->isDisabled;
       case 'isSystemAgent':
         return (bool)$this->isSystemAgent;
+      case 'isMailingList':
+        return (bool)$this->isMailingList;
       case 'isEmailVerified':
         return (bool)$this->isEmailVerified;
       case 'isApproved':
@@ -112,6 +115,46 @@ final class PhabricatorUser
     return true;
   }
 
+  public function canEstablishWebSessions() {
+    if (!$this->isUserActivated()) {
+      return false;
+    }
+
+    if ($this->getIsMailingList()) {
+      return false;
+    }
+
+    if ($this->getIsSystemAgent()) {
+      return false;
+    }
+
+    return true;
+  }
+
+  public function canEstablishAPISessions() {
+    if (!$this->isUserActivated()) {
+      return false;
+    }
+
+    if ($this->getIsMailingList()) {
+      return false;
+    }
+
+    return true;
+  }
+
+  public function canEstablishSSHSessions() {
+    if (!$this->isUserActivated()) {
+      return false;
+    }
+
+    if ($this->getIsMailingList()) {
+      return false;
+    }
+
+    return true;
+  }
+
   /**
    * Returns `true` if this is a standard user who is logged in. Returns `false`
    * for logged out, anonymous, or external users.
@@ -140,6 +183,7 @@ final class PhabricatorUser
         'consoleTab' => 'text64',
         'conduitCertificate' => 'text255',
         'isSystemAgent' => 'bool',
+        'isMailingList' => 'bool',
         'isDisabled' => 'bool',
         'isAdmin' => 'bool',
         'timezoneIdentifier' => 'text255',
@@ -1032,7 +1076,7 @@ final class PhabricatorUser
       case PhabricatorPolicyCapability::CAN_VIEW:
         return PhabricatorPolicies::POLICY_PUBLIC;
       case PhabricatorPolicyCapability::CAN_EDIT:
-        if ($this->getIsSystemAgent()) {
+        if ($this->getIsSystemAgent() || $this->getIsMailingList()) {
           return PhabricatorPolicies::POLICY_ADMIN;
         } else {
           return PhabricatorPolicies::POLICY_NOONE;
diff --git a/src/applications/people/storage/PhabricatorUserLog.php b/src/applications/people/storage/PhabricatorUserLog.php
index 1f14a27e4c..5939778f25 100644
--- a/src/applications/people/storage/PhabricatorUserLog.php
+++ b/src/applications/people/storage/PhabricatorUserLog.php
@@ -16,6 +16,7 @@ final class PhabricatorUserLog extends PhabricatorUserDAO
 
   const ACTION_ADMIN          = 'admin';
   const ACTION_SYSTEM_AGENT   = 'system-agent';
+  const ACTION_MAILING_LIST   = 'mailing-list';
   const ACTION_DISABLE        = 'disable';
   const ACTION_APPROVE        = 'approve';
   const ACTION_DELETE         = 'delete';
@@ -62,6 +63,7 @@ final class PhabricatorUserLog extends PhabricatorUserDAO
       self::ACTION_EDIT => pht('Edit Account'),
       self::ACTION_ADMIN => pht('Add/Remove Administrator'),
       self::ACTION_SYSTEM_AGENT => pht('Add/Remove System Agent'),
+      self::ACTION_MAILING_LIST => pht('Add/Remove Mailing List'),
       self::ACTION_DISABLE => pht('Enable/Disable'),
       self::ACTION_APPROVE => pht('Approve Registration'),
       self::ACTION_DELETE => pht('Delete User'),
diff --git a/src/applications/people/typeahead/PhabricatorPeopleDatasource.php b/src/applications/people/typeahead/PhabricatorPeopleDatasource.php
index ab1f11cede..f359197500 100644
--- a/src/applications/people/typeahead/PhabricatorPeopleDatasource.php
+++ b/src/applications/people/typeahead/PhabricatorPeopleDatasource.php
@@ -54,7 +54,9 @@ final class PhabricatorPeopleDatasource
       if ($user->getIsDisabled()) {
         $closed = pht('Disabled');
       } else if ($user->getIsSystemAgent()) {
-        $closed = pht('Bot/Script');
+        $closed = pht('Bot');
+      } else if ($user->getIsMailingList()) {
+        $closed = pht('Mailing List');
       }
 
       $result = id(new PhabricatorTypeaheadResult())
@@ -65,6 +67,10 @@ final class PhabricatorPeopleDatasource
         ->setPriorityType('user')
         ->setClosed($closed);
 
+      if ($user->getIsMailingList()) {
+        $result->setIcon('fa-envelope-o');
+      }
+
       if ($this->enrichResults) {
         $display_type = 'User';
         if ($user->getIsAdmin()) {
diff --git a/src/applications/settings/controller/PhabricatorSettingsMainController.php b/src/applications/settings/controller/PhabricatorSettingsMainController.php
index 9f95b01695..80753b17ca 100644
--- a/src/applications/settings/controller/PhabricatorSettingsMainController.php
+++ b/src/applications/settings/controller/PhabricatorSettingsMainController.php
@@ -97,6 +97,8 @@ final class PhabricatorSettingsMainController
 
     $result = array();
     foreach ($panels as $key => $panel) {
+      $panel->setUser($this->user);
+
       if (!$panel->isEnabled()) {
         continue;
       }
diff --git a/src/applications/settings/panel/PhabricatorConduitCertificateSettingsPanel.php b/src/applications/settings/panel/PhabricatorConduitCertificateSettingsPanel.php
index d7210a3c8f..aca40d5521 100644
--- a/src/applications/settings/panel/PhabricatorConduitCertificateSettingsPanel.php
+++ b/src/applications/settings/panel/PhabricatorConduitCertificateSettingsPanel.php
@@ -19,6 +19,14 @@ final class PhabricatorConduitCertificateSettingsPanel
     return pht('Authentication');
   }
 
+  public function isEnabled() {
+    if ($this->getUser()->getIsMailingList()) {
+      return false;
+    }
+
+    return true;
+  }
+
   public function processRequest(AphrontRequest $request) {
     $user = $this->getUser();
     $viewer = $request->getUser();
diff --git a/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php b/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php
index 288552fd44..dc2acef9bf 100644
--- a/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php
+++ b/src/applications/settings/panel/PhabricatorSSHKeysSettingsPanel.php
@@ -19,6 +19,10 @@ final class PhabricatorSSHKeysSettingsPanel extends PhabricatorSettingsPanel {
   }
 
   public function isEnabled() {
+    if ($this->getUser()->getIsMailingList()) {
+      return false;
+    }
+
     return true;
   }