tva
← Insights

Ein Postfach für deinen projektspezifischen KI-Agenten einrichten

Früher oder später braucht der projektspezifische KI-Agent, den du gebaut hast, eine E-Mail-Adresse. Das Telegram-Bot-Pattern, das wir in Building a Project-Specific AI Assistant via Telegram beschrieben haben, deckt Echtzeit-Chat ab — aber Mail ist ein eigener Kanal: Service-Benachrichtigungen, Auftragsbestätigungen, OAuth-Passwort-Resets, Backoffice-Korrespondenz mit Menschen, die nicht auf Telegram sind. Du kannst diese Mails an eine persönliche Adresse weiterleiten und mit dem Rauschen leben — oder du gibst dem Projekt ein eigenes Postfach auf einer dedizierten Subdomain.

Dieser Guide behandelt den zweiten Weg: ein dediziertes Postfach auf einer Projekt-Subdomain, mit sauber konfiguriertem DKIM, SPF und DMARC. Das Pattern setzt einen Anbieter für DNS (in unserem Fall Cloudflare) und einen separaten Anbieter für das Mail-System (Opalstack) ein — die Konfiguration, bei der die meisten kleinen Betriebe landen: DNS dort, wo die Apex-Domain bereits liegt; Mail bei dem Anbieter, der vernünftiges IMAP, sauberen API-Zugang und eine Reputation hat, die Gmails Filter übersteht.

Das gesamte Setup besteht aus vier API-Aufrufen und drei DNS-Records. Mit der richtigen Vorbereitung dauert es von Anfang bis Ende etwa zehn Minuten. Wir zeigen die Aufrufe, die Verifikation und die Fehlerquellen, an denen wir beim ersten Mal gescheitert sind.

Was dieser Guide löst

  • Eine Projekt-Subdomain (system.example.com) ohne angebundene Mail-Infrastruktur
  • Eingehende Mails an eine projektspezifische Adresse, die bounced, weil kein MX-Record existiert
  • Ausgehende Mails vom Projekt, die bei Gmail den DKIM-Check nicht bestehen und im Spam landen
  • SPF- und DMARC-Records, die zwar existieren, aber nichts authentifizieren
  • Ein KI-Agent, der einen E-Mail-Kanal braucht, ohne über dein persönliches Konto zu gehen

Was du brauchst

  • Eine Apex-Domain, die du kontrollierst, mit DNS bei einem Anbieter, der eine API bereitstellt (Cloudflare, Route53, DigitalOcean DNS etc.)
  • Einen Mail-Anbieter, der das Hinzufügen von Domains per API unterstützt, DKIM-Keys bei der Domain-Erstellung generiert und IMAP/SMTP-Endpunkte bereitstellt (Opalstack, Mailcow, Migadu, Fastmail etc.)
  • API-Tokens für beide Anbieter, an einem Ort hinterlegt, von dem aus du Shell-Kommandos absetzen kannst
  • dig, openssl s_client und einen Python-Interpreter für die Verifikation
  • Ungefähr fünfzehn Minuten

Warum das Provider-Mix-Pattern

Das naheliegende Modell ist „ein Anbieter für alles“ — Website, DNS und Postfach beim gleichen Provider. Das funktioniert, solange keiner der drei Bereiche unabhängig weiterentwickelt werden muss. Den Entscheidungsrahmen zwischen gebündelten Diensten und dedizierten Spezialisten haben wir in The Self-Hosting Decision: When SaaS Costs More Than Your Own Infrastructure ausgeführt — dieselbe Logik gilt hier im kleineren Maßstab.

In unserem Fall liegt das DNS der Apex-Domain bei Cloudflare, weil wir AnyCast-Auflösung, Proxying für die öffentlichen Sites und eine API für automatisiertes Record-Management brauchen. Das Mail-System liegt bei Opalstack, weil die Kosten pro Postfach minimal sind, die Reputation ihres IMAP-Servers solide ist und ihre API zu den saubereren im europäischen Mail-Hosting-Bereich gehört. Wir verlagern weder DNS wegen Mail noch Mail wegen DNS. Der Preis für den Betrieb als zwei getrennte Systeme ist exakt drei DNS-Records und ein mentales Modell: Der DNS-Anbieter sagt der Welt, wohin Mail geht; der Mail-Anbieter empfängt, speichert und signiert sie.

