Skip to content

SDK Python e CLI

O pacote aether365 é o SDK Python oficial e a interface de linha de comandos da API da Aether365. Encapsula https://api.aether365.io, trata da autenticação, extrai o envelope de resposta e repete automaticamente os pedidos em caso de falhas transitórias. Tudo o que pode fazer com curl pode fazê-lo com o SDK ou a CLI.

O SDK e a CLI usam uma chave de API (ak_live_...) e apontam para o endpoint unificado: os pedidos são encaminhados automaticamente para a região de origem do seu tenant. Consulte Autenticação para perceber como funcionam as chaves.

Instalação

O pacote é distribuído internamente (não está no PyPI). Instale-o diretamente a partir do repositório ou de um checkout local.

bash
# From a local checkout of the monorepo
pip install ./packages/cli

# Or with Poetry, from a path
poetry add ./packages/cli

É necessário Python 3.12 ou mais recente. A instalação do pacote também disponibiliza o comando aether365 no seu PATH.

Configuração

Tanto o SDK como a CLI leem as mesmas variáveis de ambiente:

VariávelFinalidadePredefinição
AETHER365_API_KEYA sua chave de API (ak_live_...). Obrigatória.-
AETHER365_API_URLSubstitui o URL base (por exemplo, o endpoint de dev).https://api.aether365.io
AETHER365_OUTPUTFormato de saída da CLI: table ou json.table
bash
export AETHER365_API_KEY="ak_live_..."

A região é automática: a API resolve o seu tenant a partir da chave e encaminha o pedido para a região correta, pelo que nunca precisa de configurar nem passar uma região.

Início rápido: SDK

python
from aether365 import Aether365Client

with Aether365Client() as client:          # reads AETHER365_API_KEY
    tenant = client.tenants.me()
    print(tenant["name"])

    # Trigger a scan and wait for it to finish
    scan = client.scans.create("compliance")
    for snapshot in client.scans.wait(scan["id"]):
        print(snapshot["status"])

    # Read the findings
    findings = client.scans.results(scan["id"], result="Failed")
    print(f"{len(findings)} failed checks")

Início rápido: CLI

bash
# Show the authenticated tenant
aether365 tenant me

# Trigger a scan and follow progress until it finishes
aether365 scan run --type compliance --watch

# List scans as JSON
aether365 --output json scan list

# Fail a CI job when a scan has failed findings (exit code 2)
aether365 scan results <SCAN_ID> --fail-on-findings

O que uma chave de API pode e não pode fazer

Uma chave de API está limitada a uma superfície segura, de leitura e operações. Pode ler os seus dados, iniciar e gerir scans, gerar relatórios e gerir os alvos de superfície de ataque. Não pode executar ações de controlo de conta nem de bloqueio do diretório: gestão de chaves de API, faturação, membros da equipa, adição/remoção de ligações, SSO, aplicação de um plano de remediação ou as escritas conditional-access/break-glass do AI Pilot. Essas ações continuam disponíveis apenas para uma sessão iniciada no dashboard. Um pedido a uma rota não permitida devolve 403 AUTH_INSUFFICIENT_SCOPE.

Referência de comandos e métodos

Cada linha mostra a mesma operação de três formas: curl puro, o método do SDK e o comando da CLI.

Tenant e conta

OperaçãocurlSDKCLI
Obter o perfil do tenantGET /tenants/meclient.tenants.me()aether365 tenant me
Listar ligaçõesGET /tenants/me/connectionsclient.connections.list()aether365 tenant connections
Preferências de notificaçãoGET /tenants/me/notificationsclient.notifications.get()aether365 tenant notifications
Scans agendadosGET /tenants/me/scheduled-scansclient.scheduled_scans.list()aether365 tenant scheduled-scans

Scans

OperaçãocurlSDKCLI
Listar scansGET /tenants/me/scansclient.scans.list()aether365 scan list
Iniciar um scanPOST /tenants/me/scansclient.scans.create("compliance")aether365 scan run --type compliance
Obter um scanGET /scans/{id}client.scans.get(id)aether365 scan get <id>
Ler resultadosGET /scans/{id}/resultsclient.scans.results(id)aether365 scan results <id>
Cancelar um scanPOST /scans/{id}/cancelclient.scans.cancel(id)aether365 scan cancel <id>
Ocultar um scanPATCH /scans/{id}/hideclient.scans.hide(id)aether365 scan hide <id>
Voltar a mostrar um scanPATCH /scans/{id}/unhideclient.scans.unhide(id)aether365 scan unhide <id>
Eliminar um scanDELETE /scans/{id}client.scans.delete(id)aether365 scan delete <id>

O curl para iniciar um scan:

bash
curl -X POST https://api.aether365.io/tenants/me/scans \
  -H "Authorization: Bearer $AETHER365_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"scanType": "compliance"}'

Relatórios

