Build a Local Email Identity Lab

Capture local email to explore sender identity and DMARC alignment.

Introduction

30 Second Summary

An email inbox can make a sender look familiar before you inspect any details. The name on screen can tell a different story from the address underneath.

In this project, you will build a local email identity lab with Mailpit. You will capture safe test messages on your Mac to reveal the gap between the sender an inbox displays and the identity a receiving system can verify.

What You'll Build

You'll watch each sender change inside a local browser inbox while the underlying message details remain available for inspection.

By the end of this project, you'll have:

  • A local inbox where you can watch safe test messages arrive in Safari without contacting a real mailbox.
  • A sender comparison that shows the visible From: author beside the SMTP envelope sender.
  • An identity map for predicting a DMARC outcome from SPF or DKIM alignment.
  • Secret Mission: Test display-name deception by pairing a trustworthy name with a different underlying address.

Are there any prerequisites?

You need a Mac with Homebrew installed. You also need permission to install a Homebrew formula.

No domain or email account is required.

Before We Start

This checkpoint locks in what you are building before the hands-on work begins. Every exercise message stays inside a loopback-only Mailpit lab, which keeps the experiment away from real people and real mailboxes.

Install and Isolate Mailpit

Email submission usually involves infrastructure that can reach public recipients. A capture-only Mailpit server provides the same SMTP submission behavior inside a local boundary.

You will install Mailpit 1.31.2 through Homebrew. Its web interface and SMTP listener will bind to your Mac's loopback address.

In this step, get ready to:
  • Confirm that Terminal, TextEdit, and Safari are available.
  • Install Mailpit 1.31.2 through Homebrew.
  • Start Mailpit with loopback-only listeners.
Confirm your Mac tools and install Mailpit

The included Mac applications support the rest of the lab. Homebrew supplies the Mailpit formula.

  • Press Cmd+Space to open macOS search.
  • Type Terminal into the search field.
  • Press Enter to open Terminal.
  • Repeat the macOS search sequence for TextEdit.
  • Repeat the macOS search sequence for Safari.

All three applications should open normally. Terminal should display a command prompt.

  • Check Mailpit's Homebrew state by running this command:
brew info mailpit

What does this command do?

This command asks Homebrew for the Mailpit formula details. The result shows whether the formula is installed on your Mac.

✔️ Mailpit is current

The installed section shows 1.31.2. Mailpit already matches the version used in this lab.

That completes the installation check. You can continue with the installed formula.

ⓧ I see an older installed version

Homebrew can replace the older formula with the current stable release. A short download pause is normal during the upgrade.

  • Upgrade the installed Mailpit formula by running this command:
brew upgrade mailpit

What does this command do?

Homebrew downloads the current Mailpit formula. It replaces the older installed release.

  • Confirm the installed release by running this command:
brew info mailpit

What does this check confirm?

Homebrew displays the formula details again. The installed section should now show 1.31.2.

Mailpit 1.31.2 is now installed through Homebrew.

Upgrade did not complete?

Check that Terminal remains connected to the internet. Homebrew needs to download the current formula.

Still stuck? Help me troubleshoot my Mailpit upgrade through Homebrew.

ⓧ Mailpit is not installed

Homebrew knows about the formula. Your Mac still needs a local copy of Mailpit.

  • Install the current stable Mailpit formula by running this command:
brew install mailpit

What does this command do?

Homebrew downloads the Mailpit formula. It installs the mailpit binary so Terminal can run it.

  • Confirm the installed release by running this command:
brew info mailpit

What does this check confirm?

Homebrew displays the formula details. The installed section should show 1.31.2.

The installation is complete. Mailpit 1.31.2 is now available through Homebrew.

Installation did not complete?

Check that Terminal remains connected to the internet. Homebrew needs network access to download the formula.

Need another pair of eyes? Help me troubleshoot my Mailpit installation through Homebrew.

The setup layer is complete. Mailpit 1.31.2 is installed through Homebrew.

Start Mailpit on loopback addresses

Mailpit normally supports configurable network listeners. This lab replaces the all-interface defaults with 127.0.0.1 so both services stay reachable only from your Mac.

