Before you start
You'll need:
- A domain whose DNS you can edit, for example
example.com. - An AWS account, in a Region where Amazon SES email receiving is available. Check the SES documentation for the current list of Regions.
- For sending: an SMTP server (Amazon SES SMTP, Resend or any other provider), or a Resend API key.
How Bucketmail uses it. SES stores each incoming message as a raw MIME file in S3. Bucketmail lists the prefix for each account, downloads new objects once and keeps them on your device. It remembers which objects it has already downloaded, so deleting a message in the app never downloads it again. Bucketmail never deletes anything from S3.
1. Verify your domain in SES
- In the Amazon SES console, open Configuration → Identities and create a domain identity for
example.com. Add the DKIM records it gives you to your DNS. - Point your domain's mail at SES by adding an MX record:
ReplaceType Name Priority Value MX example.com10 inbound-smtp.us-east-1.amazonaws.comus-east-1with the Region where you set up receiving.
Changing the MX record moves all mail for that domain to SES. If the domain already has a mailbox provider, use a subdomain such as mail.example.com while you try things out.
2. Create the S3 bucket
Create a private S3 bucket (keep Block all public access on), for example my-mail-bucket. It can be in any Region, because Bucketmail detects the bucket's Region automatically. Then add a bucket policy that lets SES write to it:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSESPuts",
"Effect": "Allow",
"Principal": { "Service": "ses.amazonaws.com" },
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-mail-bucket/*",
"Condition": {
"StringEquals": { "AWS:SourceAccount": "111122223333" },
"StringLike": { "AWS:SourceArn": "arn:aws:ses:*" }
}
}
]
}
Replace my-mail-bucket with your bucket name and 111122223333 with your AWS account ID.
Default bucket encryption with S3-managed keys (SSE-S3) needs no extra setup. If you use SSE-KMS, the IAM user in step 4 also needs kms:Decrypt on that key.
3. Create an SES receipt rule
- In SES, open Configuration → Email receiving, create a rule set and make it active.
- Add a rule. Under Recipient conditions, enter the addresses (or the whole domain) the rule applies to, such as
support@example.com. - Add the action Deliver to Amazon S3 bucket:
- S3 bucket:
my-mail-bucket - Object key prefix: one prefix per mailbox, for example
support/inbox/ - Leave message encryption off. SES client-side encryption produces objects Bucketmail can't read.
- S3 bucket:
- Save the rule and send a test email to the address. A new object should appear under the prefix within a few seconds.
Several mailboxes? Give each address its own rule and prefix, such as support/inbox/ and sales/inbox/. Each one becomes a separate account in Bucketmail. If you leave an account's prefix empty in the app, Bucketmail uses account-name/inbox/.
4. Give Bucketmail read-only access (IAM)
Create an IAM user just for Bucketmail and attach this policy. It needs only two permissions, s3:ListBucket and s3:GetObject:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListMail",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-mail-bucket"
},
{
"Sid": "ReadMail",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-mail-bucket/*"
}
]
}
Then create an access key for the user (use case: Application running outside AWS). Keep the Access Key ID and Secret Access Key for the next step.
To limit the user to certain mailboxes, narrow s3:GetObject to arn:aws:s3:::my-mail-bucket/support/*. You can also add an s3:prefix condition to s3:ListBucket.
Bucketmail doesn't need s3:PutObject or s3:DeleteObject, and you shouldn't grant them. Messages you delete or move in the app change only your device's copy.
5. Configure Bucketmail
Open Setup: choose Bucketmail → Settings… (⌘,) on the Mac, or tap the gear button in the mailbox list on iPhone and iPad.
Amazon S3 — Receiving
- Enter the Access Key ID, Secret Access Key and Default Region, for example
us-east-1. - Tap Save to Keychain. Your keys are stored in the Keychain on this device, never in a file.
- After you add accounts, use Test Buckets to confirm Bucketmail can list each bucket. If the Region is wrong, Bucketmail corrects it automatically.
Add an account
| Field | Example | Notes |
|---|---|---|
| Name | support | Shown in the sidebar. Also used for the default prefix. |
| From Address | support@example.com | Used when you send from this account. |
| Sender Name | Example Support | Optional display name. |
| Bucket | my-mail-bucket | Leave empty for a send-only account. |
| Prefix | support/inbox/ | The object key prefix from your receipt rule. |
6. Sending: SMTP or Resend
Under Sending, choose Send Using for each account. Then use Send Test Email, which sends a message to the account's own address.
SMTP
Port 465 uses TLS from the start (implicit TLS). Port 587 connects and then upgrades with STARTTLS. Bucketmail authenticates with AUTH PLAIN or LOGIN.
| Provider | Server | Port | Username / password |
|---|---|---|---|
| Amazon SES | email-smtp.us-east-1.amazonaws.com | 465 or 587 | SES SMTP credentials, created in the SES console. These are different from your IAM access key. |
| Resend | smtp.resend.com | 465 or 587 | Username resend, password is your Resend API key |
| Other providers | Your provider's SMTP host | 465 or 587 | As your provider specifies |
With Amazon SES, the From address (or its domain) must be a verified identity. New SES accounts start in the sandbox and can send only to verified addresses until you request production access.
Resend API
Choose Resend API and paste a Resend API key. Bucketmail sends over HTTPS to api.resend.com. The From address's domain must be verified in Resend.
7. Checking for mail
- Get Mail: the download button in the toolbar, pull to refresh on iPhone and iPad, or ⇧⌘N on the Mac.
- Check for mail at launch and Check automatically (every 5, 15 or 30 minutes, or every hour) are in Setup under Fetching.
- Only new objects are downloaded. Messages are stored on your device under the app's Application Support folder. On the Mac, Setup → Storage → Show in Finder takes you there.
Importing a config.json
If you already have a JSON configuration for your mailboxes, use Setup → Import config.json… to add every account at once. Passwords, API keys and AWS keys go straight into the Keychain.
{
"support": {
"bucket_name": "my-mail-bucket",
"prefix": "support/inbox/",
"from_email": "support@example.com",
"sender_name": "Support",
"send_method": "smtp",
"smtp_server": "smtp.resend.com",
"smtp_port": 465,
"smtp_username": "resend",
"smtp_password": "re_xxxxxxxx"
},
"_aws": {
"aws_access_key_id": "AKIA…",
"aws_secret_access_key": "…",
"aws_region": "us-east-1"
}
}
Once the import has finished, delete the file from wherever you shared it, since it contains secrets.
Troubleshooting
“Access Denied” when testing buckets or getting mail
Check that the IAM policy names the right bucket. s3:ListBucket goes on the bucket ARN and s3:GetObject on bucket/*. If the bucket uses SSE-KMS, the user also needs kms:Decrypt.
The bucket works, but no messages appear
Compare the account's Prefix with the receipt rule's object key prefix, including the trailing slash. Also make sure the rule set is active and that the MX record has propagated.
Messages show up as unreadable or garbled
Turn off message encryption in the SES S3 action. Bucketmail reads plain MIME objects.
Sending fails with an authentication error
For Amazon SES, use SMTP credentials rather than your IAM access key. For Resend SMTP, the username is resend and the password is the API key. Also check the port: 465 for TLS, 587 for STARTTLS.
I deleted a message by mistake
Bucketmail never deletes anything from S3, so the original is still in your bucket. You can download it from the S3 console and open the .eml file.
Still stuck? See Support.