4ward
v0.1.0
Published
Serverless email infrastructure for AWS in Rust
Downloads
197
Maintainers
Readme
| INBOUND — Alias Engine | OUTBOUND — Transactional API |
|---|---|
| SES Inbound → S3 (raw MIME, 24h TTL) → Rust Lambda (arm64) | POST /v1/emails on API Gateway HTTP API → Rust Lambda → SESv2 |
| SRS-style rewriting: Reply-To keeps the original sender, From becomes "{name} (via {alias})" <relay@{domain}> | Bearer auth (4w_live_…) validated against SSM /4ward/api-keys/* (60s cache) |
| Loop protection, audit headers (X-Original-From/To, X-4ward-Relay), optional provenance banner | HTML + text, attachments (base64), from-domain must be a verified identity |
| Forwards to Gmail / Outlook / anywhere without breaking SPF/DMARC | Returns {"id":"<ses-message-id>","status":"sent"} |
Why 4ward? (vs SaaS)
Email forwarding is a solved problem — but hosted SaaS asks you to rent someone else's infrastructure every month, exactly when a side project can least afford it. 4ward runs the same job inside your own AWS account:
- 100% serverless — SES, Lambda, API Gateway, S3. Nothing to run, patch, or keep alive.
- Your account, your data — mail, API keys and config live in your AWS account. No third-party SaaS reads, stores, or brokers your email.
- $0/month at idle — send nothing, pay nothing. SES bills strictly per use, and Lambda's always-free tier (1M requests + 400,000 GB-seconds/month) covers the stack at rest.
- Deliverability preserved — SRS-style rewriting keeps SPF/DMARC alignment for your relay domain, and first-hop ARC sealing carries the original authentication results through Gmail/Outlook re-evaluation.
| | Typical SaaS email service | 4ward (your AWS account) |
|---|---|---|
| Cost at idle | Fixed subscription from day one | $0 — pay-per-use only |
| Where your mail lives | Vendor's servers | Your bucket, your functions, your SES identity |
| Control & portability | Vendor terms and export tools | CloudFormation stack in/out, standard AWS primitives |
| Quotas & limits | Vendor plan tiers | SES quotas you can raise yourself (npx 4ward request-production) |
| Lock-in | Proprietary pipeline | Open source, Apache-2.0, auditable end to end |
Comparisons are qualitative on purpose — vendor pricing changes constantly, so check current plans yourself. 4ward's own usage costs are AWS pay-per-use (SES, Lambda, S3, API Gateway), which at low volume stays inside the always-free Lambda tier plus pennies of SES.
Quickstart
npx 4ward init # questionnaire → 4ward.json
npx 4ward deploy # session check → arm64 builds → CloudFormation stack
npx 4ward dns # records to copy (table, --format json|bind)
npx 4ward keys create prod # token → SSM, printed once
npx 4ward status # sandbox? quota? enforcement?
npx 4ward request-production # automated SES production-access request
npx 4ward alias set [email protected] [email protected],[email protected]Needs an AWS CLI session with deploy permissions. Local Lambda builds need cargo-lambda + Zig (deploy warns and ships placeholder code without them).
Send an email
curl -X POST "$API/v1/emails" \
-H "Authorization: Bearer 4w_live_<token>" \
-H 'Content-Type: application/json' -d '{
"from": "Acme <[email protected]>",
"to": ["[email protected]"],
"reply_to": "[email protected]",
"subject": "System Verification",
"html": "<p>Your code is: <strong>849201</strong></p>",
"text": "Your code is: 849201",
"attachments": [{ "filename": "document.pdf", "content": "<base64>", "content_type": "application/pdf" }]
}'4ward.json
{
"version": "1",
"project": "4ward",
"aws": { "region": "us-east-1", "profile": "default", "stack_name": "4ward-example-com" },
"api": { "enabled": true, "cors": ["*"], "rate_limit": { "requests_per_second": 100, "burst": 200 } },
"settings": { "banner_enabled": true, "retention_days": 1, "sender_format": "{name} (via {alias}) <relay@{domain}>" },
"domains": [
{ "domain": "example.com", "dns_provider": "route53", "catch_all": "[email protected]",
"routes": { "support": ["[email protected]", "[email protected]"] } }
]
}"route53" uses your existing hosted zone (auto-detected at deploy; records are printed for you to add); "external" prints the same MX / SPF / 3× DKIM CNAME / DMARC table to copy. Bounce (>5%) and complaint (>0.1%) CloudWatch alarms ship in the stack.
Layout
crates/4ward-core config schema + DNS record generation
crates/4ward-cli 4ward binary (embeds templates/template.yaml)
lambdas/forwarder inbound SRS forwarder
lambdas/api outbound API
docs/assets brand crops (lockup, icon) + architecture diagram
bin/run.js npx dispatcher (prebuilt per-platform binary, cargo fallback)Dev
cargo check --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cargo lambda build --arm64 --release --package lambda-forwarder
cargo lambda build --arm64 --release --package lambda-api
aws cloudformation validate-template --template-body file://crates/4ward-cli/templates/template.yaml