The foreground process also keeps the lab state visible in Terminal. Closing that process ends the temporary Mailpit session.

  • Start the foreground Mailpit process by running this command:
mailpit --listen 127.0.0.1:8025 --smtp 127.0.0.1:1025

How is the lab isolated?

  • The --listen 127.0.0.1:8025 setting binds the web interface to the loopback address.
  • The --smtp 127.0.0.1:1025 setting binds the SMTP listener to the loopback address.
  • The omitted --database option makes Mailpit use a temporary local message database.
  • Relay and forwarding remain unconfigured.

Terminal stays attached to the Mailpit process. This confirms that the foreground server remains active.

  • Keep this Terminal window open.
  • Leave SMTP relay unconfigured.
  • Leave message forwarding unconfigured.

Mailpit process will not stay running?

Check that no older Mailpit process is already using the local web or SMTP port. Only one process can use each port at a time.

Compare your startup command with the command above. Both listener addresses must include 127.0.0.1.

Still having trouble? Help me diagnose why my foreground Mailpit process stops.

Verify the empty local inbox

The web interface gives you a visible checkpoint for the capture server. An empty inbox confirms that Mailpit is running before you submit any test messages.

Take a moment to predict the inbox state before you load the page.

  • Switch back to Safari.
  • Select Safari's address field.
  • Enter http://localhost:8025.
  • Press Return.

You'll see the Mailpit web interface with an empty local inbox. The Terminal window running Mailpit remains open.

The active temporary database currently contains no messages. Both Mailpit services remain bound to loopback-only addresses.

Mailpit page did not load?

Confirm that the Terminal window running Mailpit is still open. A returned command prompt means the foreground process has stopped.

Check that Safari is using http://localhost:8025.

Need help finding the gap? Help me troubleshoot why the local Mailpit inbox does not load.

Your loopback-only inbox is live. Next, you will send a baseline message into this local capture lab.

Send a Baseline Message

Your loopback-only Mailpit lab is running. Safari shows its empty inbox.

A baseline message gives you a normal sender identity to study first. It becomes your reference when the visible author changes later.

In this step, get ready to:
  • Create ~/email.txt as a plain-text message file.
  • Compose the complete baseline message in ~/email.txt.
  • Submit the baseline message to the local Mailpit inbox.
Create a plain-text message file

TextEdit can save formatted documents. This email fixture needs plain text so each line reaches Mailpit exactly as written.

  • Press Cmd+Space on your Mac to open the search bar.
  • Type TextEdit into the search bar.
  • Select TextEdit from the search results.
  • Click File in the TextEdit menu bar.
  • Click New.
  • Click Format in the TextEdit menu bar.
  • Click Make Plain Text.

You now have an empty plain-text document ready for the message fixture.

  • Click File in the TextEdit menu bar.
  • Click Save.
  • Name the document email.txt.
  • Choose your Home folder as the save location.
  • Click Save.

TextEdit should now show email.txt as the document name. The saved file lives at ~/email.txt.

Compose the baseline message

An email message has message headers followed by a body. A blank line marks the boundary between them.

  • In TextEdit, fill ~/email.txt with the baseline message by pasting the text below:
From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello

This is a message just to say hello.
So, "Hello".

How Is the Message Structured?

  • The From: field identifies the displayed author.
  • The To: field identifies the displayed recipient.
  • The Subject: field supplies the inbox title.
  • The blank line separates those fields from the message body.
  • Save ~/email.txt.

The TextEdit title bar should still show email.txt. The document should preserve the blank line above the body.

Does the Message Layout Look Different?

  • Check that ~/email.txt is stored in your Home folder.
  • Confirm that one blank line separates the Subject: field from the body.

Still stuck? Help me check the structure of my plain-text email fixture.

✔️ Awesome, I've got everything!

Your saved file contains the complete baseline message.

ⓧ I'd like to double check the full code

From: John Doe <jdoe@machine.example>
To: Mary Smith <mary@example.net>
Subject: Saying Hello

This is a message just to say hello.
So, "Hello".

Compare this reference with ~/email.txt. Every line should match exactly.

Capture the baseline message

