Skip to content

SDK Pythona i CLI

Autor: Zespół Aether365 Odbiorcy: Programiści i inżynierowie DevOps Zakres: Instalacja i korzystanie z oficjalnego SDK Pythona aether365 oraz interfejsu wiersza poleceń

Pakiet aether365 to oficjalny SDK Pythona i interfejs wiersza poleceń dla API Aether365. Opakowuje https://api.aether365.io, obsługuje uwierzytelnianie, rozpakowuje kopertę odpowiedzi i automatycznie ponawia żądania przy przejściowych błędach. Wszystko, co da się zrobić przez curl, da się też zrobić przez SDK lub CLI.

SDK i CLI używają klucza API (ak_live_...) i kierują żądania na ujednolicony endpoint - zapytania trafiają automatycznie do regionu macierzystego Twojego tenanta. Jak działają klucze, opisuje strona Uwierzytelnianie.

Instalacja

Pakiet jest dystrybuowany wewnętrznie (nie przez PyPI). Zainstaluj go bezpośrednio z repozytorium lub z lokalnej kopii.

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

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

Wymagany jest Python 3.12 lub nowszy. Instalacja pakietu dodaje też polecenie aether365 do PATH.

Konfiguracja

Zarówno SDK, jak i CLI czytają te same zmienne środowiskowe:

ZmiennaPrzeznaczenieDomyślnie
AETHER365_API_KEYTwój klucz API (ak_live_...). Wymagany.-
AETHER365_API_URLNadpisanie bazowego URL (np. endpointu dev).https://api.aether365.io
AETHER365_OUTPUTFormat wyjścia CLI: table lub json.table
bash
export AETHER365_API_KEY="ak_live_..."

Region jest automatyczny: API rozpoznaje tenanta po kluczu i przekazuje żądanie do właściwego regionu, więc regionu nigdy nie konfigurujesz ani nie przekazujesz.

Szybki start: 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")

Szybki start: 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

Co klucz API może, a czego nie

Klucz API ma bezpieczny zakres: odczyt plus operacje bieżące. Może czytać Twoje dane, uruchamiać skany i nimi zarządzać, generować raporty oraz zarządzać celami attack surface. Nie może wykonywać działań kontrolujących konto ani grożących zablokowaniem katalogu - zarządzania kluczami API, rozliczeń, członkostwa w zespole, podłączania/odłączania połączeń, SSO, zastosowania planu remediacji ani zapisów AI Pilot dotyczących conditional access / break-glass. Te operacje pozostają dostępne wyłącznie w zalogowanej sesji w dashboardzie. Żądanie do niedozwolonej trasy zwraca 403 AUTH_INSUFFICIENT_SCOPE.

Przegląd poleceń i metod

Każdy wiersz pokazuje tę samą operację na trzy sposoby: surowy curl, metoda SDK i polecenie CLI.

Tenant i konto

OperacjacurlSDKCLI
Pobranie profilu tenantaGET /tenants/meclient.tenants.me()aether365 tenant me
Lista połączeńGET /tenants/me/connectionsclient.connections.list()aether365 tenant connections
Preferencje powiadomieńGET /tenants/me/notificationsclient.notifications.get()aether365 tenant notifications
Zaplanowane skanyGET /tenants/me/scheduled-scansclient.scheduled_scans.list()aether365 tenant scheduled-scans

Skany

OperacjacurlSDKCLI
Lista skanówGET /tenants/me/scansclient.scans.list()aether365 scan list
Uruchomienie skanuPOST /tenants/me/scansclient.scans.create("compliance")aether365 scan run --type compliance
Pobranie skanuGET /scans/{id}client.scans.get(id)aether365 scan get <id>
Odczyt wynikówGET /scans/{id}/resultsclient.scans.results(id)aether365 scan results <id>
Anulowanie skanuPOST /scans/{id}/cancelclient.scans.cancel(id)aether365 scan cancel <id>
Ukrycie skanuPATCH /scans/{id}/hideclient.scans.hide(id)aether365 scan hide <id>
Przywrócenie skanuPATCH /scans/{id}/unhideclient.scans.unhide(id)aether365 scan unhide <id>
Usunięcie skanuDELETE /scans/{id}client.scans.delete(id)aether365 scan delete <id>

Wywołanie curl uruchamiające skan:

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"}'

Raporty

