Zum Inhalt springen
Avanet

Sophos Email S/MIME per API automatisieren

Mit der Sophos Email Management API lässt sich der vollständige S/MIME-Zertifikatslebenszyklus steuern. Die sichere Reihenfolge lautet: Bestand lesen, genau eine interne Tenant-CA erstellen oder hochladen, die Tenant-Konfiguration zunächst deaktiviert anlegen, Vertrauens- und externe Empfängerzertifikate bereitstellen, S/MIME aktivieren, interne Benutzerzertifikate bereitstellen und anschliessend den Mailfluss testen. Dieser Artikel trennt bewusst interne Tenant-CA, vertraute externe CAs, interne Benutzerzertifikate und externe Empfängerzertifikate. Sie haben unterschiedliche Pfade und dürfen nicht gegeneinander ausgetauscht werden.

Für Architektur, Policy und Tests in der Oberfläche hilft die GUI-Anleitung zu S/MIME. Den allgemeinen API-Vertrag erklärt der Einstieg in die Sophos Email Management API; OAuth2, Tenant-Auflösung und Regionalhost werden im geplanten API-Authentifizierungs- und Tenant-Routing-Runbook behandelt.

Kritische Warnung: DELETE /smime/config/{deleteToken} löscht alle S/MIME-Zertifikate und privaten Schlüssel des Tenants und setzt smimeEnabled auf false. Das ist kein Zertifikatswechsel und keine normale Fehlerbehebung. Die API dokumentiert keinen Export privater Schlüssel. Ohne separat verwahrte, autorisierte PKCS#12-Quellen können Schlüssel und die Entschlüsselbarkeit historischer Inhalte dauerhaft verloren gehen.

Voraussetzungen und sichere Request-Basis

Übernimm aus dem Authentifizierungsablauf nur diese validierten Werte:

  • SOPHOS_ACCESS_TOKEN: kurzlebiger Bearer-Token;
  • SOPHOS_TENANT_ID: UUID des Ziel-Tenants;
  • SOPHOS_API_HOST: vollständiger regionaler Host dieses Tenants.

Die geprüfte Spezifikation ist Email Management API v1.4.0. Vor jeder Implementierung muss die aktuelle Spezifikation erneut geprüft werden. Alle folgenden Pfade hängen an der regionalen Basis /email/v1 und benötigen Authorization: Bearer ***, X-Tenant-ID und bei JSON-Requests Content-Type: application/json:

EMAIL_API_HOST="${SOPHOS_API_HOST%/}/email/v1"

Token, deleteToken, PKCS#12-Passwörter, PKCS#12-Inhalte und private Schlüssel gehören nicht in Kommandozeilenargumente, Quellcode, normale Logs oder Tickets. Verwende Dateien mit Modus 600, einen freigegebenen Secret Store und bereinige temporäre Dateien. Die Beispiele verwenden ops@example.net und alice@example.net; beide Werte müssen durch freigegebene Adressen des Ziel-Tenants ersetzt werden.

Vor dem ersten Schreibzugriff führe diese drei Lesetests aus und protokolliere nur HTTP-Status, requestId/correlationId bei Fehlern und das Schemaergebnis:

GET /smime/config
GET /smime/ca/internal
GET /smime/users/internal?pageSize=1

404 bei den ersten beiden Reads bedeutet, dass Konfiguration beziehungsweise interne CA noch nicht existiert. Das ist ein Zustand, kein Anlass, Pfade zu erraten. Listen liefern items und pages; pages.nextKey wird URL-kodiert als pageFromKey an die nächste Anfrage übergeben, bis kein nextKey mehr vorhanden ist.

Interne Tenant-CA bereitstellen

Die interne CA signiert von Sophos erzeugte Zertifikate für interne Benutzer. Pro Tenant ist genau eine interne CA möglich. Sowohl Erstellen als auch Hochladen erzeugt bei Bedarf automatisch eine deaktivierte S/MIME-Konfiguration, aktiviert S/MIME aber nicht. Ein zweiter Versuch trifft auf 409; es gibt in der geprüften API keinen separaten Pfad zum Löschen oder Ersetzen nur dieser CA.

Variante A: CA durch Sophos erzeugen

POST /smime/ca/internal erwartet organizationName, locality, country und email. country besteht aus genau zwei Grossbuchstaben nach ISO 3166-1. Optional sind organizationUnit sowie entweder certExpiryDate im Format YYYY-MM-DD oder certValidityPeriod von 1 bis 20 Jahren. Ohne Gültigkeitsangabe gelten 20 Jahre; bei beiden Angaben verwendet die API den kürzeren Zeitraum.

{
  "organizationName": "Example Operations GmbH",
  "organizationUnit": "Messaging",
  "locality": "Zurich",
  "country": "CH",
  "email": "ops@example.net",
  "certValidityPeriod": 10
}