A fresh Terminal window keeps the Mailpit process running in its original window. Shell input redirection feeds your saved message into Mailpit's local submission command.

  • Open a fresh Terminal window in your Home folder.
  • Submit ~/email.txt to the local Mailpit process by running this command:

Before you run it, what sender and subject do you expect the local inbox to display?

mailpit sendmail < email.txt

What Does This Command Do?

The < email.txt portion feeds the saved file into Mailpit's built-in local submission path. Mailpit captures the result in its temporary local database.

This submission stays inside the loopback-only Mailpit process. It does not contact a real recipient or an external SMTP server.

  • Switch back to Safari.
  • Refresh the Mailpit inbox.
  • Open the message titled Saying Hello.
  • Locate the complete sender field.
  • Locate the complete recipient field.
  • Locate the subject field.
  • Read the message body.

You should see one message from John Doe to Mary Smith with Saying Hello as its subject. The body should show This is a message just to say hello. followed by So, "Hello"..

Is the Mailpit Inbox Still Empty?

  • Confirm that the original Terminal window still shows the running Mailpit process.
  • Check that the fresh Terminal window opened in your Home folder.
  • Verify that email.txt appears in your Home folder.

Need another pair of eyes? Help me find why my baseline message is missing from Mailpit.

Your first local capture is complete. Next, you'll change the visible From: identity to test whether inbox appearance proves authorship.

Change the Visible From Identity

Your baseline message proved that a file in your Home folder can appear in the local Mailpit inbox without leaving your Mac.

The inbox currently shows the author you typed into From:. This step tests what happens when you replace that visible identity while every listener remains on loopback.

In this step, get ready to:
  • Replace the baseline message in ~/email.txt with a changed visible author.
  • Submit the changed message to the running local Mailpit process.
  • Compare the two visible identities in Safari.
Replace the visible author

The From: field belongs to the message content that an inbox displays. Changing this field creates a controlled test of visible authorship.

  • In TextEdit, select the existing contents of ~/email.txt.
  • Replace the selected message by pasting the content below:
From: "Joe Q. Public" <john.q.public@example.com>
To: Mary Smith <mary@example.net>
Subject: Visible From changed locally

This message is a safe local demonstration.
The visible From field is not proof of authentication.

What does this message change?

  • The display name is now Joe Q. Public.
  • The underlying author address is now john.q.public@example.com.
  • The subject identifies this message as the changed local test.
  • The body records the identity lesson inside the captured message.
  • Save ~/email.txt.
  • Confirm the first line displays Joe Q. Public with the address john.q.public@example.com.

Does the saved message look wrong?

  • Confirm the document remains plain text.
  • Confirm the filename still ends in .txt.
  • Compare every line with the reference below.

Still stuck? Help me check the changed message file.

✔️ Awesome, I've got everything!

Your saved message is ready for local submission.

ⓧ I'd like to double check the full code

From: "Joe Q. Public" <john.q.public@example.com>
To: Mary Smith <mary@example.net>
Subject: Visible From changed locally

This message is a safe local demonstration.
The visible From field is not proof of authentication.

What should match?

Your complete ~/email.txt file should match this reference exactly. The blank line separates the headers from the body.

Submit the changed message

Mailpit's built-in sender reads the saved message before handing it to the local listener. The running capture process stores that submission in its temporary database.

Before you submit, what do you expect the inbox to display? Keep your answer in mind.

  • In the fresh Terminal window from earlier, submit the changed file by running this command:
mailpit sendmail < email.txt

What does this command do?

The command redirects the contents of email.txt into Mailpit's built-in sender. The running SMTP listener captures the resulting message inside the local database.

  • Switch back to the Mailpit inbox in Safari.
  • Refresh the page only if the second message is not already visible.

You'll see a second message displayed from Joe Q. Public <john.q.public@example.com>. Its subject is Visible From changed locally.

This is the intended result: the local capture accepted the changed visible author without establishing that the author is genuine.

Don't see the second message?

  • Confirm the original Terminal window still shows the foreground Mailpit process running.
  • Confirm the fresh Terminal window is still in your Home folder.
  • Confirm email.txt is saved before submitting it again.

