Vai al contenuto
Avanet
Accedi

Gestire in sicurezza le API Credential di Sophos Fusion (in precedenza Sophos Central)

Sophos Fusion può essere automatizzato tramite API e collegato a piattaforme SIEM, RMM, di reporting o assicurative. Non si usano account amministratore personali, ma API Credential dedicate formate da Client ID e Client Secret.

Queste credenziali sono identità macchina. Chi possiede il secret può eseguire tutte le azioni API consentite dal ruolo Service Principal assegnato. Il secret va quindi trattato come una password privilegiata e non deve finire in script, ticket, e-mail o repository Git.

Distinguere API Credentials e Integration Credential Manager

In Global Settings > Access Control esistono due aree dal nome simile:

AreaCompito
API Credentialsidentità tecnica con cui un’applicazione richiama le API Sophos Central
Integration Credential Managercredenziali di prodotti terzi usate da Sophos per integrazioni come Data Ingestion o Response Actions

Per uno script proprio, una query SIEM o un client API si creano API Credential. Le credenziali di un prodotto terzo che Sophos Fusion deve usare appartengono invece all’Integration Credential Manager.

Non tutte le automazioni richiedono API Credential generiche: utenti e gruppi si sincronizzano tramite un servizio di directory, mentre il software può essere distribuito con uno script di installazione eseguito localmente su ciascun dispositivo. Per AD Sync si crea un’identità API solo se il flusso di sincronizzazione previsto lo richiede, assegnandole esclusivamente il ruolo Service Principal Directory Sync.

Prerequisiti e responsabilità

Solo un Super Admin può creare e gestire API Credential. L’applicazione si autentica con il proprio Client ID e Client Secret, non con l’account personale dell’amministratore.

Prima della creazione si documentano scopo, proprietario, sistema di destinazione, ruolo necessario, scadenza e contatto di emergenza. Si usa una Credential distinta per ogni applicazione e ambiente. Un secret condiviso tra script di backup, SIEM e fornitori esterni impedisce un blocco mirato e complica l’analisi delle cause.

Scegliere il ruolo Service Principal corretto

Sophos offre diversi ruoli:

  • Service Principal Read-Only legge i dati del tenant, ma non può modificarli né eseguire query Live Discover.
  • Service Principal Management può leggere, creare, modificare ed eliminare utenti e gruppi, leggere e gestire alert, leggere Endpoint ed eseguire azioni come uno scan, oltre a visualizzare e modificare impostazioni globali Endpoint Protection. Gestisce anche amministratori, ruoli e Security Policy, ma non accede alle query Live Discover.
  • Service Principal Forensics crea, visualizza, esegue ed elimina query Live Discover.
  • Service Principal Directory Sync è esclusivamente per la sincronizzazione Active Directory e non può svolgere altre attività API.
  • Service Principal Firewall limita l’identità alla gestione Firewall e vieta attività API Central esterne a tale ambito.
  • Service Principal Audit Log consente ad applicazioni esterne, strumenti SIEM e script di integrazione di recuperare gli eventi dell’Audit Log con accesso alle query in sola lettura.
  • Service Principal Super Admin dispone di ampi diritti di lettura, scrittura, eliminazione e query.

La scelta parte sempre dal ruolo più ristretto. Un’integrazione di reporting o assicurazione cyber riceve Read-Only. AD Sync usa il ruolo dedicato. Super Admin si usa solo se gli endpoint API documentati richiedono davvero ampi diritti di scrittura e nessun ruolo più ristretto funziona.

Creare una Credential

Accedere a fusion.sophos.com, quindi aprire Global Settings > Access Control > API Credentials. Al primo accesso occorre accettare le condizioni di utilizzo.

  1. Aprire Add Credential.
  2. Inserire un nome univoco e una descrizione con applicazione, ambiente e proprietario.
  3. Selezionare il ruolo Service Principal minimo necessario.
  4. Creare la Credential e acquisire subito Client ID e Client Secret.
  5. Conservare il secret in un secret store aziendale e cancellarlo dagli appunti temporanei.

Il Client Secret viene mostrato una sola volta e non può essere visualizzato di nuovo. Se viene perso, non si ripristina quello esistente: si crea una nuova Credential e si elimina la precedente dopo una migrazione riuscita.

Contratto API, autenticazione e regione

