Gérer en toute sécurité les identifiants API Sophos Central
Sophos Fusion (anciennement Sophos Central) peut être automatisé par API et intégré à des plateformes SIEM, RMM, de reporting ou d’assurance. On n’utilise pas de compte administrateur personnel à cette fin, mais des API Credentials constitués d’un Client ID et d’un Client Secret.
Ces identifiants sont des identités de machine. Toute personne qui possède le secret peut exécuter les actions API autorisées par le rôle de service principal attribué. Un secret doit donc être traité comme un mot de passe privilégié et ne doit jamais se trouver dans un script, un ticket, un e-mail ou un dépôt Git.
Distinguer API Credentials et Integration Credential Manager
Sous Global Settings > Access Control, deux sections portent des noms proches :
| Section | Fonction |
|---|---|
| API Credentials | Identité technique avec laquelle une application appelle les API Sophos Central |
| Integration Credential Manager | Identifiants de produits tiers utilisés par Sophos pour des intégrations telles que Data Ingestion ou Response Actions |
Pour un script interne, une requête SIEM ou un client API, on crée des API Credentials. Les identifiants d’un produit tiers que Sophos Fusion doit lui-même utiliser appartiennent en revanche à l’Integration Credential Manager.
Toutes les automatisations ne nécessitent pas des API Credentials générales : les utilisateurs et groupes se synchronisent via un service d’annuaire, et les logiciels peuvent être déployés par un script d’installation exécuté localement sur chaque appareil. On ne crée une identité API pour AD Sync que si le processus prévu l’exige, avec le seul rôle Service Principal Directory Sync.
Conditions préalables et responsabilité
Seul un Super Admin peut créer et gérer des API Credentials. L’application s’authentifie avec ses propres Client ID et Client Secret, et non avec le compte personnel de l’administrateur.
Avant la création, on documente la finalité, le propriétaire, le système cible, le rôle requis, la date d’expiration et le contact d’urgence. Chaque application et chaque environnement disposent de leur propre identifiant. Un secret partagé entre un script de sauvegarde, un SIEM et un prestataire externe empêche une révocation ciblée et complique l’analyse des causes.
Choisir le rôle de service principal approprié
Sophos propose plusieurs rôles :
- Service Principal Read-Only lit les données du tenant, mais ne peut ni les modifier ni exécuter de requêtes Live Discover.
- Service Principal Management peut consulter, créer, modifier et supprimer des utilisateurs et groupes d’utilisateurs, consulter et traiter des alertes, interroger les endpoints et déclencher des actions telles qu’une analyse, ainsi qu’afficher et modifier les paramètres globaux d’Endpoint Protection. Ce rôle gère aussi les administrateurs, les rôles et les Security Policies, mais n’a pas accès aux requêtes Live Discover.
- Service Principal Forensics crée, affiche, exécute et supprime des requêtes Live Discover.
- Service Principal Directory Sync est exclusivement destiné à la synchronisation Active Directory et ne peut effectuer aucune autre tâche API.
- Service Principal Firewall limite l’identité à l’administration des firewalls et n’autorise aucune autre tâche de l’API Central.
- Service Principal Audit Log permet aux applications externes, outils SIEM et scripts d’intégration de récupérer les événements d’Audit Log avec un accès en lecture seule.
- Service Principal Super Admin possède des droits étendus de lecture, d’écriture et de suppression ainsi que l’accès aux requêtes.
On commence toujours par le rôle le plus limité. Une intégration de reporting ou de cyberassurance reçoit Read-Only. AD Sync reçoit le rôle prévu à cet effet. Super Admin ne s’utilise que lorsque les endpoints API documentés exigent réellement des droits d’écriture étendus et qu’aucun rôle plus restreint ne convient.
Créer un identifiant
Connectez-vous à fusion.sophos.com, puis ouvrez Global Settings > Access Control > API Credentials. Lors du premier accès, il faut accepter les conditions d’utilisation.
- Ouvrir Add Credential.
- Saisir un nom explicite et une description indiquant l’application, l’environnement et le propriétaire.
- Sélectionner le rôle de service principal minimal nécessaire.
- Créer l’identifiant et récupérer immédiatement le Client ID et le Client Secret.
- Déposer le secret dans le coffre-fort de secrets de l’entreprise et effacer les copies temporaires.
Le Client Secret n’est affiché qu’une seule fois. Il est impossible de le révéler à nouveau par la suite. S’il est perdu, on ne restaure pas le secret existant : on crée un nouvel identifiant, puis on supprime l’ancien après une migration réussie.
Contrat API, authentification et région
Le contrat commun utilise POST https://id.sophos.com/api/v2/oauth2/token pour OAuth2 et GET https://api.central.sophos.com/whoami/v1 pour l’identité. Les Credentials Partner et Enterprise lisent ensuite respectivement GET https://api.central.sophos.com/partner/v1/tenants et GET https://api.central.sophos.com/organization/v1/tenants. Seul l’hôte HTTPS renvoyé dans apiHosts.dataRegion ou apiHost est utilisé pour l’API produit ; ne jamais déduire la région.
Demander un jeton d’accès en toute sécurité
read -r -p "Client ID: " SOPHOS_CLIENT_ID
read -r -s -p "Client Secret: " SOPHOS_CLIENT_SECRET; printf '\n'
TOKEN_RESPONSE=$(printf 'grant_type=client_credentials&client_id=%s&client_secret=%s&scope=token' \
"$(jq -rn --arg v "$SOPHOS_CLIENT_ID" '$v|@uri')" \
"$(jq -rn --arg v "$SOPHOS_CLIENT_SECRET" '$v|@uri')" |
curl --fail-with-body --silent --show-error --request POST \
--header 'Content-Type: application/x-www-form-urlencoded' --data-binary @- \
https://id.sophos.com/api/v2/oauth2/token)
unset SOPHOS_CLIENT_SECRET
SOPHOS_ACCESS_TOKEN=$(jq -er '
select(.token_type == "bearer") |
select((.expires_in | type) == "number" and .expires_in > 0) |
.access_token | select(type == "string" and length > 0)
' <<<"$TOKEN_RESPONSE")
unset TOKEN_RESPONSE
WHOAMI=$(printf 'header = "Authorization: Bearer %s"\n' "$SOPHOS_ACCESS_TOKEN" |
curl --fail-with-body --silent --show-error --config - \
https://api.central.sophos.com/whoami/v1
)
Une réponse valide contient access_token, token_type: "bearer" et un expires_in numérique positif. Elle peut aussi contenir refresh_token, errorCode, message et trackingId. Ne jamais la journaliser ; demander un nouveau jeton à son expiration.
Évaluer whoami
Le contrat de réponse whoami pour un tenant et la résolution des autres types sont :
{
"id": "<tenant-uuid>",
"idType": "tenant",
"apiHosts": {
"global": "https://api.central.sophos.com",
"dataRegion": "https://api-us03.central.sophos.com"
}
}
SOPHOS_ID=$(jq -er '.id | select(type == "string" and length > 0)' <<<"$WHOAMI")
SOPHOS_ID_TYPE=$(jq -er '.idType | select(. == "tenant" or . == "partner" or . == "organization")' <<<"$WHOAMI")
UUID_RE='^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$'
if [[ "$SOPHOS_ID_TYPE" == tenant ]]; then
SOPHOS_TENANT_ID=$(jq -er --arg re "$UUID_RE" '.id | select(type=="string" and test($re))' <<<"$WHOAMI")
SOPHOS_API_HOST=$(jq -er '.apiHosts.dataRegion | select(type=="string" and test("^https://api-[a-z0-9-]+\\.central\\.sophos\\.com$"))' <<<"$WHOAMI")
else
case "$SOPHOS_ID_TYPE" in
partner) TENANTS_URL='https://api.central.sophos.com/partner/v1/tenants'; CONTEXT_HEADER="X-Partner-ID: ${SOPHOS_ID}" ;;
organization) TENANTS_URL='https://api.central.sophos.com/organization/v1/tenants'; CONTEXT_HEADER="X-Organization-ID: ${SOPHOS_ID}" ;;
*) exit 1 ;;
esac
TENANTS_FILE=$(mktemp); printf '[]\n' >"$TENANTS_FILE"
page=1; max_pages=1000; expected_pages=
while (( page <= max_pages )); do
PAGE_RESPONSE=$(printf 'header = "Authorization: Bearer %s"\n' "$SOPHOS_ACCESS_TOKEN" | curl --fail-with-body --silent --show-error --get --config - --header "$CONTEXT_HEADER" --data-urlencode "page=${page}" --data-urlencode 'pageSize=100' --data-urlencode 'pageTotal=true' "$TENANTS_URL")
page_total=$(jq -er 'select((.items|type)=="array") | .pages.total | select(type=="number" and floor==. and .>=1 and .<=1000)' <<<"$PAGE_RESPONSE")
if [[ -z "$expected_pages" ]]; then expected_pages=$page_total; fi
[[ "$page_total" == "$expected_pages" ]] || exit 1
jq -e --argjson page "$PAGE_RESPONSE" '. + $page.items' "$TENANTS_FILE" >"${TENANTS_FILE}.new"; mv "${TENANTS_FILE}.new" "$TENANTS_FILE"
(( page >= expected_pages )) && break; ((page++))
done
(( page == expected_pages )) || exit 1
read -r -p 'UUID du tenant cible selon la correspondance approuvée : ' TARGET_TENANT_ID
TARGET_TENANT=$(jq -cer --arg id "$TARGET_TENANT_ID" --arg re "$UUID_RE" '[.[] | select((.id|type)=="string" and (.id|test($re)) and (.id|ascii_downcase)==($id|ascii_downcase)) | select((.apiHost|type)=="string" and (.apiHost|test("^https://api-[a-z0-9-]+\\.central\\.sophos\\.com$")))] | select(length==1) | .[0]' "$TENANTS_FILE")
SOPHOS_TENANT_ID=$(jq -r '.id' <<<"$TARGET_TENANT"); SOPHOS_API_HOST=$(jq -r '.apiHost' <<<"$TARGET_TENANT"); rm -f "$TENANTS_FILE"
fi
export SOPHOS_TENANT_ID SOPHOS_API_HOST
Chaque requête produit d’un tenant associe exactement Authorization: Bearer <jeton-d'accès>, X-Tenant-ID: <uuid-tenant> et l’apiHost régional de ce même tenant. L’hôte global ne remplace pas une API produit régionale.
whoami renvoie id, idType et apiHosts. Pour Partner ou Enterprise, l’ID n’est pas un Tenant ID : la boucle exige les en-têtes d’autorisation et de contexte, est limitée à 1 000 pages, suit la valeur réelle pages.total et n’exporte qu’une correspondance UUID unique dont l’apiHost régional est valide.
Validation et récupération contrôlée
Avant toute écriture, vérifier idType, UUID, format HTTPS de l’hôte, JSON, pagination et objets attendus avec une lecture sans risque. scope=token n’accorde aucun droit métier : rôle, accès tenant, licence et opération restent déterminants. En cas de 400, contrôler le formulaire ; 401, Credential/expiration/secret ; 403, rôle et accès ; 404, hôte/version/chemin ; 429, Retry-After et Backoff ; 5xx, Request ID ou trackingId et nouvelle tentative limitée. Ne jamais transmettre de Token ou secret au support.
Si le tenant ou l’hôte est incorrect, arrêter les écritures et isoler les données reçues. Une suppression de Credential bloque les futurs appels mais n’annule aucune modification : appliquer le Rollback produit préparé. Terminer en supprimant de la session le token, les identifiants, l’UUID du tenant, l’hôte et WHOAMI avec unset.
unset SOPHOS_ACCESS_TOKEN SOPHOS_CLIENT_ID SOPHOS_ID SOPHOS_ID_TYPE
unset SOPHOS_TENANT_ID SOPHOS_API_HOST WHOAMI
Dépanner l’accès API commun
Pour 400, contrôler formulaire et champs ; 401, Credential, expiration, secret, token et syntaxe Bearer ; 403, rôle, accès tenant et opération ; 404, hôte global ou régional, version et chemin ; 429, respecter Retry-After et effectuer des tentatives limitées avec backoff et jitter ; 5xx, conserver Request ID ou trackingId et réessayer dans une limite. Avec un idType inattendu ou un apiHost absent, ne construire aucun en-tête tenant. Ne jamais transmettre token ou secret au support.
Tester l’authentification de manière contrôlée
Le premier test ne doit pas être une opération d’écriture en production. On obtient d’abord un jeton d’accès OAuth auprès de l’endpoint Sophos Identity. L’endpoint whoami fournit ensuite l’ID du tenant, l’hôte API et le type de données du compte. Ce n’est qu’alors que l’on exécute une requête de lecture sans risque vers l’hôte API indiqué pour ce tenant.
L’hôte API ne doit pas être copié depuis un exemple. Sophos exploite plusieurs régions de données, il faut donc utiliser l’URL retournée par whoami. L’ID du tenant et l’ID de l’organisation ne sont pas non plus interchangeables.
Le test doit documenter au minimum les points suivants :
- l’authentification avec la nouvelle identité fonctionne ;
- le tenant attendu est retourné ;
- les opérations de lecture autorisées fonctionnent ;
- une opération interdite est rejetée avec
403 Forbidden; - le système cible consigne le test de manière traçable sans enregistrer le Client Secret.
Gérer l’expiration et la rotation
Sophos n’envoie aucun avertissement lorsqu’un API Credential expire. Après expiration, il ne peut plus servir à l’authentification et est automatiquement supprimé de Sophos Fusion. La surveillance doit donc être assurée en dehors de Sophos Fusion.
Une rotation propre utilise une courte période de chevauchement :
- Créer un nouvel identifiant avec un rôle identique ou plus limité.
- Configurer l’application avec le Client ID et le secret du nouvel identifiant.
- Tester l’authentification et le fonctionnement métier.
- Supprimer l’ancien identifiant.
- Vérifier la modification dans le registre des secrets et la documentation d’exploitation.
L’ancien identifiant ne reste pas actif pendant des mois « par précaution ». Si une application ne prend en charge qu’un seul jeu de secrets, on planifie une fenêtre de maintenance.
Remplacer les anciens jetons de l’API SIEM
API Token Management est l’ancien mécanisme d’authentification de la SIEM Integration API. Sophos n’y délivre plus de nouveaux jetons et ne prolonge plus leur durée de validité. Les jetons existants ne fonctionnent que jusqu’à leur expiration.
Une intégration qui les utilise encore ne doit donc pas attendre le dernier jour. On inventorie le jeton, le système cible, la date d’expiration et les endpoints utilisés, puis on crée un API Credential approprié, on migre l’application et on vérifie l’ensemble du flux de données. L’ancien jeton n’est supprimé qu’après un contrôle parallèle concluant.
Le passage d’un jeton historique à des API Credentials ne constitue pas un simple changement de nom. L’intégration doit prendre en charge l’authentification OAuth, whoami, l’hôte régional et le modèle de rôles. Un connecteur SIEM se configure donc selon la documentation actuelle de son éditeur et non à l’aide d’un ancien exemple de jeton.
Prestataires externes et accès tiers
Pour un tiers, on crée une identité Service Principal Read-Only distincte lorsque des droits de lecture suffisent. Client ID et secret sont transmis par des canaux chiffrés séparés. Une date de fin est définie et l’accès est supprimé à la fin du projet.
Par API, un tel tiers peut notamment lire les alertes et événements, les résultats de l’Account Health Check, les détails des appareils et les configurations de stratégies. Read-Only empêche l’ajout, la modification et la suppression dans Sophos Fusion, mais ne limite pas automatiquement les données que la plateforme tierce consulte ou conserve. Avant l’autorisation, il faut donc régler contractuellement le périmètre des données, leur finalité, leur lieu de stockage, leur conservation et leur suppression.
La création suit le chemin habituel Global Settings > Access Control > API Credentials > Add Credential. Lors du premier accès, les conditions d’utilisation et de confidentialité sont acceptées. On choisit Service Principal Read-Only, puis on récupère immédiatement le Client ID et le Client Secret qui ne s’affiche qu’une seule fois. Le transfert passe par un canal chiffré approuvé, par exemple le portail HTTPS du fournisseur, jamais par e-mail ou dans le texte d’un ticket.
L’hôte API n’est pas copié d’un tableau régional statique. L’application utilise whoami pour déterminer l’hôte API valable pour ce tenant précis. L’intégration reste ainsi correctement documentée même si Sophos modifie ses régions ou endpoints. Dès que le prestataire n’a plus besoin de l’accès, l’identifiant est supprimé et l’autorisation API immédiatement révoquée.
Il est inacceptable d’exporter le compte Super Admin personnel, d’utiliser une identité API commune pour plusieurs clients ou de placer un secret dans un ticket de support. Le prestataire doit aussi indiquer où le secret est stocké, comment il est protégé et quand il sera supprimé.
Cibler la recherche d’erreurs
401 Unauthorized
Le Client ID, le secret, l’endpoint de jeton ou la requête OAuth sont généralement incorrects. Un identifiant expiré et déjà supprimé provoque aussi cette erreur. On vérifie d’abord si l’identifiant existe encore dans Sophos Fusion et si l’application utilise réellement le dernier jeu de secrets.
403 Forbidden
L’authentification a réussi, mais le rôle n’autorise pas l’action. Au lieu d’accorder immédiatement Super Admin, on associe l’endpoint API requis au rôle de service principal approprié.
Jeton correct, mauvaise région de données
Le jeton d’accès ne détermine pas à lui seul l’hôte API métier. L’application doit utiliser l’hôte régional retourné par whoami. Un hôte fixe d’une autre région provoque des erreurs ou des requêtes vers une mauvaise frontière de plateforme.
L’intégration tombe en panne sans avertissement
Si Sophos Fusion ne présente aucune alerte ouverte, on contrôle la date d’expiration, le dernier appel API réussi et la version du secret dans le système cible. La surveillance de l’expiration appartient au monitoring externe.
Contrôle régulier
Au moins chaque trimestre, on contrôle le nom, le propriétaire, le rôle, la dernière utilisation, l’expiration et le système cible de chaque identifiant. Les identités inutilisées ou sans propriétaire sont supprimées. En cas de suspicion de fuite, l’identifiant concerné est immédiatement supprimé et remplacé. Les journaux du système cible et de l’intégration sont ensuite examinés à la recherche d’appels API inhabituels.
Les droits des administrateurs personnels sont contrôlés séparément selon Attribuer correctement les rôles d’administration Sophos Fusion. Les API Credentials ne remplacent ni la MFA ni un accès administrateur personnel et traçable.