Kapitel 17b Compliance, Storage & Betrieb Admin: #pArchiveSources

nextxch Archive: Microsoft 365, Exchange, Google Workspace und IMAP ins GoBD-Archiv

nextxch Archive übernimmt E-Mails aus Mailsystemen, die nicht auf nextxch laufen, in das GoBD-Archiv. Vier Quellarten stehen im Admin unter Compliance > Archiv-Quellen bereit: SMTP-Journal (Journalberichte aus Microsoft 365 und Exchange, Kopie-Regel aus Google Workspace, BCC-Kopien beliebiger MTAs), IMAP (jeder Server, nur lesend), Microsoft 365 über Microsoft Graph und Google Workspace über die Gmail API. Jedes Postfach der Quelle wird zu einem archivierten Postfach ohne Anmeldung und ohne Mailverkehr; Suche, Legal Hold, Beweisexport und Wiederherstellung arbeiten darauf wie auf eigenen Postfächern.

Praxis-Tipp & Architektur-Hinweis

Empfohlene Kombination: das SMTP-Journal für die vollständige laufende Erfassung ab einem Stichtag (Nutzer können vorher nichts löschen), dazu einmalig oder in großem Abstand die API-Quelle für den Bestand und die Ordneransicht. Beide schreiben in dasselbe Archiv, eine doppelt erfasste Nachricht wird über SHA-256 nur einmal gespeichert. Lizenz: Archivierte Postfächer fremder Systeme sind eine eigene Lizenzzeile, eigene nextxch-Postfächer zählen dort nicht. 10 archivierte Postfächer sind in jeder Stufe frei, weitere gibt es mit einer Business- oder Enterprise-Lizenz.

1. Schnellstart: Journal-Quelle für Microsoft 365 anlegen

Neue Quellen sind zunächst deaktiviert. Verbindung testen, dann aktivieren. Die Journal-Adresse erzeugt der Server mit geheimem Token, wenn nur die Domain angegeben ist; deren MX muss auf nextxch zeigen.

Referenz / Konfiguration
# 1. Admin > Compliance > Archiv-Quellen > Neue Quelle, Art "SMTP-Journal"
#    Domains der Altumgebung: firma.de · Journal-Domain: archiv.firma.de
#    -> Journal-Adresse z. B. journal-k3x9q2m7v1c8b4n6z5ta@archiv.firma.de (kopieren)
# 2. Schutz: IP-Bereiche der Exchange-Online-Server, TLS erforderlich, erlaubte Envelope-Absender
# 3. Microsoft Purview: Lösungen > Datenlebenszyklusverwaltung > Exchange (Legacy) > Journalregeln
#    oder Exchange Online PowerShell:
Set-TransportConfig -JournalingReportNdrTo journal-ndr@archiv.firma.de
New-JournalRule -Name "nextxch Archive" -JournalEmailAddress journal-k3x9q2m7v1c8b4n6z5ta@archiv.firma.de -Scope Global -Enabled $true
Get-JournalRule | Format-Table Name,Enabled,JournalEmailAddress,Scope
# 4. Testmail senden: die Quelle zeigt das Original mit allen Envelope-Empfängern (auch Bcc)

2. Journal aus Exchange vor Ort und Google Workspace

Exchange vor Ort: Journalregel mit derselben Journal-Adresse (Premium-Journaling, braucht die Exchange Enterprise CAL) oder Standard-Journaling je Postfachdatenbank an diese Adresse; in einer Hybridumgebung die Regel zusätzlich auf dem lokalen Exchange-Server anlegen. Google Workspace: eine Routing-Regel fügt die Journal-Adresse als weiteren Empfänger hinzu, Google Vault ist nicht nötig. Mit "Umfassender E-Mail-Speicher" landen auch Mails aus SMTP-Relay und Google-Diensten in den Postfächern. Jeder andere MTA sendet BCC-Kopien an die Journal-Adresse.

Referenz / Konfiguration
# Exchange Server (Exchange Management Shell)
New-JournalRule -Name "nextxch Archive" -JournalEmailAddress journal-k3x9q2m7v1c8b4n6z5ta@archiv.firma.de -Scope Global -Enabled $true

