Gerir API Credentials do Sophos Fusion com segurança
O Sophos Fusion (anteriormente Sophos Central) pode ser automatizado através de APIs e ligado a plataformas de SIEM, RMM, reporting ou seguros. Para esse efeito, não se utilizam contas pessoais de administrador, mas API Credentials próprias, compostas por Client ID e Client Secret.
Estas credenciais são identidades de máquinas. Quem possuir um secret pode executar todas as ações de API permitidas pela função Service Principal atribuída. Por isso, um secret deve ser tratado como uma palavra-passe privilegiada e nunca pode ficar guardado em scripts, tickets, e-mails ou repositórios Git.
Distinguir API Credentials do Integration Credential Manager
Em Global Settings > Access Control existem duas áreas com nomes semelhantes:
| Área | Função |
|---|---|
| API Credentials | Identidade técnica com a qual uma aplicação acede às APIs do Sophos Fusion |
| Integration Credential Manager | Credenciais de produtos de terceiros que a Sophos utiliza para integrações como Data Ingestion ou Response Actions |
Para um script próprio, uma consulta SIEM ou um cliente de API, criam-se API Credentials. As credenciais de um produto de terceiros que o próprio Sophos Fusion deve utilizar pertencem, pelo contrário, ao Integration Credential Manager.
Nem todas as automatizações necessitam de API Credentials gerais: os utilizadores e grupos são sincronizados através de um serviço de diretório e o software pode ser distribuído por um script de instalação executado localmente em cada dispositivo. Só se cria uma identidade de API para o AD Sync quando o processo de sincronização previsto a exigir, atribuindo-lhe exclusivamente a função Service Principal Directory Sync.
Pré-requisitos e responsabilidade
Apenas um Super Admin pode criar e gerir API Credentials. A aplicação autentica-se com o seu próprio Client ID e Client Secret, e não com a conta pessoal do administrador.
Antes da criação, documentam-se a finalidade, o responsável, o sistema de destino, a função necessária, a data de expiração e o contacto de emergência. Utiliza-se uma Credential própria para cada aplicação e ambiente. Um secret comum para um script de backup, o SIEM e prestadores externos impede um bloqueio seletivo e dificulta a análise da causa.
Escolher a função Service Principal adequada
A Sophos disponibiliza várias funções:
- Service Principal Read-Only lê dados do tenant, mas não os pode alterar nem executar consultas Live Discover.
- Service Principal Management pode consultar, criar, alterar e eliminar utilizadores e grupos de utilizadores, consultar e processar Alerts, consultar Endpoints e iniciar ações como um scan, bem como consultar e alterar definições globais de Endpoint Protection. Além disso, a função gere administradores, funções e Security Policies, mas não tem acesso a consultas Live Discover.
- Service Principal Forensics cria, consulta, executa e elimina consultas Live Discover.
- Service Principal Directory Sync destina-se exclusivamente à sincronização do Active Directory e não pode executar outras tarefas de API.
- Service Principal Firewall limita a identidade à gestão de Firewalls e não permite tarefas de API do Central fora desse âmbito.
- Service Principal Audit Log permite que aplicações externas, ferramentas SIEM e scripts de integração obtenham eventos do Audit Log com acesso de consulta só de leitura.
- Service Principal Super Admin possui direitos abrangentes de leitura, escrita e eliminação, bem como acesso a consultas.
A seleção começa sempre pela função mais limitada. Uma integração de reporting ou de seguros cibernéticos recebe Read-Only. O AD Sync recebe a função prevista especificamente para esse efeito. Super Admin só é utilizado quando os endpoints de API documentados exigem efetivamente direitos de escrita abrangentes e nenhuma função mais limitada funciona.
Criar a Credential
Inicie sessão em fusion.sophos.com e abra Global Settings > Access Control > API Credentials. No primeiro acesso, é necessário aceitar os termos de utilização.
- Abrir Add Credential.
- Introduzir um nome inequívoco e uma descrição com a aplicação, o ambiente e o responsável.
- Selecionar a função Service Principal mínima necessária.
- Criar a Credential e copiar imediatamente o Client ID e o Client Secret.
- Guardar o secret num Secret Store empresarial e limpar a área de transferência temporária.
O Client Secret só é apresentado uma vez. Não pode voltar a ser mostrado posteriormente. Se for perdido, não se recupera o secret existente; cria-se uma nova Credential e elimina-se a antiga depois de a transição ter sido concluída com êxito.
Contrato da API, autenticação e região
O contrato comum utiliza POST https://id.sophos.com/api/v2/oauth2/token para OAuth2 e GET https://api.central.sophos.com/whoami/v1 para identificar a Credential. Credentials Partner e Enterprise consultam depois, respetivamente, GET https://api.central.sophos.com/partner/v1/tenants e GET https://api.central.sophos.com/organization/v1/tenants. Para a API de produto, utilizar apenas o host HTTPS devolvido em apiHosts.dataRegion ou apiHost; nunca deduzir a região.
Pedir um token de acesso com segurança
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
)
Uma resposta válida contém access_token, token_type: "bearer" e um expires_in numérico positivo; pode incluir ainda refresh_token, errorCode, message e trackingId. Nunca a registar e pedir um novo token quando expirar.
Avaliar whoami
O contrato de resposta whoami para um tenant e a resolução dos outros tipos são:
{
"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 do tenant de destino do mapeamento aprovado: ' 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
Cada pedido de produto do tenant associa exatamente Authorization: Bearer <token-de-acesso>, X-Tenant-ID: <uuid-do-tenant> e o apiHost regional desse mesmo tenant. O host global não substitui uma API de produto regional.
whoami devolve id, idType e apiHosts. Para Partner/Enterprise, o ID não é um Tenant ID: o ciclo exige cabeçalhos de autorização e contexto, está limitado a 1000 páginas, segue o valor real pages.total e exporta apenas uma correspondência UUID única com apiHost regional válido.
Validação e recuperação controlada
Antes de escrever, verificar idType, UUID, formato HTTPS do host, JSON, paginação e objetos esperados com uma leitura inofensiva. scope=token não concede direitos de produto; função, acesso ao tenant, licença e operação continuam a decidir. Para 400, verificar formulário; 401, Credential/expiração/secret; 403, função e acesso; 404, host/versão/caminho; 429, Retry-After e Backoff; 5xx, Request ID ou trackingId e tentativas limitadas. Nunca enviar Token ou secret ao suporte.
Se tenant ou host estiverem errados, interromper escritas e isolar dados recebidos. Eliminar a Credential bloqueia futuras chamadas, mas não reverte alterações: aplicar o rollback específico preparado e remover token, IDs, tenant, host e WHOAMI da sessão com unset.
unset SOPHOS_ACCESS_TOKEN SOPHOS_CLIENT_ID SOPHOS_ID SOPHOS_ID_TYPE
unset SOPHOS_TENANT_ID SOPHOS_API_HOST WHOAMI
Resolver problemas do acesso comum à API
Para 400, verificar formulário e campos; 401, Credential, expiração, secret, token e sintaxe Bearer; 403, função, acesso ao tenant e operação; 404, host global/regional, versão e caminho; 429, respeitar Retry-After e repetir dentro de um limite com backoff e jitter; 5xx, guardar Request ID ou trackingId e repetir dentro de um limite. Com idType inesperado ou apiHost em falta, não construir cabeçalhos de tenant. Nunca enviar token ou secret ao suporte.
Testar a autenticação de forma controlada
O primeiro teste não consiste numa ação de escrita em produção. Primeiro, obtém-se um OAuth Access Token através do endpoint Sophos Identity. Em seguida, o endpoint whoami devolve o Tenant ID, o API Host e o tipo de dados da conta. Só depois se executa uma chamada de leitura inofensiva ao API Host fornecido para o tenant.
O API Host não é copiado de um exemplo. A Sophos opera várias regiões de dados, pelo que se deve utilizar o URL fornecido por whoami. O Tenant ID e o Organization ID também não são intercambiáveis.
Para o teste, documentam-se pelo menos os seguintes casos:
- A autenticação com a nova identidade funciona.
- É devolvido o tenant esperado.
- As operações de leitura autorizadas funcionam.
- Uma operação não autorizada é rejeitada com
403 Forbidden. - O sistema de destino regista o teste de forma rastreável sem guardar o Client Secret.
Gerir a expiração e a rotação
A Sophos não envia qualquer aviso quando uma API Credential expira. Depois de expirar, já não pode ser utilizada para autenticação e é removida automaticamente do Sophos Fusion. Por isso, a monitorização tem de ser feita fora do Sophos Fusion.
Um processo de rotação correto utiliza uma sobreposição curta:
- Criar uma nova Credential com uma função idêntica ou mais limitada.
- Alterar a aplicação para o Client ID e o secret da nova Credential.
- Testar a autenticação e a função operacional.
- Eliminar a Credential antiga.
- Verificar a alteração no registo de secrets e na documentação operacional.
A Credential antiga não permanece ativa durante meses por precaução. Se uma aplicação suportar apenas um conjunto de secrets, planeia-se uma janela de manutenção.
Substituir antigos SIEM API Tokens
API Token Management é o método de autenticação anterior para a SIEM Integration API. A Sophos já não emite novos tokens nessa área nem prolonga a validade dos existentes. Os tokens existentes só funcionam até à respetiva expiração.
Uma integração que ainda os utilize não deve ser mantida até ao último dia. Inventariam-se o token, o sistema de destino, a data de expiração e os endpoints utilizados, cria-se uma API Credential adequada, altera-se a aplicação e verifica-se o fluxo de dados completo. O token antigo só é removido depois de uma verificação paralela bem-sucedida.
A mudança de um Legacy Token para API Credentials não é uma simples alteração de nome. A integração tem de suportar a autenticação OAuth, whoami, o Regional Host e o modelo de funções. Por isso, um SIEM Connector é configurado com base nas instruções atuais do fabricante e não através de um exemplo antigo de token.
Prestadores externos e acesso de terceiros
Para uma entidade externa, cria-se uma identidade Service Principal Read-Only própria, desde que bastem direitos de leitura. O Client ID e o secret são transmitidos através de um canal separado e cifrado. Define-se uma data final para o acesso, que é eliminado no fim do projeto.
Através da API, este acesso de terceiros pode ler, em particular, Alerts e Events, resultados do Account Health Check, detalhes de dispositivos e configurações de Policy. Read-Only impede a adição, alteração e eliminação no Sophos Fusion, mas não limita automaticamente os dados legíveis que a plataforma de terceiros consulta ou armazena efetivamente. Antes da autorização, clarificam-se contratualmente o âmbito dos dados, a finalidade da utilização, o local de armazenamento, a retenção e a eliminação.
A criação segue o caminho normal Global Settings > Access Control > API Credentials > Add Credential. No primeiro acesso, confirmam-se os termos de utilização e de proteção de dados, seleciona-se a função Service Principal Read-Only e copiam-se imediatamente e de forma segura o Client ID e o Client Secret, que só é apresentado uma vez. A transmissão é feita através de um canal cifrado aprovado, por exemplo o portal HTTPS do fornecedor, e não por e-mail ou no texto de um ticket.
O API Host não é copiado de uma tabela regional estática. A aplicação utiliza whoami para determinar o API Host válido para esse tenant específico. Desta forma, a integração continua corretamente documentada mesmo que a Sophos altere regiões ou endpoints. Assim que o fornecedor deixar de necessitar do acesso, a Credential é eliminada, revogando imediatamente a autorização de API.
Não é aceitável exportar a conta pessoal de Super Admin, utilizar uma identidade de API comum para vários clientes ou colocar um secret num ticket de suporte. O prestador também tem de indicar onde o secret é guardado, como é protegido e quando é eliminado.
Isolar erros de forma direcionada
401 Unauthorized
Na maioria dos casos, o Client ID, o secret, o Token Endpoint ou o OAuth Request estão incorretos. Uma Credential expirada e já removida também provoca este erro. Primeiro, verifica-se se a Credential ainda existe no Sophos Fusion e se a aplicação utiliza realmente o conjunto de secrets mais recente.
403 Forbidden
A autenticação foi bem-sucedida, mas a função não permite a ação. Em vez de atribuir imediatamente Super Admin, associa-se o endpoint de API necessário à função Service Principal adequada.
Token correto, região de dados errada
O Access Token, por si só, não determina o API Host funcional. A aplicação tem de utilizar o Regional Host fornecido por whoami. Um Host fixo de outra região provoca erros ou consultas no limite errado da plataforma.
A integração falha sem aviso
Se o Sophos Fusion não mostrar um Alert aberto, verificam-se a data de expiração, a última chamada de API bem-sucedida e a versão do secret no sistema de destino. A monitorização da expiração pertence à monitorização externa.
Revisão regular
Pelo menos trimestralmente, verificam-se o nome, o responsável, a função, a última utilização, a expiração e o sistema de destino de cada Credential. As identidades não atribuíveis ou não utilizadas são eliminadas. Se houver suspeita de fuga de um secret, a Credential afetada é imediatamente eliminada e substituída por uma nova. Em seguida, analisam-se os registos do sistema de destino e da integração à procura de chamadas de API anómalas.
Os direitos pessoais de administrador são verificados separadamente de acordo com Atribuir corretamente funções administrativas no Sophos Fusion. As API Credentials não substituem o MFA nem um acesso pessoal e rastreável de administrador.