Need a hand? Help me troubleshoot the missing local message.

Compare the captured identities

A side-by-side comparison isolates the field you changed. It also confirms that the experiment stayed inside the same local capture process.

Before you compare the messages, which inbox fields do you expect to differ? Keep your answer in mind.

  • Confirm the Mailpit inbox contains exactly two captured messages.
  • Compare the displayed sender on the baseline message with the displayed sender on the second message.
  • Compare the recipient shown on both messages.
  • Compare the subject shown on both messages.
  • Confirm both messages remain inside the loopback-only Mailpit inbox.

The baseline message displays John Doe as its sender. The second message displays Joe Q. Public <john.q.public@example.com>.

Both messages still show Mary Smith as the recipient. Their subjects distinguish the baseline from the changed-visible-From test.

Mailpit has displayed the header exactly as submitted. It has not established authentication for that visible author.

You have exposed the key weakness: changing a visible author can change the inbox presentation while the entire experiment stays safely on your Mac.

Your local inbox now proves that visible authorship can change without proving who sent the message. Next, you'll trace the identities that a receiving system would evaluate.

Trace the Identities and Predict DMARC

Your changed message is now sitting beside the baseline in Mailpit. The local inbox accepted the new visible From: value without authenticating it.

That acceptance leaves an important question: which identity would a receiving system authenticate? You will answer it by separating the message header from the SMTP envelope.

SPF can authenticate the SMTP envelope identity. DKIM can authenticate a signing domain.

DMARC compares those authenticated domains with the visible author domain. Your map will show why appearance alone cannot produce an aligned result.

In this step, get ready to:
  • Inspect Mailpit sendmail's default envelope sender.
  • Inspect the changed message's captured header fields.
  • Predict a hypothetical DMARC result from the available authentication evidence.
Trace the envelope sender

An SMTP envelope carries transport information outside the message content. Mailpit sendmail's help output documents which envelope sender it uses by default.

  • Switch back to the fresh Terminal window in your Home folder.

Before you run the check, do you think the visible From: value also sets the envelope sender? Make your prediction now.

  • Display Mailpit sendmail's options by running this command:
mailpit sendmail -h

What does this command reveal?

The command prints Mailpit sendmail's available options. This lets you inspect its transport behavior separately from the message content.

  • Locate the line that begins with -f.

You should see -f string Set the envelope sender address (default "user@host"). The documented default transport identity is therefore user@host.

Help output not showing?

Confirm you are using the fresh Terminal window from earlier. The first Terminal window is occupied by the foreground Mailpit process.

Need another pair of eyes? Help me inspect the Mailpit sendmail options.

Inspect the captured header fields

Mailpit can expose captured headers or raw source. This view lets you confirm which fields came from email.txt.

  • Return to the Mailpit web interface in Safari from earlier.
  • Select the changed message with subject Visible From changed locally.
  • Choose the available message view that exposes headers or raw source.
  • Locate the From: field containing "Joe Q. Public" <john.q.public@example.com>.
  • Locate the To: field containing Mary Smith <mary@example.net>.
  • Locate the Subject: field containing Visible From changed locally.

What should you see?

  • The author field reads From: "Joe Q. Public" <john.q.public@example.com>.
  • The recipient field reads To: Mary Smith <mary@example.net>.
  • The subject field reads Subject: Visible From changed locally.

Cannot find the full fields?

The exact control wording can differ. Look for the message view that exposes headers or raw source instead of relying on a specific button name.

Still stuck? Help me find the captured message headers in Mailpit.

Map the authentication identities

Authentication evidence is separate from the fields you typed into the message. The final map connects each identity to the mechanism that would evaluate it.

How does DMARC connect the identities?

  • The Author Domain comes from the From: field.
  • SPF evaluates the SMTP MAIL FROM identity.
  • DKIM uses the d tag from a validated DKIM-Signature header.
  • DMARC passes when at least one authenticated domain aligns with the Author Domain.
  • Use john.q.public@example.com to identify example.com as the visible author domain.
  • Match the documented default user@host to Mailpit sendmail's envelope sender.
  • Check the inspected headers for a DKIM-Signature field.
  • Classify the SPF-authenticated identifier based on whether public-domain SPF validation occurred.