Diese Trennung hat operativen Wert, weil sie den Schadensradius begrenzt. Ein DNS-Ausfall stoppt neue Mail-Routing-Entscheidungen, aber bereits zugestellte Mails an die MX-Hosts landen weiterhin an. Ein Mail-Ausfall stoppt die Zustellung, aber DNS-Lookups werden weiterhin aufgelöst. Hätten wir alles bei einem Anbieter gestapelt, würden beide Schichten gemeinsam ausfallen. Dieselbe Logik findet sich in unserer Produktionsarchitektur für gestapelte Reverse Proxies — Separation of Concerns, jede Schicht unabhängig austauschbar.

Dediziertes Postfach, Weiterleitungs-Alias oder SaaS-Inbox

Bevor du irgendetwas erstellst, wähle das richtige Abstraktionsniveau. Die drei Optionen sind nicht gleichwertig.

Ein dediziertes Postfach bedeutet eine echte Inbox, die Mails hält, IMAP-Zugangsdaten hat und sowohl senden als auch empfangen kann. Kosten: grob ein bis drei Euro pro Monat bei einem selbst gehosteten Mail-Anbieter, plus der Aufwand für das API-Setup. Das ist das, was ein KI-Agent braucht, wenn er Mails tatsächlich lesen soll — um eingehende Auftragsbestätigungen zu parsen, Service-Benachrichtigungen zu verarbeiten oder einen mehrstufigen Austausch mit einem menschlichen Ansprechpartner zu führen.

Ein Weiterleitungs-Alias ist eine virtuelle Adresse, die einfach auf eine bestehende Inbox umleitet. Kosten: null, nur Konfiguration. Das ist die richtige Wahl, wenn der KI-Agent lediglich unter einer projektbrandeten Adresse empfangen muss, das eigentliche Lesen und Verarbeiten aber in einer menschlichen Inbox stattfindet, die bereits existiert. Der Nachteil: kein IMAP-Zugang für den Agenten, keine projektspezifische Filterung auf der Zielseite, und kein sauberer Rollback-Pfad, wenn das Projekt endet — die Alias-Bereinigung wird vergessen.

Eine SaaS-Inbox bedeutet einen Dienst wie Postmark, Mailgun Inbound oder AWS SES mit Empfangsregeln. Kosten: Abrechnung pro Nachricht plus der Entwicklungsaufwand, um deinen KI-Agenten an die Webhook-Receiver anzubinden. Das ist die richtige Wahl, wenn der Agent hohes Volumen verarbeiten, Mails nach Header-Regeln routen oder bei jeder Nachricht automatisierte Workflows auslösen muss. Für einen projektspezifischen Agenten, der dutzende bis hunderte Mails im Monat verarbeitet, ist das überdimensioniert.

Für den Anwendungsfall aus dem Telegram-KI-Assistenten-Post — ein menschlicher Operator, zwei Projekt-Mitarbeiter, ein Claude-gestützter Bot — ist das dedizierte Postfach die richtige Wahl. Der Agent bekommt eine echte Adresse, die er per IMAP lesen, per SMTP versenden und die mit dem Projekt sauber anlaufen und abschalten kann.

Schritt 1: Die Subdomain im Mail-System registrieren

Der Mail-Anbieter muss wissen, dass deine Projekt-Subdomain eine seiner Domains ist, bevor er Mails dafür akzeptiert. Dieser Aufruf generiert auch das DKIM-Schlüsselpaar.

POST https://my.mailhost.example/api/v1/domain/create/
Authorization: Token <YOUR_MAIL_API_TOKEN>
Content-Type: application/json

[{"name": "system.example.com"}]

Die Antwort enthält drei Felder, die relevant sind: die Domain-UUID (die du für die Bereinigung und spätere Adress-Zuordnung brauchst), den state (meist PENDING_CREATE für wenige Sekunden, dann READY) und ein dkim_record-Feld mit einem fertig formatierten TXT-Wert, den du direkt ins DNS einfügen kannst:

{
  "id": "<DOMAIN_UUID>",
  "state": "PENDING_CREATE",
  "name": "system.example.com",
  "dkim_record": "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4G..."
}

Warte, bis state auf READY wechselt, und erfasse dann den dkim_record-Wert. Im nächsten Schritt fügst du ihn unverändert beim DNS-Anbieter ein. Wenn der Create-Aufruf mit einem invalid hostname-Fehler scheitert, liegt das meistens daran, dass dein Mail-Anbieter nur Second-Level-Domains unterstützt und bei drei Ebenen tiefen Subdomains streikt. Öffne ein Support-Ticket; in der Praxis ist uns noch kein Anbieter begegnet, der das dauerhaft verweigert hat.

Prüfe die DKIM-Schlüsselgröße, bevor du weitermachst. Ein dkim_record-Wert unter etwa 250 Bytes ist ein 1024-Bit-RSA-Schlüssel; 2048-Bit-Schlüssel liegen bei ungefähr 380–420 Bytes. NIST hat 1024-Bit-RSA 2013 als veraltet eingestuft, und Gmail, Microsoft, Yahoo und AWS SES behandeln 2048 Bit als Mindeststandard für 2026 — 1024-Bit-Schlüssel authentifizieren zwar noch, gelten aber in Enterprise-Spam-Filtern als schwaches Signal. Wenn dein Anbieter die Schlüsselgröße wählen lässt, nimm 2048; ein 1024-Bit-Standard ist ein Hinweis auf die Qualität des Anbieters.

Schritt 2: Die DNS-Records konfigurieren

Drei Records, alle beim DNS-Anbieter für die Projekt-Subdomain erstellt. Keiner davon darf über Cloudflares Edge geproxied werden — MX- und TXT-Records müssen DNS-only sein. Die Cloudflare-API setzt den Proxy bei nicht unterstützten Typen stillschweigend zurück, aber explizit ist sauberer.

Die zwei MX-Records teilen Absendern mit, wohin Mails zugestellt werden sollen. Die meisten Mail-Anbieter betreiben zwei oder mehr MX-Hosts mit gleicher Priorität für Round-Robin-Failover:

POST https://api.dnsprovider.example/zones/<ZONE_ID>/dns_records

{"type":"MX","name":"system.example.com",
 "content":"mx1.de.mailhost.example","priority":10,
 "ttl":3600,"proxied":false}

{"type":"MX","name":"system.example.com",
 "content":"mx2.de.mailhost.example","priority":10,
 "ttl":3600,"proxied":false}

Der DKIM-TXT-Record verwendet den dkim_record-Wert aus Schritt 1, platziert unter dkim._domainkey.<subdomain>:

{"type":"TXT",
 "name":"dkim._domainkey.system.example.com",
 "content":"v=DKIM1; k=rsa; p=MIGfMA0G...",
 "ttl":3600,"proxied":false}

Ist der öffentliche DKIM-Schlüssel länger als 255 Bytes — was bei 2048-Bit-RSA-Schlüsseln der Fall ist — muss er in mehrere quoted Chunks aufgeteilt werden: "chunk1" "chunk2". Die meisten DNS-Anbieter übernehmen das Aufteilen automatisch in ihrer API; wenn nicht, muss es auf deiner Seite passieren.

SPF und DMARC Records setzt du einmalig, auf der Subdomain selbst und auf _dmarc.<subdomain>. SPF teilt Empfängern mit, welche IPs berechtigt sind, für diese Domain zu senden; DMARC teilt ihnen mit, was zu tun ist, wenn SPF oder DKIM fehlschlägt:

{"type":"TXT","name":"system.example.com",
 "content":"v=spf1 include:spf.mailhost.example ~all",
 "ttl":3600,"proxied":false}

{"type":"TXT","name":"_dmarc.system.example.com",
 "content":"v=DMARC1; p=none; rua=mailto:[email protected]; aspf=r; adkim=r",
 "ttl":3600,"proxied":false}

