Inbox rules: permissions and (allow, block, filter)

MailSlurp has a concept called InboxRulesets that allow you to create complex rules and patterns for an inbox to control:

  • what emails are accepted by an inbox
  • what recipients an inbox can send emails to

You can add multiple rules to an inbox using wildcard patterns and standard email address matching. This guide explains different use cases with examples and documentation.

Inbox ruleset lifecycle

Here is a brief overview of how inbox rulesets are evaluated. If an inbox has rulesets they will be evaluated against email addresses within outbound and bound emails to block, filter, or allow the sending or receiving action.

inbox ruleset diagram

Emails that are blocked during receiving are stored as missed emails and can be accessed in the dashboard or via the API.

Structure of rulesets

Each inbox ruleset has the following properties

PropertyDescriptionExample values
inboxIdID of inbox to attach ruleset to123-456
scopeWhen to evaluate a rulesetRECEIVING_EMAILS, SENDING_EMAILS
actionWhat action to take if rule matchesBLOCK, ALLOW, FILTER_REMOVE
targetThe pattern to match email sender or recipients against. Can be a wildcard pattern using * or an email address*@gmail.com, admin@mydomain.com

Scope types

ScopeDescription
RECEIVING_EMAILSInbox rulesets scoped to receiving emails will be evaluated whenever an attached inbox receives an email. Target is matched against the sender from field. Use with BLOCK or ALLOW actions.
SENDING_EMAILSRules scoped to sending emails will be evaluated before emails are sent from an attached inbox. Use FILTER_REMOVE to strip blocked addresses to prevent sending to target email addresses or use BLOCK and ALLOW to block or allow if a target matches any recipient in the send options.

Action types

ActionWorks with ScopeDescription
BLOCKAll scopesIf a ruleset matches a target email address in received or sending email the email will be blocked from being received or sent respectively.
ALLOWAll scopesIf a ruleset matches a target email address in any scope the email will be allowed to be sent or received. If you have several specific BLOCK actions and a more permissive ALLOW the allow will take precedence.
FILTER_REMOVESENDING_EMAILSWill remove matching email address from an email before sending to ensure that email addresses cannot be sent to those addresses. Differs from BLOCK in way that FILTER_REMOVE still allows an email to be sent it just removes the affected email addresses.

Target syntax

The target property of an inbox ruleset is a wildcard pattern or email address that can be used by the ruleset to evaluate inputs to see if the ruleset matches.

Target typeExampleDescription
Wild card matching*@test.comUse asterisk * wild cards to match for email address patterns. Useful for blocking, allowing, or filtering email address from whole domains
Email matchingabc@test.comDirect email matching (case insensitive) for more precise blocking, allowing, and filter of email addresses

If you need to target multiple email addresses use multiple inbox rulesets or a wildcard pattern.

Action precedence

The ALLOW action will always override BLOCK if a ruleset matches for both. So if you add a BLOCK * ruleset to an inbox but also add an ALLOW test@gmail.com using the RECEIVING_EMAILS scope then the inbox will block all inbound emails except those from test@gmail.com. Read further for more information on scope.

ALLOW actions have a higher precedence than BLOCK so if two actions match for a ruleset target the ALLOW will override the BLOCK.

Creating inbox rulesets

To create a ruleset first create an inbox in the Mailslurp dashboard or using the API. You can then add as many rulesets as you wish to a given inbox using the inbox ID. Let’s see different ways to create rulesets and the cover what different scopes and actions do.

Create rules in code

// add ruleset to block all receiving for an inbox
await mailslurp.inboxRulesetController.createNewInboxRuleset({
    action: CreateInboxRulesetOptions.ActionEnum.BLOCK,
    scope: CreateInboxRulesetOptions.ScopeEnum.RECEIVINGEMAILS,
    target: '*'
}, inbox.id)

More code examples

To use Inbox Rulesets in code use the REST API or an official SDK client. Here we will configure the MailSlurp Javascript client to create and test inbox rulesets using jest.

Setup

import {CreateInboxRulesetOptions, MailSlurp, MatchOption} from 'mailslurp-client';

const timeout = 120000
const mailslurp = new MailSlurp({ apiKey: process.env.apiKey });
jest.setTimeout(timeout);

Block sending