Il flusso seguente descrive le API REST di prodotto regionali di Sophos Central: l’host Identity globale emette il token OAuth; l’host globale whoami identifica la credenziale. Per i contratti REST con routing regionale, le chiamate di prodotto del tenant usano poi l’host restituito per quel tenant. A tale scopo devono essere raggiungibili dalla workstation amministrativa o dal sistema di integrazione le destinazioni HTTPS seguenti:

  • POST https://id.sophos.com/api/v2/oauth2/token per OAuth2;
  • GET https://api.central.sophos.com/whoami/v1 per identità e individuazione dell’host;
  • GET https://api.central.sophos.com/partner/v1/tenants per credenziali partner;
  • GET https://api.central.sophos.com/organization/v1/tenants per credenziali Enterprise;
  • l’host HTTPS restituito in apiHosts.dataRegion o nel campo tenant apiHost per l’API di prodotto.

Non indovinare un URL regionale né copiarlo da una tabella statica. Per questo flusso REST accettare solo l’host HTTPS completo restituito, aggiungendo poi i percorsi di prodotto. La verifica dell’host nello script seguente vale per questo contratto, non universalmente per ogni API Sophos.

La Search GraphQL API ha un proprio contratto di destinazione: POST JSON a https://api.taegis.sophos.com/graphql con token Bearer, X-Tenant-ID e X-GraphQL-Schema: default. Non usare l’host REST regionale né sostituire globalmente apiHosts.dataRegion. Acquisizione del token e associazione al tenant restano necessarie; chiarire separatamente autorizzazioni ed entitlement per l’operazione specifica. Le descrizioni generali dei ruoli sopra non dimostrano un ruolo minimo Search GraphQL. Il runbook per le ricerche Search-QL storiche illustra l’intero flusso. Il solo nome host non garantisce la residenza dei dati.

Richiedere un token di accesso in modo sicuro

Leggere il secret senza visualizzarlo e inviare i dati del modulo tramite input standard. In questo modo non compare nella cronologia della shell né come argomento espanso nell’elenco dei processi:

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' \
  "$(printf '%s' "$SOPHOS_CLIENT_ID" | jq -sRr '@uri')" \
  "$(printf '%s' "$SOPHOS_CLIENT_SECRET" | jq -sRr '@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
)

Una risposta riuscita contiene almeno access_token, token_type: "bearer" ed expires_in; possono comparire anche refresh_token, errorCode, message e trackingId. expires_in è la validità in secondi. Per il flusso Client Credentials richiedere un nuovo token alla scadenza, senza fare affidamento sul refresh_token facoltativo. Non registrare mai la risposta: entrambi i campi token sono secret.

Valutare whoami

Passare l’header Bearer a curl tramite input standard e salvare soltanto i campi di discovery non segreti. I valori dell’esempio di risposta tenant sono segnaposto, non valori di produzione.

{
  "id": "<tenant-uuid>",
  "idType": "tenant",
  "apiHosts": {
    "global": "https://api.central.sophos.com",
    "dataRegion": "https://api-us03.central.sophos.com"
  }
}

Con idType: "tenant", verificare rigorosamente UUID e host prima di acquisirli. Con idType: "partner" o "organization", whoami contiene normalmente solo apiHosts.global; SOPHOS_ID non è quindi un ID tenant. Il ciclo limitato usa l’header di contesto richiesto e segue pages.total. Ogni oggetto tenant fornisce il proprio id e apiHost. Scegliere il destinatario tramite UUID da un’associazione interna affidabile, mai soltanto per un nome visualizzato simile.

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 del tenant di destinazione dalla mappatura approvata: ' 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

Ogni richiesta di prodotto del tenant in questo flusso REST regionale associa quindi tre valori: token Bearer, X-Tenant-ID: <Tenant-UUID> e apiHost regionale del tenant. Non sostituire un’API REST di prodotto regionale con l’host globale. Un host GraphQL specifico dell’API è distinto. scope=token non autorizza operazioni funzionali; contano anche ruolo, accesso al tenant, licenza ed endpoint concreto.

Validazione e ripristino controllato

Prima di scrivere, chiamare un endpoint di lettura innocuo dell’API di destinazione e verificare idType atteso, UUID tenant corretto, formato host consentito, JSON valido, paginazione completa e oggetti attesi. Confermare poi un caso di test esplicitamente vietato con 403, senza provocare modifiche in produzione. A fine sessione rimuovere token di accesso, ID tenant e host:

unset SOPHOS_ACCESS_TOKEN SOPHOS_CLIENT_ID SOPHOS_ID SOPHOS_ID_TYPE
unset SOPHOS_TENANT_ID SOPHOS_API_HOST WHOAMI

In caso di tenant o host errato, interrompere subito l’esecuzione, non inviare scritture e isolare i risultati salvati come dati potenzialmente di un altro tenant, oppure eliminarli secondo le regole. Annullare una modifica funzionale già eseguita con il rollback specifico del prodotto documentato prima; eliminare la credenziale revoca solo le chiamate future e non annulla modifiche.

Risolvere i problemi dell’accesso API comune

  • 400: verificare codifica del modulo, campi obbligatori ed esattamente grant_type=client_credentials e scope=token.
  • 401: verificare esistenza e scadenza della credenziale, ultimo set di secret, token e sintassi Bearer; poi autenticarsi nuovamente una volta.
  • 403: identità autenticata, ma mancano ruolo, accesso al tenant o autorizzazione all’operazione. Non assegnare indiscriminatamente Super Admin.
  • 404: verificare host globale o regionale, versione API e percorso; non cercare la regione per tentativi.
  • 429: rispettare Retry-After e riprovare in modo limitato con backoff e jitter.
  • 5xx: conservare ID richiesta o trackingId, ora, metodo e percorso con i dati sensibili oscurati, quindi riprovare entro un limite; non copiare mai secret o token nei ticket di supporto.
  • idType inatteso o apiHost assente: non costruire header tenant. Verificare tipo di credenziale ed elenco tenant Partner/Enterprise completamente paginato.

Testare l’autenticazione in modo controllato

Il primo test non è una scrittura in produzione. Per il test REST regionale qui mostrato, ottenere prima un token di accesso OAuth dall’endpoint Sophos Identity. L’endpoint whoami fornisce poi identità, tipo di account e, per le credenziali tenant, host API regionale; le credenziali partner e organizzazione richiedono l’elenco dei tenant. Solo dopo eseguire una lettura innocua sull’host API REST restituito per quel tenant.

Non copiare un host API REST regionale da un esempio. Per questo contratto usare l’URL fornito da whoami o dall’elenco dei tenant; Search GraphQL usa l’host distinto descritto sopra. Anche ID tenant e ID organizzazione non sono intercambiabili.

Il test documenta almeno:

  • l’autenticazione con la nuova identità funziona,
  • viene restituito il tenant previsto,
  • le operazioni di lettura autorizzate funzionano,
  • un’operazione non consentita viene rifiutata con 403 Forbidden,
  • il sistema di destinazione registra il test in modo tracciabile senza memorizzare il Client Secret.

Gestire scadenza e rotazione

Sophos non invia avvisi quando una API Credential scade. Dopo la scadenza non può più autenticarsi e viene rimossa automaticamente da Sophos Fusion. Il monitoraggio deve quindi avvenire fuori da Sophos Fusion.

Una rotazione corretta usa una breve sovrapposizione:

  1. Creare una nuova Credential con ruolo identico o più ristretto.
  2. Configurare l’applicazione con Client ID e secret nuovi.
  3. Testare autenticazione e funzione operativa.
  4. Eliminare la vecchia Credential.
  5. Verificare la modifica nel registro dei secret e nella documentazione operativa.

La vecchia Credential non va lasciata attiva per mesi come precauzione. Se un’applicazione supporta un solo set di secret, si pianifica una finestra di manutenzione.

Sostituire i vecchi token SIEM API

API Token Management è la precedente autenticazione della SIEM Integration API. Sophos non emette più nuovi token e non estende la durata di quelli esistenti, che funzionano solo fino alla scadenza.

Un’integrazione che li usa non va lasciata invariata fino all’ultimo giorno. Si inventariano token, sistema di destinazione, scadenza ed endpoint usati, si crea una API Credential appropriata, si migra l’applicazione e si verifica l’intero flusso dati. Il vecchio token viene rimosso solo dopo un controllo parallelo riuscito.

Il passaggio da token legacy ad API Credential non è una semplice rinomina. L’integrazione deve supportare autenticazione OAuth, whoami, host regionale e modello dei ruoli. Un connettore SIEM si configura quindi secondo la documentazione attuale del produttore, non con un vecchio esempio di token.