Starte DMARC mit p=none. Das ist der Monitoring-Modus — Empfänger senden aggregierte Berichte an die rua-Adresse, lehnen Mails aber nicht basierend auf der Policy ab. Der Standard-Rollout sieht zwei bis sechs Wochen bei p=none vor, bis die Aggregatberichte mindestens 98 % legitime Mails ausweisen — dann eine schrittweise Erhöhung über den pct=-Parameter, zum Beispiel p=quarantine; pct=25 für zwei Wochen, dann pct=75, dann pct=100, dann schließlich p=reject. Den Rollout zu überspringen und direkt auf einer brandneuen Domain mit p=reject zu starten, ist ein zuverlässiger Weg, eigene legitime Mails zu verlieren, bevor der DKIM-Signing-Pfad verifiziert wurde.

Schritt 3: Postfach und Adress-Mapping erstellen

Das Datenmodell der meisten Mail-Anbieter besteht aus zwei separaten Ressourcen: einem Mailuser (dem IMAP-Account mit Zugangsdaten und Quota) und einer Adresse (dem local@domain-String, der Mails zu einem Mailuser routet). Sie sind getrennt, weil ein und derselbe Mailuser Ziel mehrerer verschiedener Adressen auf derselben oder unterschiedlichen Domains sein kann.

Generiere ein starkes Passwort und erstelle den Mailuser. Die Namenskonvention variiert je nach Anbieter; gängig ist <local>_<domain-mit-underscores>. Achte auf das Längenlimit — die meisten Anbieter begrenzen Mailuser-Namen auf 32 Zeichen, was bei einer längeren Subdomain leicht zu lang wird:

import secrets, string
alphabet = string.ascii_letters + string.digits + "!@#%^&*-_=+"
password = ''.join(secrets.choice(alphabet) for _ in range(32))

# Then:
POST /api/v1/mailuser/create/
[{"name": "bot_system_example_com",
  "imap_server": "<IMAP_SERVER_UUID>",
  "password": password}]

Sobald der Mailuser den Status READY hat, erstelle das Adress-Mapping, das local@subdomain mit ihm verknüpft:

POST /api/v1/address/create/
[{"source": "[email protected]",
  "destinations": ["<MAILUSER_UUID>"],
  "forwards": []}]

Das forwards-Array dient für zusätzliche externe Adressen, die eine Kopie erhalten sollen. Lasse es leer, außer du möchtest das Postfach parallel an eine menschliche Inbox weiterleiten — was während der Projektübergabephase nützlich sein kann, langfristig aber unübersichtlich wird.

Schritt 4: Das Setup End-to-End verifizieren

Vier Prüfungen, in dieser Reihenfolge. Den Self-Loopback nicht überspringen — er ist der einzige Test, der bestätigt, dass das eingehende Routing das Postfach tatsächlich erreicht.

DNS-Propagierung. Cloudflare-ähnliche AnyCast-Anbieter propagieren in der Regel in deutlich unter einer Minute. Schleife, bis beide Records erscheinen:

for i in $(seq 1 36); do
  mx=$(dig +short system.example.com MX)
  dkim=$(dig +short dkim._domainkey.system.example.com TXT)
  if [ -n "$mx" ] && [ -n "$dkim" ]; then break; fi
  sleep 5
done
echo "MX: $mx"
echo "DKIM: $dkim"

IMAP-Login. Bestätige, dass die Zugangsdaten funktionieren und das Postfach tatsächlich durch eine Inbox abgesichert ist:

openssl s_client -crlf -connect imap.mailhost.example:993 -quiet
a1 LOGIN bot_system_example_com <password>
a2 SELECT INBOX

Erwartete Antwort: a1 OK Logged in, gefolgt vom SELECT mit EXISTS 0 bei einem frischen Postfach.

Self-Loopback. Der beste End-to-End-Test: Eine Mail von der neuen Adresse an sich selbst schicken und prüfen, dass sie per IMAP ankommt. Das validiert den gesamten Pfad — SMTP-Authentifizierung, DKIM-Signing, MX-Auflösung, Mail-Annahme, Postfach-Zustellung, IMAP-Sichtbarkeit — ohne dass der Spam-Filter irgendeines externen Anbieters kooperieren muss:

import smtplib, ssl, imaplib, time
from email.message import EmailMessage