Erfolg ist 201. Speichere den zurückgegebenen 64-stelligen SHA-256-fingerprint, issuer, validFrom, expiresAt und origin, ohne die vollständige Antwort unnötig zu protokollieren.

Variante B: bestehende CA samt Schlüssel hochladen

POST /smime/ca/internal/certificate erwartet einen Base64-kodierten PKCS#12-Zertifikat-Schlüssel-Bundle, nicht PEM:

{
  "pkcs12": "<BASE64_PKCS12>",
  "password": "<PKCS12_PASSWORD>"
}

pkcs12 muss nach Base64-Kodierung 1200 bis 24000 Zeichen umfassen, password 3 bis 50 Zeichen. Vor dem Request prüft der PKI-Owner Zertifikat, privaten Schlüssel, Kette, Zweck und Passwort. Base64 ist nur Transportkodierung und schützt den privaten Schlüssel nicht. Zeilenumbrüche aus der Base64-Ausgabe entfernen; niemals einen PEM-Text in pkcs12 einsetzen.

Nach beiden Varianten validierst du unabhängig:

  1. GET /smime/ca/internal liefert Metadaten und denselben fingerprint.
  2. GET /smime/ca/internal/certificate liefert das öffentliche CA-Zertifikat als PEM mit application/octet-stream.
  3. Der heruntergeladene PEM-Fingerprint stimmt mit dem Change-Inventar überein. Die Datei enthält keinen wiederherstellbaren privaten CA-Schlüssel.

Tenant-Konfiguration erst danach aktivieren

GET /smime/config liefert smimeEnabled, extractCertificate, bis zu fünf certExpiryNotificationEmailAddresses und den acht Zeichen langen deleteToken. Behandle den Token wie ein destruktives Secret.

Existiert trotz Precheck keine Konfiguration, legt POST /smime/config sie an. smimeEnabled ist Pflicht, extractCertificate hat standardmässig false:

{
  "smimeEnabled": false,
  "extractCertificate": false,
  "certExpiryNotificationEmailAddresses": ["ops@example.net"]
}

Für eine vorhandene Konfiguration verwendet man PATCH /smime/config. Mindestens ein Feld ist erforderlich; ausgelassene Felder bleiben unverändert. null oder [] löscht bei PATCH alle Benachrichtigungsadressen, Duplikate werden entfernt. Der sichere Rollout ist:

  1. Konfiguration mit smimeEnabled: false schreiben und per GET bestätigen.
  2. Vertraute CAs und externe Pilot-Zertifikate bereitstellen und inventarisieren.
  3. Erst dann PATCH /smime/config mit {"smimeEnabled":true} senden. Ohne interne CA antwortet die API mit 409.
  4. Per GET smimeEnabled: true bestätigen, interne Pilot-Zertifikate erstellen oder hochladen und Signatur-/Verschlüsselungstests durchführen.

extractCertificate: true erlaubt die Extraktion aus eingehenden Nachrichten. Die fachlichen Voraussetzungen, insbesondere die Signaturprüfung in der Secure-Message-Policy, bleiben dieselben wie in der GUI-Anleitung; der API-Schalter allein macht ein Zertifikat nicht vertrauenswürdig.

Vertraute externe CAs verwalten

Diese Liste enthält zusätzliche Aussteller zur Verifikation signierter Nachrichten. Sie ist weder die interne Tenant-CA noch ein Benutzerzertifikat. Prüfe vor einem Upload in Sophos Fusion (ehemals Sophos Central), ob der Aussteller bereits global vertraut wird, und verifiziere den SHA-256-Fingerprint über einen unabhängigen Kanal.

  • GET /smime/cas/external listet Metadaten. Filter sind commonName, certValidBefore, certValidAfter, certExpiryBefore, certExpiryAfter, certFingerprint, issuerCN, pageFromKey und pageSize (Default 50).
  • POST /smime/cas/external/certificate lädt einen PEM-CA-Text im Feld certificate hoch. Das Feld umfasst 300 bis 32000 Zeichen einschliesslich Header und Footer.
  • GET /smime/cas/external/certificate/{fingerprint} lädt genau dieses PEM herunter.
  • DELETE /smime/cas/external?certFingerprint=... löscht genau diesen Vertrauenseintrag.
{
  "certificate": "-----BEGIN CERTIFICATE-----\n<BASE64_CERTIFICATE>\n-----END CERTIFICATE-----"
}

Ein identisches Zertifikat ergibt beim Upload 409. Vor dem DELETE muss ein exakter List-Read mit certFingerprint genau einen erwarteten Eintrag liefern. Nach 200 und deleted: true muss derselbe Filter leer sein; danach eine Testsignatur über die verbleibende Vertrauenskette prüfen.