Fornitori esterni e accesso di terzi

Per un soggetto esterno si crea un’identità Service Principal Read-Only dedicata, se bastano diritti di lettura. Client ID e secret vengono trasferiti su canali cifrati separati. L’accesso riceve una data di fine e viene eliminato alla conclusione del progetto.

Via API, questo accesso può leggere soprattutto Alerts ed Events, risultati dell’Account Health Check, dettagli dei dispositivi e configurazioni delle policy. Read-Only impedisce aggiunte, modifiche ed eliminazioni in Sophos Fusion, ma non limita automaticamente quali dati leggibili vengano prelevati o conservati dalla piattaforma terza. Prima dell’autorizzazione si chiariscono contrattualmente ambito, scopo, luogo di archiviazione, conservazione ed eliminazione dei dati.

La creazione segue Global Settings > Access Control > API Credentials > Add Credential. Al primo accesso si accettano condizioni d’uso e privacy, si sceglie Service Principal Read-Only e si acquisiscono in sicurezza Client ID e Client Secret visibile una sola volta. Il trasferimento avviene tramite un canale cifrato approvato, come il portale HTTPS del fornitore, non via e-mail o ticket.

L’API Host non viene copiato da una tabella regionale statica. L’applicazione usa whoami per determinare l’host valido proprio per quel tenant. La documentazione resta così corretta anche se Sophos modifica regioni o endpoint. Quando il fornitore non necessita più dell’accesso, si elimina la Credential revocando immediatamente l’autorizzazione API.

Non sono accettabili l’esportazione dell’account Super Admin personale, un’identità API condivisa tra più clienti o un secret nel ticket di supporto. Il fornitore deve inoltre dichiarare dove conserva il secret, come lo protegge e quando lo elimina.

Individuare gli errori

401 Unauthorized

Di norma Client ID, secret, endpoint token o richiesta OAuth sono errati. Anche una Credential scaduta e già rimossa causa questo errore. Verificare prima che esista ancora in Sophos Fusion e che l’applicazione usi davvero il set di secret più recente.

403 Forbidden

L’autenticazione è riuscita, ma il ruolo non consente l’azione. Invece di assegnare subito Super Admin, si associa l’endpoint API necessario al ruolo Service Principal appropriato.

Token corretto, regione dati errata

Il token di accesso non determina da solo l’host API di prodotto. Per un’API REST di prodotto con routing regionale, l’applicazione deve usare l’host regionale fornito da whoami o dall’elenco dei tenant; Search GraphQL ha un contratto di destinazione proprio. Un host fisso di un’altra regione causa errori o query contro il confine di piattaforma errato.

L’integrazione si interrompe senza preavviso

Se Sophos Fusion non mostra un alert aperto, si verificano scadenza, ultima chiamata API riuscita e versione del secret nel sistema di destinazione. Il monitoraggio della scadenza appartiene al sistema esterno.

Controllo periodico

Almeno ogni trimestre si verificano nome, proprietario, ruolo, ultimo utilizzo, scadenza e destinazione di ogni Credential. Le identità non attribuibili o inutilizzate vengono eliminate. In caso di sospetta fuoriuscita del secret, la Credential interessata viene eliminata immediatamente e sostituita con una nuova. In seguito si esaminano i log del sistema di destinazione e dell’integrazione alla ricerca di chiamate API insolite.

I diritti degli amministratori personali vengono controllati separatamente secondo Assegnare correttamente i ruoli amministrativi di Sophos Fusion. Le API Credential non sostituiscono né MFA né un accesso amministrativo personale tracciabile.

Domande frequenti

È possibile visualizzare di nuovo un Client Secret esistente?

No. Il secret è visibile solo subito dopo la creazione. Se viene perso, si crea e testa una nuova Credential e si elimina la precedente.

Quale ruolo è adatto a un SIEM che legge soltanto dati?

Di norma Service Principal Read-Only. Se l’integrazione richiede azioni specifiche di forensics o scrittura, vanno valutate singolarmente e realizzate con un’identità separata appropriata.

Sophos Fusion avvisa prima della scadenza?

No. La scadenza deve essere monitorata nel registro dei secret o nel monitoring. Dopo la scadenza l’autenticazione non è più possibile e la Credential viene rimossa automaticamente.