OperacjacurlSDKCLI
Status raportuGET /scans/{id}/reportclient.reports.status(id)aether365 report status <id>
Wygenerowanie raportuPOST /scans/{id}/report/generateclient.reports.generate(id)aether365 report generate <id>
Lista raportówGET /tenants/me/reportsclient.reports.list()aether365 report list
Pobranie pliku raportuGET /scans/{id}/report (presigned)client.reports.download(id, path)aether365 report download <id> -o out.pdf

Status raportu to jedna z wartości: ready, rendering, orgNameRequired lub locked. Wygenerowanie raportu może zużyć kredyt raportowy (jednorazowa opłata, gdy plan nie zawiera przydziału) - właściciel klucza wyraża na to zgodę, wywołując generate.

Lista raportów jest stronicowana offsetowo: przekaż meta["nextCursor"] (całkowitoliczbowy offset wiersza albo None na ostatniej stronie) z powrotem jako cursor. client.reports.iter_all() podąża za kursorem za Ciebie.

Attack surface

OperacjacurlSDKCLI
PodsumowanieGET /tenants/me/attack-surfaceclient.attack_surface.summary()aether365 eas summary
HistoriaGET /tenants/me/attack-surface/historyclient.attack_surface.history()aether365 eas history
Lista celówGET /tenants/me/attack-surface/targetsclient.attack_surface.targets()aether365 eas targets list
Dodanie celuPOST /tenants/me/attack-surface/targetsclient.attack_surface.add_target(host)aether365 eas targets add <host>
Aktualizacja celuPATCH /tenants/me/attack-surface/targets/{id}client.attack_surface.update_target(id, ...)aether365 eas targets update <id> --label ...
Usunięcie celuDELETE /tenants/me/attack-surface/targets/{id}client.attack_surface.remove_target(id)aether365 eas targets remove <id>
Weryfikacja celuPOST /tenants/me/attack-surface/targets/{id}/verifyclient.attack_surface.verify_target(id)aether365 eas targets verify <id>
Uruchomienie skanu EASPOST /tenants/me/attack-surface/scanclient.attack_surface.scan()aether365 eas scan

Postawa bezpieczeństwa, remediacja i AI Pilot

OperacjacurlSDKCLI
Widok zagrożeń i ryzykaGET /tenants/me/threatsclient.threats.list()aether365 threats
Postawa politykGET /tenants/me/policiesclient.policies.list()aether365 policies
Możliwości remediacjiGET /tenants/me/remediation/capabilitiesclient.remediation.capabilities()aether365 remediation capabilities
Lista planów remediacjiGET /tenants/me/remediation-plansclient.remediation.plans()aether365 remediation plans
Pobranie planu remediacjiGET /tenants/me/remediation-plans/{id}client.remediation.plan(id)aether365 remediation plan <id>
AI Pilot: elementy do naprawyGET /tenants/me/ai-pilot/remediableclient.ai_pilot.remediable()aether365 ai-pilot remediable
AI Pilot: konta break-glassGET /tenants/me/ai-pilot/break-glassclient.ai_pilot.break_glass()aether365 ai-pilot break-glass
AI Pilot: polityki CAGET /tenants/me/ai-pilot/conditional-accessclient.ai_pilot.conditional_access()aether365 ai-pilot conditional-access

Remediacja jest dla kluczy API tylko do odczytu. Zastosowanie planu nie jest udostępnione: pozycje planu z rejestru akcji mogą zawierać poprawki Conditional Access / authorization policy, które odcięłyby tenanta od jego własnego katalogu (AADSTS50097), więc apply pozostaje w dashboardzie, z operatorem w pętli decyzyjnej. Z tego samego powodu conditional-access i break-glass w AI Pilot są również dostępne wyłącznie do odczytu.

Obsługa błędów i ponawianie

Każdy błąd API mapuje się na typowany wyjątek dziedziczący po 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.")

Klient automatycznie ponawia 429 RATE_LIMITED i 503 SERVICE_STARTING (rozgrzewanie zimnej bazy w środowisku dev) z wykładniczym backoffem, respektując nagłówek Retry-After. Błędy limitów, takie jak SCAN_PLAN_LIMIT_REACHED, są zgłaszane natychmiast - nie są ponawiane.

Użycie CLI w CI

aether365 scan results <id> --fail-on-findings kończy się kodem 2, gdy istnieje jakiekolwiek nieudane znalezisko, więc pipeline może uzależnić przejście od wyników skanu:

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

CLI zapisuje błędy na stderr i kończy się kodem 1 przy dowolnym błędzie API, a kodem 2 na bramce znalezisk.

Czy ta strona była pomocna?