The message supplies no DKIM signing identifier. This local capture establishes no SPF-authenticated identifier.

Before you compare your map with the reference, do you expect any visible field alone to produce a DMARC pass? Lock in your answer now.

  • Compare your identity map with the reference below.

Reference identity map

  • Visible author domain: example.com.
  • Mailpit sendmail documented default envelope sender: user@host.
  • SPF-authenticated identifier: none established by this local exercise.
  • DKIM signing identifier: none supplied.
  • DMARC conclusion: local capture does not perform public-domain authentication. For a hypothetical domain with an applicable DMARC policy, the message would fail without an aligned SPF or DKIM authenticated identifier.

That closes the gap exposed by the changed message. Your identity map now separates what the inbox displays from what a DMARC-aware receiver can authenticate.

Secret mission

Test a Deceptive Display Name

A familiar sender name can hide a different underlying address. Create a third local message that presents Mary Smith while preserving john.q.public@example.com as the address.

Clean Up Your Resources

Clean Up Your Resources

Your loopback-only Mailpit lab has no ongoing costs. Choose whether to keep the lab running. You can pause it or delete it instead.

Resources you used:

  • Mailpit 1.31.2 installed through Homebrew.
  • Foreground Mailpit process with its web interface bound to 127.0.0.1:8025. Its SMTP listener is bound to 127.0.0.1:1025.
  • Temporary local message database containing all three captured messages.
  • Plain-text message fixture at ~/email.txt.

Keep everything running

No action needed. Choose this if you want to keep testing sender identities inside the local lab.

  • Mailpit stays installed through Homebrew.
  • The foreground process keeps the local web interface available at http://localhost:8025.
  • The temporary database continues to hold all three captured messages.
  • The display-name test remains saved in ~/email.txt.

Pause - I'll come back to this later

Shut down the foreground process to free the loopback ports. Mailpit also clears its temporary message database.

  • Switch back to the Terminal window running Mailpit.
  • Press Control-C to stop the foreground process.
  • Return to Safari.
  • Refresh the Mailpit page.

Safari can no longer load the Mailpit interface. This confirms that the foreground process has stopped.

Mailpit deletes the temporary message database when it exits. All three captured messages are now cleared.

Mailpit 1.31.2 remains installed through Homebrew. The file ~/email.txt remains in your Home folder.

Delete - I don't want to use this again

This option removes the local lab from your Mac. The identity map above keeps the key conclusions after the captured messages disappear.

  • Switch back to the Terminal window running Mailpit.
  • Press Control-C to stop the foreground process.

Your loopback listeners are now closed. Mailpit also deletes the temporary message database when it exits.

  • Uninstall the Mailpit formula by running this command:
brew uninstall mailpit

What does this command do?

Homebrew removes the Mailpit formula from your Mac. The foreground process must remain stopped because its executable is being removed.

  • Check Terminal's completion output.

You should see that Homebrew removed Mailpit.

Mailpit Did Not Uninstall?

  • Confirm that the foreground Mailpit process is stopped.
  • Ask for help with the Homebrew uninstall.
  • Move ~/email.txt to Trash using the macOS file browser.
  • Confirm that email.txt no longer appears in your Home folder.

Your local Mailpit lab is now removed. You still have the identity model you learned.

Nice Work!

Nice Work!

You did it! Your loopback-only Mailpit lab now captures three email identity tests without contacting a real mailbox.

You've learned how to:

  • Run a loopback-only SMTP capture lab with Mailpit. Capture test messages without contacting a real mailbox.
  • Change the visible From: author. Compare the message header with the SMTP envelope sender.
  • Identify the domain that SPF would authenticate. Identify the signing domain that DKIM would authenticate. Use DMARC alignment to predict a hypothetical failure when neither authenticated identifier exists.
  • Secret Mission: Demonstrate display-name deception by presenting Mary Smith as the display name above the underlying address john.q.public@example.com. Explain why RFC 9989 treats display-name attacks as outside DMARC's scope.

Ready to quiz yourself?