msg = EmailMessage()
msg["From"] = "[email protected]"
msg["To"]   = "[email protected]"
msg["Subject"] = "loopback test"
msg.set_content("hello self")

with smtplib.SMTP("smtp.mailhost.example", 587) as s:
    s.starttls(context=ssl.create_default_context())
    s.login("bot_system_example_com", "<password>")
    s.send_message(msg)

time.sleep(10)
imap = imaplib.IMAP4_SSL("imap.mailhost.example", 993)
imap.login("bot_system_example_com", "<password>")
imap.select("INBOX")
typ, search = imap.search(None, "ALL")
print("inbox count:", len(search[0].split()))

Suche in den Headern der zugestellten Mail nach der Authentication-Results-Zeile. Ein korrekt konfiguriertes Setup zeigt spf=pass mit dem richtigen smtp.mailfrom und einen DKIM-Signature-Header mit d=<deine Subdomain> und s=dkim. Sind diese vorhanden, funktioniert die gesamte Kette; die einzige verbleibende Variable ist, wie externe Empfänger dich einschätzen — darüber werden die DMARC-Berichte in den folgenden Tagen Aufschluss geben.

Externer Versand. Schicke eine Mail an eine externe Adresse, die du verifizieren kannst — ein persönliches Gmail-Konto, eine separate Arbeits-Inbox, irgendetwas außerhalb des eigenen Systems. Bestätige, dass sie im Posteingang landet, nicht im Spam. Wenn sie beim allerersten Versand von einer neuen Domain im Spam landet, liegt das meistens daran, dass die Sender-Reputation dieser Domain noch nicht existiert; der Aufbau ist ein gradueller Prozess, aber eine einzelne Test-Mail sollte sauber durchkommen, weil der Empfänger DKIM und SPF eigenständig bewertet — unabhängig vom bisherigen Versandvolumen.

Häufige Stolperfallen

Das 32-Zeichen-Limit für Mailuser-Namen trifft einen, sobald Subdomain plus Local-Part länger als erwartet sind. backoffice_dashboard_system_example_com hat neununddreißig Zeichen und wird abgelehnt; bo_dashboard_system_example_com passt mit einunddreißig. Wähle Abkürzungen bewusst, anstatt sie mitten beim Deployment von der API aufgezwungen zu bekommen.

Die Cloudflare-Proxy-Falle. Cloudflares UI lässt dich die Orange-Cloud-Proxy für jeden Record umschalten. Für A/AAAA auf einem Web-Origin willst du sie fast immer aktiviert haben. Für MX-Records ist sie immer aus — Cloudflare proxied keine Mails. Die Falle tritt auf, wenn du per Skript massenweise Proxying aktivierst und dabei versehentlich MX-Records einschließt. Cloudflare ignoriert das Proxy-Flag für nicht unterstützte Typen stillschweigend, sodass es so aussieht, als hätte es funktioniert — und du verlierst Minuten damit, herauszufinden, warum nichts falsch ist.

Greylisting bei der ersten eingehenden Mail. Mail-Systeme stellen die erste Nachricht eines unbekannten Absenders manchmal in die Greylist — temporäre 4xx-Antwort, Aufforderung an den Absender, in ein paar Minuten erneut zu versuchen. Gmail wiederholt automatisch. Wenn dein erster eingehender Smoke-Test fehlzuschlagen scheint, warte fünfzehn Minuten, bevor du ihn als broken einschätzt.

Das SPF-DNS-Lookup-Limit. SPF hat ein hartes Limit von zehn DNS-Lookups während der Auswertung (RFC 7208 §4.6.4). Ein einzelnes include:spf.mailhost.example zählt als ein Lookup, auch wenn das Include intern dutzende IPs auflöst. Das Limit wirst du erst überschreiten, wenn du mehrere Absender kettest — zum Beispiel, wenn du später include:_spf.resend.com für eine Marketing-Pipeline hinzufügst. Plane den SPF-Record für die langfristige Absender-Liste, nicht nur für den ersten.