test('inbox ruleset block sending and throw', async () => {
  const mailslurp = new MailSlurp({ apiKey: process.env.API_KEY! });
  // create two inboxes for testing
  const inbox1 = await mailslurp.inboxController.createInboxWithDefaults();
  const inbox2 = await mailslurp.inboxController.createInboxWithDefaults();

  // can send with no ruleset
  await mailslurp.inboxController.sendEmailAndConfirm({
    inboxId: inbox2.id!,
    sendEmailOptions: { to: [inbox1.emailAddress!], subject: 'Before block' },
  });
  const [received] = await mailslurp.waitController.waitForMatchingEmails({
    matchOptions: {
      matches: [
        {
          field: MatchOptionFieldEnum.FROM,
          should: MatchOptionShouldEnum.CONTAIN,
          value: inbox2.emailAddress,
        },
      ],
    },
    count: 1,
    inboxId: inbox1.id!,
    timeout: 60000,
  });
  expect(received.subject).toContain('Before block');

  // now create sending block for all domains
  const rulesetSendBlock =
    await mailslurp.inboxRulesetController.createNewInboxRuleset({
      inboxId: inbox1.id,
      createInboxRulesetOptions: {
        action: CreateInboxRulesetOptionsActionEnum.BLOCK,
        scope: CreateInboxRulesetOptionsScopeEnum.SENDING_EMAILS,
        target: '*',
      },
    });

  // sending throws an exception for inbox2 recipient
  try {
    await mailslurp.inboxController.sendEmailAndConfirmRaw({
      inboxId: inbox1.id!,
      sendEmailOptions: {
        to: [inbox2.emailAddress!],
        subject: "Can't email inbox2",
      },
    });
  } catch (e: any) {
    expect(e.status).toEqual(400);
    expect(await e.text()).toContain('Inbox ruleset prevents sending');
  }

  // can test ruleset using the test endpoint to find out why blocked
  const testResult =
    await mailslurp.inboxRulesetController.testInboxRulesetsForInbox({
      inboxId: inbox1.id!,
      inboxRulesetTestOptions: {
        testTarget: inbox2.emailAddress!,
      },
    });
  expect(testResult.matches).toBeTruthy();
  // our sending block rule matches
  expect(Object.keys(testResult.rulesetMatches!)).toContain(
    rulesetSendBlock.id
  );
  expect(testResult.rulesetMatches![rulesetSendBlock.id]!).toEqual(true);

  // add an allow rule for inbox2's email address
  const sendingEmailsAllowRule =
    await mailslurp.inboxRulesetController.createNewInboxRuleset({
      inboxId: inbox1.id,
      createInboxRulesetOptions: {
        action: CreateInboxRulesetOptionsActionEnum.ALLOW,
        scope: CreateInboxRulesetOptionsScopeEnum.SENDING_EMAILS,
        target: inbox2.emailAddress,
      },
    });

  // test that our new rule allows sending
  const testResult2 =
    await mailslurp.inboxRulesetController.testInboxRulesetsForInbox({
      inboxId: inbox1.id!,
      inboxRulesetTestOptions: {
        testTarget: inbox2.emailAddress!,
      },
    });
  expect(testResult2.rulesetMatches![rulesetSendBlock.id]!).toEqual(true);
  expect(testResult2.rulesetMatches![sendingEmailsAllowRule.id]!).toEqual(
    true
  );

  // now can send to inbox 2
  const sendRaw = await mailslurp.inboxController.sendEmailAndConfirmRaw({
    inboxId: inbox1.id!,
    sendEmailOptions: {
      to: [inbox2.emailAddress!],
      subject: 'Hi inbox2',
    },
  });
  expect(sendRaw.raw.ok).toBeTruthy();
});

Filter remove when sending

In this example we demonstrate the use of FILTER_REMOVE action inbox ruleset to ensure that a particular email address cannot have emails sent to it from an inbox.

test('inbox ruleset using filter_remove for sending', async () => {
  const mailslurp = new MailSlurp({ apiKey: process.env.API_KEY! });
  // create inboxes for testing
  const inbox1 = await mailslurp.inboxController.createInboxWithDefaults();
  const inbox2 = await mailslurp.inboxController.createInboxWithDefaults();
  const inbox3 = await mailslurp.inboxController.createInboxWithDefaults();

  // add filter remove action for inbox 1 to remove inbox2 email address
  await mailslurp.inboxRulesetController.createNewInboxRuleset({
    inboxId: inbox1.id,
    createInboxRulesetOptions: {
      action: CreateInboxRulesetOptionsActionEnum.FILTER_REMOVE,
      scope: CreateInboxRulesetOptionsScopeEnum.SENDING_EMAILS,
      target: inbox2.emailAddress,
    },
  });

  const sent = await mailslurp.inboxController.sendEmailAndConfirm({
    inboxId: inbox1.id!,
    sendEmailOptions: {
      to: [inbox2.emailAddress!, inbox3.emailAddress!],
      subject: "Can't email inbox2",
    },
  });

  expect(sent.to).not.toContain(inbox2.emailAddress);
  expect(sent.to).toContain(inbox3.emailAddress);
});

Block inbox receiving emails

test('inbox ruleset block receiving emails', async () => {
  const mailslurp = new MailSlurp({ apiKey: process.env.API_KEY! });

  const inbox1 = await mailslurp.inboxController.createInboxWithDefaults();
  const inbox2 = await mailslurp.inboxController.createInboxWithDefaults();
  // normally inbox1 can receive emails
  await mailslurp.inboxController.sendEmailAndConfirm({
    inboxId: inbox2.id!,
    sendEmailOptions: { to: [inbox1.emailAddress!], subject: 'Before block' },
  });
  const [received] = await mailslurp.waitController.waitForMatchingEmails({
    inboxId: inbox1.id!,
    timeout: 60000,
    count: 1,
    matchOptions: {
      matches: [
        {
          field: MatchOptionFieldEnum.FROM,
          should: MatchOptionShouldEnum.CONTAIN,
          value: inbox2.emailAddress,
        },
      ],
    },
  });
  expect(received.subject).toContain('Before block');

  // add ruleset to block all receiving to inbox1
  const ruleset =
    await mailslurp.inboxRulesetController.createNewInboxRuleset({
      inboxId: inbox1.id,
      createInboxRulesetOptions: {
        action: CreateInboxRulesetOptionsActionEnum.BLOCK,
        scope: CreateInboxRulesetOptionsScopeEnum.RECEIVING_EMAILS,
        target: '*',
      },
    });
  expect(ruleset.inboxId).toEqual(inbox1.id);
  expect(ruleset.target).toEqual('*');

  // now send from inbox2 to inbox1 and expect email to be missed
  await mailslurp.inboxController.sendEmailAndConfirm({
    inboxId: inbox2.id!,
    sendEmailOptions: { to: [inbox1.emailAddress!], subject: 'After block' },
  });

  // blocked emails can be found using missed email controller, the email was sent to inbox1 so check inbox1 missed emails
  // const missed = await mailslurp.missedEmailController.waitForNthMissedEmail({
  //   inboxId: inbox1.id!,
  //   timeout: 60000,
  //   index: 0,
  // });
  // expect(missed.subject).toContain('After block');
});