# Google Admin-Konsole: Menü > Apps > Google Workspace > Gmail > Routing > Konfigurieren
#   Betroffene Nachrichten: eingehend, ausgehend, intern eingehend, intern ausgehend
#   Aktion: Nachricht ändern > Weitere Empfänger hinzufügen > Erweitert > Journal-Adresse
#   Optional: Spam nicht an diesen Empfänger zustellen, Unzustellbarkeitsberichte unterdrücken
# Journal-Quelle in nextxch: Format bcc oder auto, IP-Bereiche der Google-Ausgangsserver, TLS erforderlich

3. IMAP: beliebiger Server, nur lesend

Ordner werden mit EXAMINE geöffnet und Inhalte mit BODY.PEEK[] geholt, Flags an der Quelle ändern sich nie. Ein Cursor je Ordner (UIDVALIDITY, letzte UID, HIGHESTMODSEQ bei CONDSTORE) wird nach jeder Nachricht fortgeschrieben, ein Abbruch setzt genau dort fort. TLS ist Pflicht (implizit oder STARTTLS), optional mit festgelegtem Zertifikat (SHA-256); Anmeldung per Passwort oder XOAUTH2, ein Konto oder eine Liste von Konten. Papierkorb und Spam werden standardmäßig übersprungen.

Referenz / Konfiguration
{
  "host": "imap.althoster.de",
  "tls": "implicit",
  "auth": "password",
  "mode": "single",
  "username": "buchhaltung@firma.de",
  "address": "buchhaltung@firma.de",
  "excludeFolders": ["Entwürfe"],
  "since": "2016-01-01",
  "maxConnections": 2
}
# Geheimnis: password (bzw. oauthToken bei xoauth2), im Listenmodus accounts/<id>/password

4. Microsoft 365 über Microsoft Graph: App-Registrierung in Entra ID

Die Quelle liest den Bestand und neue Mails mit Delta-Abfragen je Ordner, ohne EWS (Microsoft schaltet EWS in Exchange Online ab). Anwendungsberechtigungen in Microsoft Graph mit Administratorzustimmung: Mail.Read und User.Read.All, GroupMember.Read.All nur beim Benutzerfilter "Gruppe". Anmeldung per Zertifikat (empfohlen) oder Client-Geheimnis, Clouds global, usgov, usgovdod und china. Das Drosseln durch Graph (429 mit Retry-After) wird beachtet, ein Lauf setzt an der letzten vollständig verarbeiteten Seite fort. In der Quelle gelöschte Nachrichten bleiben im Archiv. Optional begrenzt Exchange Online RBAC for Applications den Zugriff auf eine Gruppe.

Referenz / Konfiguration
# Entra Admin Center > App-Registrierungen > Neue Registrierung "nextxch Archive" (nur dieser Mandant)
# API-Berechtigungen > Microsoft Graph > Anwendungsberechtigungen:
#   Mail.Read, User.Read.All (+ GroupMember.Read.All bei Gruppenfilter) > Administratorzustimmung erteilen
# Zertifikate & Geheimnisse: Zertifikat (.cer) hochladen oder Client-Geheimnis anlegen
{
  "tenantId": "firma.onmicrosoft.com",
  "clientId": "11111111-2222-3333-4444-555555555555",
  "credentialType": "certificate",
  "cloud": "global",
  "userFilter": { "mode": "group", "groupId": "99999999-0000-0000-0000-000000000009" },
  "sinceUtc": "2019-01-01T00:00:00Z"
}
# Geheimnisse: certificatePfx (Base64) + certificatePassword oder clientSecret (der Wert, nicht die ID)

5. Google Workspace über die Gmail API: Service-Account und domänenweite Delegation

Ein Service-Account im eigenen Google-Cloud-Projekt des Kunden (Gmail-Quoten gelten je Projekt) mit aktivierter Gmail API und Admin SDK API. In der Admin-Konsole wird seine numerische Client-ID für die domänenweite Delegation mit den Scopes gmail.readonly und admin.directory.user.readonly freigegeben, für den Filter "Gruppe" zusätzlich admin.directory.group.member.readonly. Erstimport über messages.list und messages.get (raw), danach History-Sync; ist die History abgelaufen, startet der Import neu und bereits archivierte Nachrichten zählen als Duplikate. Das Quota-Budget je Benutzer und Projekt ist einstellbar.