OperaçãocurlSDKCLI
Estado do relatórioGET /scans/{id}/reportclient.reports.status(id)aether365 report status <id>
Gerar um relatórioPOST /scans/{id}/report/generateclient.reports.generate(id)aether365 report generate <id>
Listar relatóriosGET /tenants/me/reportsclient.reports.list()aether365 report list
Transferir um relatórioGET /scans/{id}/report (presigned)client.reports.download(id, path)aether365 report download <id> -o out.pdf

O estado de um relatório é um de ready, rendering, orgNameRequired ou locked. Gerar um relatório pode consumir um crédito de relatório (um pagamento único quando o plano não inclui saldo): é o titular da chave que aceita esse custo ao chamar generate.

A listagem de relatórios é paginada por offset: devolva meta["nextCursor"] (um offset de linha inteiro, ou None na última página) como cursor. client.reports.iter_all() segue o cursor por si.

Superfície de ataque

OperaçãocurlSDKCLI
Visão geralGET /tenants/me/attack-surfaceclient.attack_surface.summary()aether365 eas summary
HistóricoGET /tenants/me/attack-surface/historyclient.attack_surface.history()aether365 eas history
Listar alvosGET /tenants/me/attack-surface/targetsclient.attack_surface.targets()aether365 eas targets list
Adicionar um alvoPOST /tenants/me/attack-surface/targetsclient.attack_surface.add_target(host)aether365 eas targets add <host>
Atualizar um alvoPATCH /tenants/me/attack-surface/targets/{id}client.attack_surface.update_target(id, ...)aether365 eas targets update <id> --label ...
Eliminar um alvoDELETE /tenants/me/attack-surface/targets/{id}client.attack_surface.remove_target(id)aether365 eas targets remove <id>
Verificar um alvoPOST /tenants/me/attack-surface/targets/{id}/verifyclient.attack_surface.verify_target(id)aether365 eas targets verify <id>
Executar um scan EASPOST /tenants/me/attack-surface/scanclient.attack_surface.scan()aether365 eas scan

Postura, remediação e AI Pilot

OperaçãocurlSDKCLI
Vista de ameaças / riscosGET /tenants/me/threatsclient.threats.list()aether365 threats
Postura de políticasGET /tenants/me/policiesclient.policies.list()aether365 policies
Capacidades de remediaçãoGET /tenants/me/remediation/capabilitiesclient.remediation.capabilities()aether365 remediation capabilities
Listar planos de remediaçãoGET /tenants/me/remediation-plansclient.remediation.plans()aether365 remediation plans
Obter um plano de remediaçãoGET /tenants/me/remediation-plans/{id}client.remediation.plan(id)aether365 remediation plan <id>
Remediáveis do AI PilotGET /tenants/me/ai-pilot/remediableclient.ai_pilot.remediable()aether365 ai-pilot remediable
Break-glass do AI PilotGET /tenants/me/ai-pilot/break-glassclient.ai_pilot.break_glass()aether365 ai-pilot break-glass
Políticas CA do AI PilotGET /tenants/me/ai-pilot/conditional-accessclient.ai_pilot.conditional_access()aether365 ai-pilot conditional-access

A remediação é apenas de leitura para chaves de API. A aplicação de um plano não está exposta: os itens do action-registry de um plano podem incluir patches de Conditional-Access / authorization-policy capazes de deixar um tenant bloqueado fora do próprio diretório (AADSTS50097), pelo que a aplicação fica no dashboard com um operador a acompanhar. As vistas conditional-access e break-glass do AI Pilot são igualmente expostas apenas em leitura pelo mesmo motivo.

Tratamento de erros e novas tentativas

Cada erro da API corresponde a uma exceção tipada, subclasse de Aether365Error:

python
from aether365 import Aether365Client
from aether365.exceptions import PermissionError_, PlanLimitError, NotFoundError

with Aether365Client() as client:
    try:
        client.scans.create("compliance")
    except PlanLimitError:
        print("Scan quota reached for this plan.")
    except PermissionError_:
        print("Route not allowed for this key, or plan lacks API access.")
    except NotFoundError:
        print("Resource not found.")

O cliente repete automaticamente 429 RATE_LIMITED e 503 SERVICE_STARTING (o arranque a frio da base de dados em dev) com backoff exponencial, respeitando o cabeçalho Retry-After. Os erros de quota como SCAN_PLAN_LIMIT_REACHED são lançados de imediato: não são repetidos.

Usar a CLI em CI

aether365 scan results <id> --fail-on-findings termina com o código 2 quando existe algum resultado falhado, pelo que um pipeline pode condicionar a sua conclusão aos resultados do scan:

bash
aether365 scan run --type compliance --watch
aether365 scan results "$SCAN_ID" --fail-on-findings

A CLI escreve os erros no stderr e termina com 1 em qualquer erro da API e com 2 na barreira de findings.

Esta página foi útil?