Externe Empfängerzertifikate verwalten

Externe Benutzerzertifikate sind öffentliche Zertifikate von Kommunikationspartnern. Sie enthalten keinen privaten Tenant-Schlüssel. POST /smime/users/external/certificate übernimmt einen PEM-Text im Feld certificate (300 bis 32000 Zeichen), leitet die Identität aus dem Zertifikat ab und aktiviert S/MIME für diesen externen Benutzer:

{
  "certificate": "-----BEGIN CERTIFICATE-----\n<BASE64_CERTIFICATE>\n-----END CERTIFICATE-----",
  "confirmVerificationOnlyCert": false
}

Bei einem DSA- oder EC-Zertifikat muss confirmVerificationOnlyCert: true die bewusste Einschränkung auf Signieren/Verifizieren bestätigen; es kann dann nicht für Verschlüsselung/Entschlüsselung verwendet werden. Eine Identität kann höchstens zwei Zertifikate haben (422 beim nächsten Upload); ein Duplikat ergibt 409.

  • GET /smime/users/external?email=partner@example.net filtert nach exakter Adresse. Zusätzlich gibt es emailStartsWith, die Datums-, Fingerprint- und Issuer-Filter sowie pageFromKey/pageSize wie oben.
  • GET /smime/users/external/certificate/{fingerprint} lädt ein PEM anhand des 64-stelligen SHA-256-Fingerprints.
  • DELETE /smime/users/external?email=...&certFingerprint=... löscht nur das exakte Adress-/Fingerprint-Paar. Die Parameter müssen URL-kodiert werden. Beim letzten Zertifikat verschwindet der Benutzer automatisch aus der S/MIME-Liste.

Nach Upload müssen exakte E-Mail-Adresse, fingerprint, Aussteller und Gültigkeit im List-Read stimmen. Erst dann mit einer Pilot-Policy eine verschlüsselte Nachricht senden und beim vorgesehenen Partner entschlüsseln lassen.

Interne Benutzerzertifikate erstellen oder hochladen

Interne Benutzer müssen als passende Tenant-Identität existieren. Ein API-Create oder -Upload aktiviert S/MIME für den Benutzer. Vermeide Adressnormalisierung im Automationscode: Für Filter und Löschungen wird die exakte E-Mail-Adresse aus dem GET-Ergebnis weiterverwendet.

Für ein durch Sophos erzeugtes Zertifikat sendet man POST /smime/users/internal:

{
  "email": "alice@example.net",
  "certValidityPeriod": 3
}

Nur email ist Pflicht. Optional gelten dieselben Regeln für certExpiryDate beziehungsweise certValidityPeriod von 1 bis 20 Jahren wie bei der internen CA. Die interne CA und aktivierte/configurierte S/MIME-Funktion sind Voraussetzung.

Für einen vorhandenen Schlüssel sendet man POST /smime/users/internal/certificate:

{
  "email": "alice@example.net",
  "pkcs12": "<BASE64_PKCS12>",
  "password": "<PKCS12_PASSWORD>",
  "confirmSigningOnlyCert": false
}

email, pkcs12 und password sind Pflicht. Es gelten erneut 1200 bis 24000 Base64-Zeichen und 3 bis 50 Passwortzeichen. DSA/EC benötigt confirmSigningOnlyCert: true und ist dann nur für Signieren/Verifizieren, nicht für Verschlüsseln/Entschlüsseln geeignet. Enthält der Bundle CA-Zertifikate, speichert Sophos diese zusätzlich als vertraute CAs; prüfe daher vorab jede enthaltene Kette und danach die Liste /smime/cas/external. Pro internem Benutzer sind höchstens zwei Zertifikate möglich; Duplikate liefern 409, das dritte Zertifikat 422.

  • GET /smime/users/internal?email=alice@example.net liefert den exakten Benutzer und seine Zertifikate. Weitere Filter sind userName, emailStartsWith, Datums-, Fingerprint- und Issuer-Filter sowie Pagination.
  • GET /smime/users/internal/certificate/{fingerprint} lädt PEM. Bei einem hochgeladenen Bundle enthält der Download auch die damit hochgeladenen CA-Zertifikate, aber keinen privaten Schlüssel.
  • DELETE /smime/users/internal?email=...&certFingerprint=... löscht nur dieses Paar. Beim letzten Zertifikat verschwindet der Benutzer aus der S/MIME-Liste.

Nach jedem Create oder Upload müssen 201, exakte Adresse, erwarteter Fingerprint, Aussteller und Ablaufdatum bestätigt werden. Teste anschliessend ausgehendes Signieren und eingehendes Entschlüsseln mit der vorgesehenen Secure-Message-Policy.