Referenz / Konfiguration
# Admin-Konsole: Sicherheit > Zugriffs- und Datenverwaltung > API-Steuerung > Domainweite Delegation
#   Client-ID (numerisch) + Scopes:
#   https://www.googleapis.com/auth/gmail.readonly,
#   https://www.googleapis.com/auth/admin.directory.user.readonly
{
  "adminSubject": "admin@firma.de",
  "domain": "firma.de",
  "userFilter": "orgUnit",
  "orgUnitPath": "/Vertrieb",
  "sinceUtc": "2018-01-01T00:00:00Z",
  "quotaUnitsPerUserMinute": 4800
}
# Geheimnis: serviceAccountKey (JSON-Schlüsseldatei des Service-Accounts)

6. Speicherung, WORM-Aufbewahrung und Legal Hold

Jedes archivierte Postfach hat einen eigenen, reinen Archivspeicher im GoBD-Archiv. Je Nachricht: SHA-256-Inhaltsadresse mit Deduplizierung über alle Postfächer, Duplikatprüfung je Postfach über SHA-256 und Message-ID, WORM-Aufbewahrung und Legal Hold der Quelle auf Blob und Nachricht, Hash-Kette als Manipulationsnachweis und Volltextindex. Der Verlauf je Lauf zählt gespeicherte, doppelte und abgelehnte Nachrichten.

Referenz / Konfiguration
Aufbewahrung   RetentionDays 0..36500 (0 = keine WORM-Aufbewahrung)
Modus          Normal | Governance | Compliance (Standard)
Legal Hold     je Quelle, wirkt auch auf bereits archivierte Nachrichten
Speicher       lokal oder S3 mit Object Lock (wie das übrige GoBD-Archiv)
Status         je Postfach: letzter Lauf, nächster Lauf, gespeichert, Duplikate, abgelehnt, Fehler

7. Suchen, exportieren, wiederherstellen

Archivierte Postfächer stehen in der Compliance-Suche als eigener Bereich zur Wahl (deutsche Suche mit Wortteilen, OCR in Anhängen, ZUGFeRD-Felder) und haben in der Liste je eine Schaltfläche für Suche, Beweisexport und Wiederherstellung. Der Beweisexport liefert ein ZIP mit Original-.eml und Ed25519-signiertem Manifest (siehe Kapitel 17a). Die Wiederherstellung kopiert in ein nextxch-Postfach, das Archiv bleibt unverändert. Ein Rückspielen in Microsoft 365, Google oder den IMAP-Server gibt es noch nicht; dafür steht der Export bereit. Suche in jeder Stufe, Beweisexport und Wiederherstellungsaufträge ab Business.

Referenz / Konfiguration
# Suche in einem archivierten Postfach
curl -s "https://mail.firma.de/api/compliance/search?archivedMailboxId=<id>&q=Rechnung&limit=100" -H "X-Api-Key: $KEY"

# Beweisexport eines archivierten Postfachs (202, Status unter GET /api/compliance/exports/{id})
curl -X POST https://mail.firma.de/api/compliance/exports -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
  -d '{"scope":"mailbox","archivedMailboxId":"<id>","caseReference":"AZ 4 O 123/26"}'

# Wiederherstellung in ein nextxch-Postfach
curl -X POST https://mail.firma.de/api/compliance/restore/jobs -H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
  -d '{"source":"archive","account":"archived:<id>","target":"account","targetAccount":"nachfolger@firma.de"}'

8. Admin-API: /api/admin/archive-sources

TenantAdmin im eigenen Mandanten, ServerAdmin überall; der ComplianceAuditor liest (um archivierte Postfächer für Suche und Export zu wählen), ändert aber nichts. Kind ist Journal, Imap, Microsoft365 oder Google. Das Aktivieren eines Postfachs über das Lizenzkontingent hinaus wird mit einer Meldung samt aktueller Lizenzzeile abgelehnt. Journal-Quellen empfangen per SMTP, für sie gibt es keinen Lauf (409 JOURNAL_IS_PUSHED).

Referenz / Konfiguration
GET    /api/admin/archive-sources                          Quellen, Lizenzzeile, verfügbare Arten mit Feldern
GET    /api/admin/archive-sources/license                  used, allowed, free, remaining
POST   /api/admin/archive-sources                          Quelle anlegen
GET    /api/admin/archive-sources/{id}                     Quelle, Postfächer, Namen der Geheimnisse
PUT    /api/admin/archive-sources/{id}                     ändern (Einstellungen, Aufbewahrung, Legal Hold, Zeitplan)
DELETE /api/admin/archive-sources/{id}                     löschen
POST   /api/admin/archive-sources/{id}/test                Verbindungstest
POST   /api/admin/archive-sources/{id}/discover            Postfächer erkennen
GET    /api/admin/archive-sources/{id}/mailboxes           archivierte Postfächer
PUT    /api/admin/archive-sources/{id}/mailboxes/{mbxId}   {"enabled": true} innerhalb der Lizenzzeile
POST   /api/admin/archive-sources/{id}/run                 jetzt abrufen, optional {"mailboxId": "..."}
GET    /api/admin/archive-sources/{id}/runs                Verlauf (mailboxId, limit)

