Files
mailsender/README.md
T
Claude 3bce057eab Add encryption policy, split delivery and SecureMailSender
- delivery: PolicyResolver (address > *@domain > default), RecipientKeyResolver
  (discovery + validation), DeliveryPlanner (REQUIRE refusal, SPLIT/FAIL,
  own copy per Bcc with hidden key IDs), MessageAssembler with sender keys
  for readable sent copies, EnvelopeMimeMessage for per-copy SMTP envelopes
- sender: SecureMailSender with BUILT_IN and RELAY implementations and a
  per-recipient SendReport; relay passes the strictest policy as a header hint
- autoconfigure: mode, default-policy, mixed-mode, recipients, sender-keys
  and relay properties; relay sender is not a bean so spring.mail stays intact
- demo: sends through SecureMailSender

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G71TQ5jDETVwdUJxGAwaiT
2026-10-12 03:27:40 +00:00

71 lines
2.8 KiB
Markdown

# mailsender
OpenPGP encryption for Spring Boot mail: discovers recipients' keys via Web Key Directory (WKD) and sends
PGP/MIME (RFC 3156), or hands mail to an encrypting relay. See [docs/PLAN.md](docs/PLAN.md) for the design
and milestone status.
Requires JDK 27 and Maven 3.9+. Built on Spring Boot 4.1.1 and PGPainless 2.0.
```
mvn verify
```
## Modules
| Module | Contents |
|---|---|
| `mailsender-pgp-core` | WKD key discovery, caching, pinned keys, certificate validation, OpenPGP encryption, PGP/MIME (no Spring) |
| `mailsender-pgp-spring-boot-autoconfigure` | `mail.pgp.*` properties and beans |
| `mailsender-pgp-spring-boot-starter` | dependency bundle for applications |
| `mailsender-demo` | sample app that sends test mails |
## Usage
Add `pro.thinhha.mailsender:mailsender-pgp-spring-boot-starter`, configure `spring.mail.*` as usual, and send
through `SecureMailSender` instead of `JavaMailSender`:
```java
SendReport report = secureMailSender.send(message); // MimeMessage or SimpleMailMessage
```
Each recipient's key is looked up via WKD (cached) and validated. The message is then sent PGP/MIME-encrypted to
recipients with a usable key and in plaintext to the rest (logged as a downgrade), or refused with
`EncryptionPolicyException` if a `REQUIRE` recipient has no key. `SendReport` lists the outcome per recipient.
```yaml
mail:
pgp:
mode: BUILT_IN # or RELAY: hand plaintext to an encrypting gateway (mail.pgp.relay.*)
default-policy: OPPORTUNISTIC # REQUIRE | OPPORTUNISTIC | PLAINTEXT
mixed-mode: SPLIT # or FAIL
recipients:
"[*@partner.example]": REQUIRE
sender-keys: # your own PUBLIC key, so sent copies stay readable
"[noreply@example.com]": file:/etc/mail/noreply.pub.asc
```
Map keys that are addresses need the `[...]` brackets. See [docs/PLAN.md](docs/PLAN.md) for all options.
## Demo app
The demo app sends `DEMO_COUNT` test mails (default: 1 to `test@thinhha.pro`) through `SecureMailSender` and logs
the outcome per recipient: PGP/MIME-encrypted (RFC 3156) when a valid WKD key is found, otherwise plaintext.
Set `MAIL_PGP_MODE=RELAY` and `RELAY_HOST`/`RELAY_PORT`/`RELAY_USERNAME`/`RELAY_PASSWORD` to send via a gateway.
```
mvn -q install -DskipTests
SMTP_HOST=smtp.example.com SMTP_PORT=587 \
SMTP_USERNAME=me@example.com SMTP_PASSWORD='app-password' \
DEMO_TO=test@thinhha.pro DEMO_COUNT=1 \
java -jar mailsender-demo/target/mailsender-demo-0.1.0-SNAPSHOT.jar
```
| Variable | Default | Meaning |
|---|---|---|
| `SMTP_HOST` / `SMTP_PORT` | `localhost` / `587` | SMTP server |
| `SMTP_USERNAME` / `SMTP_PASSWORD` | empty | SMTP credentials |
| `SMTP_AUTH` / `SMTP_STARTTLS` | `true` / `true` | set to `false` for a local test server |
| `DEMO_TO` | `test@thinhha.pro` | recipient |
| `DEMO_FROM` | `SMTP_USERNAME` | sender address |
| `DEMO_COUNT` | `1` | number of mails |