Automatizzare S/MIME di Sophos Email tramite API
La Sophos Email Management API consente di gestire l’intero ciclo di vita dei certificati S/MIME. La sequenza sicura è: leggere l’inventario, creare o caricare esattamente una CA interna del tenant, creare inizialmente la configurazione disabilitata, predisporre CA attendibili e certificati esterni, abilitare S/MIME, predisporre certificati interni e quindi provare il flusso email. Questo articolo distingue volutamente la CA interna del tenant, le CA esterne attendibili, i certificati degli utenti interni e i certificati dei destinatari esterni. Usano percorsi diversi e non sono intercambiabili.
Per architettura, policy e test nell’interfaccia consulta la guida GUI a S/MIME. L’introduzione a Sophos Email Management API illustra il contratto generale; OAuth2, risoluzione del tenant e host regionale sono trattati nel runbook pianificato per autenticazione API e tenant routing.
Avviso critico:
DELETE /smime/config/{deleteToken}elimina tutti i certificati S/MIME e tutte le chiavi private del tenant e impostasmimeEnabledsufalse. Non è una rotazione né una normale correzione. L’API non documenta l’esportazione delle chiavi private. Senza fonti PKCS#12 autorizzate conservate separatamente, chiavi e decifratura dei contenuti storici possono andare perdute definitivamente.
Prerequisiti e base sicura
Riutilizza solo SOPHOS_ACCESS_TOKEN (bearer token temporaneo), SOPHOS_TENANT_ID (UUID destinazione) e SOPHOS_API_HOST (host regionale completo) già validati. La specifica esaminata è Email Management API v1.4.0; verifica quella corrente prima di implementare. Tutti i percorsi sono relativi a /email/v1 e richiedono Authorization: Bearer ***, X-Tenant-ID e, per JSON, Content-Type: application/json:
EMAIL_API_HOST="${SOPHOS_API_HOST%/}/email/v1"
Non inserire token, deleteToken, password o contenuti PKCS#12 o chiavi private in argomenti, codice, log o ticket. Usa un secret store approvato, file in modalità 600 e rimuovi i temporanei. Sostituisci ops@example.net e alice@example.net con indirizzi autorizzati.
Prima di scrivere esegui questi read e registra soltanto stato HTTP, requestId/correlationId degli errori e risultato dello schema:
GET /smime/config
GET /smime/ca/internal
GET /smime/users/internal?pageSize=1
404 sui primi due indica che l’oggetto non esiste. Le liste restituiscono items e pages; passa pages.nextKey, codificato per URL, come pageFromKey finché non resta alcun nextKey.
Predisporre la CA interna del tenant
La CA interna firma i certificati generati da Sophos per utenti interni. Ogni tenant ne ha esattamente una. Creazione e upload generano, se necessario, una configurazione S/MIME disabilitata, ma non abilitano S/MIME. Un secondo tentativo restituisce 409; nell’API esaminata non esiste un percorso separato per eliminare o sostituire solo la CA.
Opzione A: creare la CA con Sophos
POST /smime/ca/internal richiede organizationName, locality, country ed email. country contiene esattamente due lettere maiuscole ISO 3166-1. organizationUnit è facoltativo, così come certExpiryDate (YYYY-MM-DD) oppure certValidityPeriod (1–20 anni). Il default è 20 anni; se sono presenti entrambi, vale il periodo più breve.
{
"organizationName": "Example Operations GmbH",
"organizationUnit": "Messaging",
"locality": "Zurich",
"country": "CH",
"email": "ops@example.net",
"certValidityPeriod": 10
}
Il successo è 201. Conserva fingerprint SHA-256 di 64 caratteri, issuer, validFrom, expiresAt e origin senza registrare inutilmente la risposta completa.
Opzione B: caricare una CA con chiave
POST /smime/ca/internal/certificate richiede un bundle certificato-chiave PKCS#12 codificato Base64, non PEM:
{
"pkcs12": "<BASE64_PKCS12>",
"password": "<PKCS12_PASSWORD>"
}
Dopo Base64, pkcs12 deve avere 1200–24000 caratteri e password 3–50. Il responsabile PKI verifica certificato, chiave privata, catena, uso e password. Base64 non protegge la chiave. Elimina gli a capo e non inserire PEM in pkcs12.
Per entrambe le opzioni verifica: GET /smime/ca/internal restituisce lo stesso fingerprint; GET /smime/ca/internal/certificate scarica il certificato pubblico PEM come application/octet-stream; il fingerprint corrisponde all’inventario. Il PEM non contiene una chiave privata recuperabile.
Abilitare la configurazione solo dopo
GET /smime/config restituisce smimeEnabled, extractCertificate, fino a cinque certExpiryNotificationEmailAddresses e il deleteToken di otto caratteri, da trattare come secret distruttivo.
Se la configurazione manca, creala con POST /smime/config. smimeEnabled è obbligatorio e il default di extractCertificate è false:
{
"smimeEnabled": false,
"extractCertificate": false,
"certExpiryNotificationEmailAddresses": ["ops@example.net"]
}
Per una configurazione esistente usa PATCH /smime/config: almeno un campo, campi omessi invariati, null o [] elimina tutti gli indirizzi e i duplicati vengono rimossi. Scrivi prima smimeEnabled: false, predisponi e inventaria CA attendibili e certificati esterni pilota e solo allora invia {"smimeEnabled":true}. Senza CA interna l’API restituisce 409. Conferma con GET, predisponi i certificati interni pilota e prova firma e cifratura. extractCertificate: true permette solo l’estrazione in ingresso; restano necessari i prerequisiti di verifica firma nella policy Secure Message descritti nella guida GUI.
Gestire le CA esterne attendibili
Queste CA verificano messaggi firmati; non sono la CA interna né certificati utente. Prima dell’upload verifica in Sophos Central se l’emittente è già globalmente attendibile e controlla SHA-256 tramite un canale indipendente.
GET /smime/cas/external: filtricommonName,certValidBefore,certValidAfter,certExpiryBefore,certExpiryAfter,certFingerprint,issuerCN,pageFromKey,pageSize(default50).POST /smime/cas/external/certificate: PEM nel campocertificate, 300–32000 caratteri inclusi header e footer.GET /smime/cas/external/certificate/{fingerprint}: scarica quel PEM.DELETE /smime/cas/external?certFingerprint=...: elimina esattamente quella trust entry.
{
"certificate": "-----BEGIN CERTIFICATE-----\n<BASE64_CERTIFICATE>\n-----END CERTIFICATE-----"
}
Un duplicato restituisce 409. Prima di DELETE, un list read esatto deve restituire una sola voce attesa; dopo 200 e deleted: true, il filtro deve essere vuoto. Prova poi una firma tramite la catena restante.
Gestire i certificati dei destinatari esterni
Sono certificati pubblici dei partner e non contengono chiavi private del tenant. POST /smime/users/external/certificate accetta PEM in certificate (300–32000 caratteri), ricava l’identità dal certificato e abilita S/MIME per quell’utente:
{
"certificate": "-----BEGIN CERTIFICATE-----\n<BASE64_CERTIFICATE>\n-----END CERTIFICATE-----",
"confirmVerificationOnlyCert": false
}
Per DSA/EC, confirmVerificationOnlyCert: true conferma consapevolmente il solo uso firma/verifica, senza cifratura/decifratura. Massimo due certificati per identità (422 al successivo); un duplicato restituisce 409.
GET /smime/users/external?email=partner@example.net filtra l’indirizzo esatto e supporta anche emailStartsWith, date, fingerprint, issuer e paginazione. GET /smime/users/external/certificate/{fingerprint} scarica PEM. DELETE /smime/users/external?email=...&certFingerprint=... elimina solo la coppia esatta con parametri URL-encoded; l’ultimo certificato rimuove implicitamente l’utente dalla lista. Dopo upload controlla email, fingerprint, issuer e validità, quindi fai decifrare un messaggio pilota al partner previsto.
Creare o caricare certificati interni
L’utente deve esistere come identità tenant corrispondente. Create o upload abilita S/MIME per l’utente. Non normalizzare l’indirizzo: riusa l’email esatta del GET.
Per creare usa POST /smime/users/internal:
{
"email": "alice@example.net",
"certValidityPeriod": 3
}
Solo email è obbligatorio. certExpiryDate/certValidityPeriod segue le regole 1–20 anni della CA. Servono CA interna e S/MIME configurato/abilitato.
Per caricare una chiave usa POST /smime/users/internal/certificate:
{
"email": "alice@example.net",
"pkcs12": "<BASE64_PKCS12>",
"password": "<PKCS12_PASSWORD>",
"confirmSigningOnlyCert": false
}
email, pkcs12, password sono obbligatori; limiti 1200–24000 caratteri Base64 e 3–50 per la password. DSA/EC richiede confirmSigningOnlyCert: true ed è solo firma/verifica. Le CA nel bundle vengono memorizzate come CA attendibili: valida la catena e controlla /smime/cas/external. Massimo due certificati per utente; duplicato 409, terzo 422.
GET /smime/users/internal?email=alice@example.net restituisce utente e certificati esatti e accetta userName, emailStartsWith, filtri data/fingerprint/issuer e paginazione. GET /smime/users/internal/certificate/{fingerprint} scarica PEM includendo le CA caricate nel bundle, ma senza chiave privata. DELETE /smime/users/internal?email=...&certFingerprint=... elimina solo la coppia; l’ultimo rimuove l’utente dalla lista S/MIME. Dopo 201, verifica indirizzo, fingerprint, issuer e scadenza, poi prova firma in uscita e decifratura in ingresso.
Eseguire il reset distruttivo solo come ricostruzione approvata
Approvazione obbligatoria: vengono eliminate CA interna, CA attendibili, certificati interni ed esterni e tutte le chiavi private memorizzate;
smimeEnableddiventafalse. Non corregge un solo oggetto.
Prima: (1) inventaria tutte le pagine di GET /smime/config, /smime/ca/internal, /smime/cas/external, /smime/users/internal, /smime/users/external; (2) per ogni chiave recuperabile conferma una fonte PKCS#12 autorizzata e password testata—PEM non è backup della chiave; (3) documenta policy, finestra, owner, partner, disservizio e ordine completo; (4) ottieni il deleteToken corrente direttamente dal GET; (5) fai verificare tenant, inventario, conseguenza e associazione token da una seconda persona autorizzata.
Solo allora chiama esattamente DELETE /smime/config/{deleteToken}. Token errato dà 409; configurazione assente 404. Con timeout, 5xx o esito sconosciuto, non ripetere alla cieca: rileggi prima configurazione e inventari. Il successo richiede 200 e deleted: true; poi la configurazione deve mancare o essere ricreata con smimeEnabled: false. Ordine: CA interna, configurazione disabilitata, trust, utenti, abilitazione finale.
Validazione e troubleshooting
Valida due livelli: stato API, con GET esatto di email, SHA-256 di 64 esadecimali, issuer, validFrom, expiresAt, origin, fine paginazione e configurazione; ed effetto messaggi, firmando in uscita, verificando in ingresso, cifrando al pilota esterno e decifrando per quello interno con una piccola policy Secure Message. Registra Message-ID, UTC ed esito, mai chiavi o payload completi.
400: campi JSON, header/footer PEM, Base64 senza a capo, password PKCS#12, lunghezze, data ed email; elabora ognierrors.401/403: token, permesso minimo e assegnazione tenant; non indovinare la regione.404: host regionale, percorso esatto, coppia email/fingerprint e inventario.409: CA/certificato già presente, CA mancante all’abilitazione odeleteTokenerrato; leggi lo stato prima di riscrivere.422: sono già presenti due certificati; non eliminare un fingerprint ignoto.- Lista inattesa: percorri
pages.nextKey, codificapageFromKeye usa il filtro esatto. - Messaggio fallito con GET corretto: controlla abilitazione, scope/ordine policy, validità, identità, catena e key usage; completa il test con la guida GUI.
Per escalation bastano metodo, percorso senza query sensibili, HTTP, UTC, requestId/correlationId, tenant ID, tipo oggetto e metadati anonimizzati. Escludi bearer token, deleteToken, password, PKCS#12, chiavi private e liste personali complete.