Automatizar S/MIME de Sophos Email mediante la API
La Sophos Email Management API permite controlar todo el ciclo de vida de certificados S/MIME. El orden seguro es: leer el inventario, crear o cargar exactamente una CA interna del tenant, crear primero la configuración desactivada, proporcionar CA de confianza y certificados de destinatarios externos, activar S/MIME, proporcionar certificados internos y probar el flujo de correo. Este artículo separa deliberadamente la CA interna del tenant, las CA externas de confianza, los certificados de usuarios internos y los certificados de destinatarios externos. Sus rutas son diferentes y no son intercambiables.
Para arquitectura, políticas y pruebas en la interfaz, consulte la guía gráfica de S/MIME. La introducción a Sophos Email Management API explica el contrato general; OAuth2, la resolución del tenant y el host regional se tratan en el runbook previsto de autenticación de API y tenant routing.
Advertencia crítica:
DELETE /smime/config/{deleteToken}elimina todos los certificados S/MIME y las claves privadas del tenant y establecesmimeEnabledenfalse. No es una rotación de certificado ni una solución habitual. La API no documenta exportación de claves privadas. Sin fuentes PKCS#12 autorizadas y conservadas aparte, pueden perderse para siempre las claves y el acceso al contenido histórico cifrado.
Requisitos previos y base segura
Use solo SOPHOS_ACCESS_TOKEN (token bearer temporal), SOPHOS_TENANT_ID (UUID del tenant) y SOPHOS_API_HOST (host regional completo) ya validados. La especificación revisada es Email Management API v1.4.0; compruebe la versión actual antes de implementar. Todas las rutas dependen de /email/v1 y requieren Authorization: Bearer ***, X-Tenant-ID y, para JSON, Content-Type: application/json:
EMAIL_API_HOST="${SOPHOS_API_HOST%/}/email/v1"
No coloque tokens, deleteToken, contraseñas o contenido PKCS#12 ni claves privadas en argumentos, código, logs o tickets. Use un almacén de secretos aprobado, archivos con modo 600 y elimine temporales. Sustituya ops@example.net y alice@example.net por direcciones autorizadas.
Antes de escribir, ejecute estos reads y registre únicamente estado HTTP, requestId/correlationId de errores y validación del esquema:
GET /smime/config
GET /smime/ca/internal
GET /smime/users/internal?pageSize=1
Un 404 en los dos primeros indica que el objeto no existe. Las listas devuelven items y pages; pase pages.nextKey codificado para URL como pageFromKey hasta que ya no haya nextKey.
Proporcionar la CA interna del tenant
La CA interna firma certificados creados por Sophos para usuarios internos. Hay exactamente una por tenant. Crear o cargar la CA crea, si hace falta, una configuración S/MIME desactivada, pero no activa S/MIME. Un segundo intento devuelve 409; la API revisada no tiene una ruta independiente para borrar o sustituir solo esta CA.
Opción A: crearla en Sophos
POST /smime/ca/internal exige organizationName, locality, country y email. country son exactamente dos mayúsculas ISO 3166-1. organizationUnit es opcional; también puede usar certExpiryDate (YYYY-MM-DD) o certValidityPeriod (1–20 años). El valor predeterminado son 20 años; si se envían ambos, se usa el plazo menor.
{
"organizationName": "Example Operations GmbH",
"organizationUnit": "Messaging",
"locality": "Zurich",
"country": "CH",
"email": "ops@example.net",
"certValidityPeriod": 10
}
El éxito es 201. Guarde fingerprint SHA-256 de 64 caracteres, issuer, validFrom, expiresAt y origin sin registrar toda la respuesta.
Opción B: cargar una CA con su clave
POST /smime/ca/internal/certificate espera un bundle de certificado y clave PKCS#12 codificado en Base64, no PEM:
{
"pkcs12": "<BASE64_PKCS12>",
"password": "<PKCS12_PASSWORD>"
}
pkcs12 debe tener 1200–24000 caracteres después de Base64 y password, 3–50. El propietario de PKI verifica certificado, clave privada, cadena, finalidad y contraseña. Base64 no protege la clave. Quite saltos de línea y no introduzca PEM en pkcs12.
En ambos casos, confirme que GET /smime/ca/internal devuelve el mismo fingerprint; GET /smime/ca/internal/certificate descarga el certificado público PEM como application/octet-stream; y su fingerprint coincide con el inventario. Ese PEM no contiene la clave privada recuperable.
Activar después la configuración del tenant
GET /smime/config devuelve smimeEnabled, extractCertificate, hasta cinco certExpiryNotificationEmailAddresses y el deleteToken de ocho caracteres. Trátelo como secreto destructivo.
Si no hay configuración, use POST /smime/config; smimeEnabled es obligatorio y extractCertificate vale false por defecto:
{
"smimeEnabled": false,
"extractCertificate": false,
"certExpiryNotificationEmailAddresses": ["ops@example.net"]
}
Para una existente use PATCH /smime/config: requiere al menos un campo, deja intactos los omitidos, elimina todas las direcciones con null o [] y deduplica. Escriba primero smimeEnabled: false, proporcione e inventaríe CA de confianza y certificados externos piloto y, solo entonces, envíe {"smimeEnabled":true}. Sin CA interna se recibe 409. Confirme con GET, proporcione los certificados internos piloto y pruebe firma y cifrado. extractCertificate: true solo permite extracción entrante; siguen siendo necesarias las condiciones funcionales de la política Secure Message explicadas en la guía gráfica.
Gestionar CA externas de confianza
Estas CA verifican mensajes firmados; no son la CA interna ni certificados de usuarios. Antes de cargar, compruebe si Sophos ya confía globalmente en el emisor y valide su SHA-256 por un canal independiente.
GET /smime/cas/external: filtroscommonName,certValidBefore,certValidAfter,certExpiryBefore,certExpiryAfter,certFingerprint,issuerCN,pageFromKey,pageSize(predeterminado50).POST /smime/cas/external/certificate: campo PEMcertificate, 300–32000 caracteres con cabecera y pie.GET /smime/cas/external/certificate/{fingerprint}: descarga ese PEM.DELETE /smime/cas/external?certFingerprint=...: elimina exactamente esa confianza.
{
"certificate": "-----BEGIN CERTIFICATE-----\n<BASE64_CERTIFICATE>\n-----END CERTIFICATE-----"
}
Un duplicado da 409. Antes de DELETE, un list read exacto debe hallar un solo registro; después de 200 y deleted: true, el filtro debe quedar vacío. Pruebe luego una firma con la cadena restante.
Gestionar certificados de destinatarios externos
Son certificados públicos de socios y no contienen claves privadas del tenant. POST /smime/users/external/certificate recibe PEM en certificate (300–32000 caracteres), obtiene la identidad del certificado y activa S/MIME para ese usuario:
{
"certificate": "-----BEGIN CERTIFICATE-----\n<BASE64_CERTIFICATE>\n-----END CERTIFICATE-----",
"confirmVerificationOnlyCert": false
}
Para DSA/EC, confirmVerificationOnlyCert: true confirma que solo servirá para firmar/verificar, no cifrar/descifrar. Hay como máximo dos certificados por identidad (422 para el siguiente); un duplicado produce 409.
GET /smime/users/external?email=partner@example.net filtra por dirección exacta y admite emailStartsWith, fechas, fingerprint, emisor y paginación. GET /smime/users/external/certificate/{fingerprint} descarga PEM. DELETE /smime/users/external?email=...&certFingerprint=... borra solo el par exacto, con parámetros codificados para URL; al borrar el último, el usuario desaparece de la lista. Tras cargar, verifique email, fingerprint, emisor y validez y haga que el socio piloto descifre un mensaje de prueba.
Crear o cargar certificados de usuarios internos
El usuario debe existir como identidad coincidente del tenant. Create o upload activa S/MIME para él. No normalice direcciones: reutilice el email exacto devuelto por GET.
Para crear, use POST /smime/users/internal:
{
"email": "alice@example.net",
"certValidityPeriod": 3
}
Solo email es obligatorio. certExpiryDate/certValidityPeriod sigue las reglas de 1–20 años de la CA. Se requieren la CA interna y S/MIME configurado/activado.
Para cargar una clave, use POST /smime/users/internal/certificate:
{
"email": "alice@example.net",
"pkcs12": "<BASE64_PKCS12>",
"password": "<PKCS12_PASSWORD>",
"confirmSigningOnlyCert": false
}
Son obligatorios email, pkcs12 y password, con 1200–24000 caracteres Base64 y 3–50 de contraseña. DSA/EC requiere confirmSigningOnlyCert: true y solo permite firma/verificación. Las CA incluidas en el bundle se guardan como CA de confianza: valide la cadena y revise /smime/cas/external. Máximo dos certificados por usuario; duplicado 409, tercero 422.
GET /smime/users/internal?email=alice@example.net devuelve usuario y certificados exactos; también admite userName, emailStartsWith, filtros de fecha/fingerprint/emisor y paginación. GET /smime/users/internal/certificate/{fingerprint} descarga PEM e incluye CA cargadas con el bundle, pero ninguna clave privada. DELETE /smime/users/internal?email=...&certFingerprint=... borra el par exacto; el último elimina al usuario de la lista S/MIME. Tras 201, verifique dirección, fingerprint, emisor y caducidad, y pruebe firma saliente y descifrado entrante.
Ejecutar el reset destructivo solo como reconstrucción aprobada
Aprobación obligatoria: se eliminan CA interna, CA de confianza, certificados internos y externos y todas las claves privadas guardadas;
smimeEnabledpasa afalse. No repara un objeto individual.
Antes de actuar: (1) inventaríe todas las páginas de GET /smime/config, /smime/ca/internal, /smime/cas/external, /smime/users/internal y /smime/users/external; (2) confirme para cada clave recuperable una fuente PKCS#12 autorizada y contraseña probada—PEM no es backup de clave; (3) documente política, ventana, owner, socios, interrupción y orden de reconstrucción; (4) obtenga el deleteToken actual directamente de GET; (5) haga que otra persona autorizada compruebe tenant, inventario, consecuencia y token.
Solo entonces invoque exactamente DELETE /smime/config/{deleteToken}. Token incorrecto da 409; configuración ausente, 404. Ante timeout, 5xx o resultado desconocido, no repita a ciegas: lea primero configuración e inventarios. Éxito exige 200 y deleted: true; después, la configuración debe faltar o reconstruirse con smimeEnabled: false. Reconstruya en orden: CA interna, configuración desactivada, confianza, usuarios y activación final.
Validación y diagnóstico
Valide dos capas: estado API, con GET exacto y email, SHA-256 de 64 hexadecimales, issuer, validFrom, expiresAt, origin, fin de paginación y configuración; y efecto en mensajes, firmando salida, verificando entrada, cifrando al piloto externo y descifrando para el interno con una política Secure Message pequeña. Registre Message-ID, UTC y resultado, nunca claves o payloads completos.
400: revise campos JSON, cabecera/pie PEM, Base64 sin saltos, contraseña PKCS#12, longitudes, fecha y email; procese cadaerrors.401/403: token, permiso mínimo y asignación del tenant; no adivine región.404: host regional, ruta exacta, par email/fingerprint e inventario.409: CA/certificado duplicado, CA ausente al activar odeleteTokenincorrecto; lea estado antes de repetir.422: ya hay dos certificados; no borre un fingerprint desconocido.- Lista inesperada: recorra
pages.nextKey, codifiquepageFromKeyy use filtro exacto. - Fallo de mensaje con GET correcto: revise activación, scope/orden de policy, validez, identidad, cadena y key usage; complete la prueba con la guía gráfica.
Para escalar bastan método, ruta sin queries sensibles, estado HTTP, UTC, requestId/correlationId, tenant ID, tipo de objeto y metadatos anonimizados. Excluya token bearer, deleteToken, contraseñas, PKCS#12, claves privadas y listas personales completas.