Destruktiven Reset nur als genehmigten Wiederaufbau ausführen

Freigabe erforderlich: Führe den folgenden Ablauf nur mit ausdrücklicher Change-Freigabe durch. Konsequenz: interne CA, vertraute CAs, interne und externe Benutzerzertifikate sowie sämtliche dazu gespeicherten privaten Schlüssel werden gelöscht; smimeEnabled wird false. Ein einzelnes Objekt kann damit nicht gezielt repariert werden.

Precheck und Freigabenachweis müssen enthalten:

  1. GET /smime/config, /smime/ca/internal, /smime/cas/external, /smime/users/internal und /smime/users/external vollständig über alle Seiten inventarisieren.
  2. Für jedes wiederaufbaubare Schlüsselobjekt eine autorisierte PKCS#12-Quelle samt getesteter Passwort-Wiederherstellung bestätigen. PEM-Downloads sind kein Private-Key-Backup.
  3. Policy-Scope, Wartungsfenster, Owner, Kommunikationspartner, erwarteten Ausfall und vollständige Wiederaufbaureihenfolge dokumentieren.
  4. Den aktuellen deleteToken unmittelbar aus GET /smime/config beziehen, nicht aus alten Logs oder Tickets.
  5. Eine zweite autorisierte Person lässt Tenant-ID, Inventar, Konsequenz und Token-Zuordnung gegenlesen.

Erst danach lautet der exakte Aufruf DELETE /smime/config/{deleteToken}. Ein nicht passender Token ergibt 409, eine fehlende Konfiguration 404. Bei Timeout, 5xx oder unbekanntem Ergebnis nicht blind wiederholen: zuerst GET /smime/config und alle Inventar-Endpunkte lesen, um die serverseitige Wirkung festzustellen. Erfolg verlangt 200 und deleted: true; danach muss die Konfiguration fehlen oder neu mit smimeEnabled: false aufgebaut werden. Der Wiederaufbau folgt wieder ab interner CA, deaktivierter Konfiguration, Vertrauen, Benutzern und abschliessender Aktivierung.

Validierung und Fehlerdiagnose

Eine API-Antwort allein beweist keinen funktionierenden S/MIME-Mailfluss. Nimm nach Änderungen immer beide Ebenen ab:

  1. API-Zustand: GET-Readback über den exakten Pfad; E-Mail-Adresse, 64 Hex-Zeichen langer SHA-256-Fingerprint, issuer, validFrom, expiresAt, origin, Seitenende und Konfiguration prüfen.
  2. Nachrichtenwirkung: mit einer kleinen Secure-Message-Pilot-Policy ausgehend signieren, eingehend verifizieren, an den externen Pilotpartner verschlüsseln und für den internen Piloten entschlüsseln. Message-ID, UTC-Zeit und Ergebnis festhalten, aber keine Schlüssel oder vollständigen Zertifikats-Payloads protokollieren.

Typische Fehler lassen sich so eingrenzen:

  • 400: JSON-Feldnamen, PEM-Header/Footer, Base64 ohne Zeilenumbrüche, PKCS#12-Passwort, Längen, Datumsformat und E-Mail-Syntax prüfen. Bei Validierungsantworten die einzelnen errors auswerten.
  • 401/403: Token, minimale Berechtigung und Tenant-Zuordnung prüfen; weder Region noch Tenant erraten.
  • 404: zuerst Regionalhost, exakten Pfad, E-Mail-/Fingerprint-Paar und Objektbestand prüfen.
  • 409: interne CA oder Zertifikat existiert bereits, interne CA fehlt beim Aktivieren oder deleteToken passt nicht. Zustand lesen statt den Schreibzugriff zu wiederholen.
  • 422: Benutzer hat bereits zwei Zertifikate. Nicht durch Löschen eines unbekannten Fingerprints umgehen.
  • Unerwarteter List-Read: alle Seiten über pages.nextKey abrufen, pageFromKey URL-kodieren und exakte statt Präfixfilter verwenden.
  • Signatur oder Verschlüsselung scheitert trotz korrektem GET: Tenant-Aktivierung, Policy-Scope/-Reihenfolge, Zertifikatsgültigkeit, exakte Identität, Vertrauenskette und Verwendungszweck prüfen. Die GUI-Anleitung enthält den vollständigen Nachrichtentest.

Für eine Eskalation genügen Methode, Pfad ohne sensible Query-Werte, HTTP-Status, UTC-Zeit, requestId/correlationId, Tenant-ID, erwarteter Objekt-Typ und anonymisierte Zertifikatsmetadaten. Bearer-Token, deleteToken, Passwörter, PKCS#12, private Schlüssel und vollständige personenbezogene Listen bleiben ausgeschlossen.