curl -X POST https://mail.firma.de/api/admin/archive-sources -H "X-Api-Key: $KEY" -H "Content-Type: application/json" -d '{
  "kind": "Journal", "name": "Microsoft 365 Journal", "journalDomain": "archiv.firma.de",
  "settings": { "domains": ["firma.de"], "allowedSenderNetworks": ["203.0.113.0/24"], "requireTls": true },
  "retentionDays": 3650, "lockMode": "Compliance" }'

Einstellungen, Standardwerte & Best Practices

Einstellung / Ort Funktion Standardwert Best Practice im Betrieb
Journal: Domains (domains) Nur Envelope-Adressen dieser Domains und ihrer Subdomains werden zu archivierten Postfächern (bei aktiver automatischer Erkennung beim ersten Auftreten). Nachrichten ohne passende Adresse landen im Postfach "Journal ohne Zuordnung" der Quelle, das nicht zur Lizenz zählt. leer · automatische Erkennung an Alle Domains der Altumgebung eintragen, sonst fehlen Postfächer in der Zuordnung.
Journal: Schutz (allowedSenderNetworks, requireTls, allowedEnvelopeSenders) Erlaubte IP-Adressen oder CIDR-Bereiche der sendenden Server, Annahme nur über TLS (STARTTLS oder implizit) und erlaubte Envelope-Absender (Adresse, *@domain oder Domain). Eine Journal-Adresse braucht entweder eine IP-Liste oder ein geheimes Token im lokalen Teil (mindestens 16 Zeichen, vom Server erzeugt). keine IP-Liste · TLS aus · alle Absender IP-Bereiche des Anbieters und TLS-Pflicht setzen; das Token zusätzlich behalten.
Journal: Format (format) auto erkennt einen Journalbericht an X-MS-Journal-Report; envelope erzwingt die Auswertung als Exchange- bzw. Microsoft-365-Bericht, bcc behandelt jede Mail als Kopie (Google-Kopie-Regel, andere MTAs). auto auto beibehalten, außer ein MTA sendet BCC-Kopien mit eigenen Kopfzeilen.
Aufbewahrung (RetentionDays, LockMode) WORM-Aufbewahrung in Tagen je Quelle (0 bis 36 500, 0 = keine WORM-Aufbewahrung) mit Modus Normal, Governance oder Compliance. Gilt für Blob und Nachricht jeder archivierten Mail. Compliance Für Handelsbriefe und Buchungsbelege die gesetzliche Frist wählen; Compliance lässt sich vor Ablauf nicht aufheben.
Legal Hold (LegalHold) Sperrt alle Nachrichten der Quelle gegen Löschung, auch über die Aufbewahrung hinaus. Beim Einschalten wird der Hold auch auf bereits archivierte Nachrichten gesetzt; jede Änderung steht im Audit-Log. aus Bei Rechtsstreit oder Prüfung einschalten und erst nach Freigabe durch die Rechtsabteilung wieder aufheben.
Zeitplan und Erkennung (ScheduleMinutes, AutoDiscover) Abrufintervall der API-Quellen (IMAP, Microsoft 365, Google) von 5 Minuten bis 7 Tage; im Cluster läuft der Abruf nur auf dem Leader. Journal-Quellen empfangen per SMTP und haben keinen Zeitplan. 60 min Für den Erstimport großer Mandanten den Lauf manuell starten und den Verlauf je Postfach beobachten.
Geheimnisse (Secrets) Passwörter, Client-Geheimnisse, Zertifikate und Service-Account-Schlüssel liegen verschlüsselt im Schlüsselbund des Servers. Sie sind nur schreibbar: Antworten der API enthalten nur ihre Namen, nie die Werte, und sie erscheinen nicht in Logs. verschlüsselt Ablaufdaten von Client-Geheimnis und Zertifikat notieren; der Verbindungstest meldet ein abgelaufenes Geheimnis.