Leeres dkim_privkey auf der Mail-Anbieter-Seite. Manche Anbieter bieten einen Domain-Create-Endpunkt an, der erfolgreich antwortet, aber keinen DKIM-Key generiert — dafür ist ein separater „DKIM aktivieren“-Aufruf notwendig. Prüfe, dass das dkim_record-Feld in deiner Create-Antwort nicht leer ist, bevor du weitermachst. Ist es leer, schau in der Provider-Dokumentation nach dem sekundären Aufruf.

Naives Monitoring des Deployments. Wenn du dutzende Domains betreibst, wird ein defekter DKIM-Record oder eine abgelaufene DMARC-Report-Zieladresse im Routine-Monitoring nicht auffallen, außer du prüfst das aktiv. Unsere monatliche Health-Check-Routine für selbst gehostete Dienste enthält genau deshalb einen Mail-Record-Audit-Schritt.

MTA-STS überspringen, wo es verfügbar ist. MTA-STS veröffentlicht eine Policy, die Absender zwingt, TLS zu deinen MX-Hosts zu verwenden und das Zertifikat zu validieren. Gmail, Microsoft 365 und Yahoo prüfen darauf; die weltweite Verbreitung liegt noch unter einem Prozent, sodass eine gültige Policy ein kleines Reputationssignal ist. Der Nachteil ist operativer Natur: eine Policy, die auf MX-Hosts verweist, die die TLS-Validierung nicht bestehen, blockiert legitime eingehende Mails. Wenn dein Anbieter MTA-STS anbietet, aktiviere es, nachdem DKIM und DMARC stabil sind.

Rollback-Pfad

Wenn die Verifikation fehlschlägt oder du entscheidest, dass das Projekt doch kein eigenes Postfach braucht, ist die Bereinigung idempotent und dauert fünf Minuten:

  1. POST /api/v1/address/delete/ mit der Adress-UUID
  2. POST /api/v1/mailuser/delete/ mit der Mailuser-UUID
  3. POST /api/v1/domain/delete/ mit der Mail-System-Domain-UUID (löscht auch die DKIM-Keys)
  4. DELETE /zones/<zone>/dns_records/<id> für jeden der drei DNS-Records

Die Reihenfolge ist wichtig, weil manche Anbieter das Löschen der Domain verweigern, solange noch Adressen daran hängen. Die umgekehrte Reihenfolge gibt dir außerdem einen sinnvollen Haltepunkt zum Prüfen — wenn Schritt 1 fehlschlägt, weil noch Mails im Postfach liegen, die du vergessen hast, hast du das DNS-Routing noch nicht verändert.

Die SPF- und DMARC-Records nach einem Rollback auf der Subdomain zu belassen ist harmlos. Sie authentifizieren zwar nichts, teilen künftigen Empfängern aber explizit mit, dass diese Subdomain keine legitimen Mails versendet — was ein kleiner Anti-Spoofing-Vorteil ist. Wir behandeln sie als Standard-aktiv, sobald sie einmal existieren. Dieses Denken in „sicheren Rückständen“ ist dieselbe Logik, die wir beim Disaster Recovery für selbst gehostete Dienste anwenden: das Cleanup-Pattern ist genauso wichtig wie das Install-Pattern.

Fazit

Ein projektspezifisches Postfach ist keine Infrastruktur — es ist ein kleines operatives Grundelement, das einem KI-Agenten oder jedem anderen automatisierten Prozess ermöglicht, vollwertiger Teilnehmer in E-Mail-basierten Workflows zu werden. Das Vier-API-Aufruf-Pattern lässt sich sauber zwischen Mail-Anbietern portieren; die DNS-Records lassen sich sauber zwischen DNS-Anbietern portieren. Was es wert ist, richtig zu machen, ist die Grenze zwischen den beiden Systemen: welcher Record wo liegt, wie die Fehlerbilder aussehen und wie man End-to-End verifiziert, ohne dabei auf den Spam-Filter irgendeines externen Anbieters angewiesen zu sein.

Wenn du Unterstützung beim Aufbau eines projektspezifischen Stacks möchtest — Telegram-Agent, Postfach, Dokumenten-Intake, alles zusammen — hilft tva gerne weiter.


Verwandte Insights

Weitere Artikel