Skip to content

Python SDK & CLI

Betreut von: Aether365 Team Zielgruppe: Entwickler und DevOps-Engineers Umfang: Installation und Nutzung des offiziellen aether365 Python SDK und der Kommandozeile

Das Paket aether365 ist das offizielle Python SDK und Kommandozeilen-Tool für die Aether365 API. Es kapselt https://api.aether365.io, übernimmt die Authentifizierung, packt den Response-Envelope aus und wiederholt Anfragen bei vorübergehenden Störungen automatisch. Alles, was mit curl möglich ist, geht auch mit dem SDK oder der CLI.

SDK und CLI verwenden einen API-Schlüssel (ak_live_...) und sprechen den einheitlichen Endpunkt an - Anfragen werden automatisch in die Heimatregion Ihres Tenants geroutet. Wie die Schlüssel funktionieren, steht unter Authentifizierung.

Installation

Das Paket wird intern verteilt (nicht über PyPI). Installieren Sie es direkt aus dem Repository oder einem lokalen Checkout.

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

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

Erforderlich ist Python 3.12 oder neuer. Mit der Installation landet auch der Befehl aether365 auf Ihrem PATH.

Konfiguration

SDK und CLI lesen dieselben Umgebungsvariablen:

VariableZweckStandard
AETHER365_API_KEYIhr API-Schlüssel (ak_live_...). Erforderlich.-
AETHER365_API_URLÜberschreibt die Basis-URL (zum Beispiel für den Dev-Endpunkt).https://api.aether365.io
AETHER365_OUTPUTAusgabeformat der CLI: table oder json.table
bash
export AETHER365_API_KEY="ak_live_..."

Die Region ist automatisch: Die API ermittelt Ihren Tenant anhand des Schlüssels und leitet an die richtige Region weiter - Sie konfigurieren oder übergeben nie eine Region.

Schnellstart: 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")

Schnellstart: 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

Was ein API-Schlüssel kann und was nicht

Ein API-Schlüssel ist auf eine sichere, lesende und operative Oberfläche beschränkt. Er kann Ihre Daten lesen, Scans starten und verwalten, Reports erzeugen und Attack-Surface-Ziele verwalten. Er kann keine Aktionen ausführen, die das Konto steuern oder das Directory aussperren könnten - API-Schlüssel-Verwaltung, Abrechnung, Team-Mitgliedschaften, das An- und Abbinden von Verbindungen, SSO, das Anwenden eines Remediation-Plans oder die Conditional-Access-/Break-Glass-Schreibzugriffe des AI Pilot. Diese bleiben einer angemeldeten Sitzung im Dashboard vorbehalten. Eine Anfrage an eine nicht erlaubte Route liefert 403 AUTH_INSUFFICIENT_SCOPE.

Befehls- und Methodenreferenz

Jede Zeile zeigt dieselbe Operation auf drei Arten: als rohes curl, als SDK-Methode und als CLI-Befehl.

Tenant und Konto

OperationcurlSDKCLI
Tenant-Profil abrufenGET /tenants/meclient.tenants.me()aether365 tenant me
Verbindungen auflistenGET /tenants/me/connectionsclient.connections.list()aether365 tenant connections
BenachrichtigungseinstellungenGET /tenants/me/notificationsclient.notifications.get()aether365 tenant notifications
Geplante ScansGET /tenants/me/scheduled-scansclient.scheduled_scans.list()aether365 tenant scheduled-scans

Scans

OperationcurlSDKCLI
Scans auflistenGET /tenants/me/scansclient.scans.list()aether365 scan list
Scan startenPOST /tenants/me/scansclient.scans.create("compliance")aether365 scan run --type compliance
Scan abrufenGET /scans/{id}client.scans.get(id)aether365 scan get <id>
Ergebnisse lesenGET /scans/{id}/resultsclient.scans.results(id)aether365 scan results <id>
Scan abbrechenPOST /scans/{id}/cancelclient.scans.cancel(id)aether365 scan cancel <id>
Scan ausblendenPATCH /scans/{id}/hideclient.scans.hide(id)aether365 scan hide <id>
Scan wieder einblendenPATCH /scans/{id}/unhideclient.scans.unhide(id)aether365 scan unhide <id>
Scan löschenDELETE /scans/{id}client.scans.delete(id)aether365 scan delete <id>

Das curl zum Starten eines Scans:

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

Reports

OperationcurlSDKCLI
Report-StatusGET /scans/{id}/reportclient.reports.status(id)aether365 report status <id>
Report erzeugenPOST /scans/{id}/report/generateclient.reports.generate(id)aether365 report generate <id>
Reports auflistenGET /tenants/me/reportsclient.reports.list()aether365 report list
Report herunterladenGET /scans/{id}/report (presigned)client.reports.download(id, path)aether365 report download <id> -o out.pdf

Der Report-Status ist einer von ready, rendering, orgNameRequired oder locked. Das Erzeugen eines Reports kann ein Report-Guthaben verbrauchen (eine Einmalzahlung, wenn kein Kontingent enthalten ist) - der Schlüsselinhaber stimmt dem durch den Aufruf von generate ausdrücklich zu.

Die Report-Liste ist offset-paginiert: Geben Sie meta["nextCursor"] (einen ganzzahligen Zeilen-Offset, auf der letzten Seite None) als cursor zurück. client.reports.iter_all() folgt dem Cursor für Sie.

Attack Surface

OperationcurlSDKCLI
ÜberblickGET /tenants/me/attack-surfaceclient.attack_surface.summary()aether365 eas summary
VerlaufGET /tenants/me/attack-surface/historyclient.attack_surface.history()aether365 eas history
Ziele auflistenGET /tenants/me/attack-surface/targetsclient.attack_surface.targets()aether365 eas targets list
Ziel hinzufügenPOST /tenants/me/attack-surface/targetsclient.attack_surface.add_target(host)aether365 eas targets add <host>
Ziel aktualisierenPATCH /tenants/me/attack-surface/targets/{id}client.attack_surface.update_target(id, ...)aether365 eas targets update <id> --label ...
Ziel löschenDELETE /tenants/me/attack-surface/targets/{id}client.attack_surface.remove_target(id)aether365 eas targets remove <id>
Ziel verifizierenPOST /tenants/me/attack-surface/targets/{id}/verifyclient.attack_surface.verify_target(id)aether365 eas targets verify <id>
EAS-Scan startenPOST /tenants/me/attack-surface/scanclient.attack_surface.scan()aether365 eas scan

Posture, Remediation und AI Pilot

OperationcurlSDKCLI
Bedrohungs-/RisikoansichtGET /tenants/me/threatsclient.threats.list()aether365 threats
Policy-PostureGET /tenants/me/policiesclient.policies.list()aether365 policies
Remediation-FähigkeitenGET /tenants/me/remediation/capabilitiesclient.remediation.capabilities()aether365 remediation capabilities
Remediation-Pläne auflistenGET /tenants/me/remediation-plansclient.remediation.plans()aether365 remediation plans
Remediation-Plan abrufenGET /tenants/me/remediation-plans/{id}client.remediation.plan(id)aether365 remediation plan <id>
AI Pilot remediableGET /tenants/me/ai-pilot/remediableclient.ai_pilot.remediable()aether365 ai-pilot remediable
AI Pilot Break-GlassGET /tenants/me/ai-pilot/break-glassclient.ai_pilot.break_glass()aether365 ai-pilot break-glass
AI Pilot CA-PoliciesGET /tenants/me/ai-pilot/conditional-accessclient.ai_pilot.conditional_access()aether365 ai-pilot conditional-access

Remediation ist für API-Schlüssel schreibgeschützt. Das Anwenden eines Plans ist nicht verfügbar: Die Action-Registry-Einträge eines Plans können Conditional-Access-/Authorization-Policy-Patches enthalten, die einen Tenant aus seinem eigenen Directory aussperren würden (AADSTS50097). Das Anwenden bleibt deshalb im Dashboard, mit einem Operator im Loop. AI Pilot Conditional-Access und Break-Glass sind aus demselben Grund ebenfalls nur lesend verfügbar.

Fehlerbehandlung und Retries

Jeder API-Fehler wird auf eine typisierte Exception-Unterklasse von Aether365Error abgebildet:

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.")

Der Client wiederholt 429 RATE_LIMITED und 503 SERVICE_STARTING (das Aufwärmen der kalten Dev-Datenbank) automatisch mit exponentiellem Backoff und berücksichtigt dabei den Retry-After-Header. Quota-Fehler wie SCAN_PLAN_LIMIT_REACHED werden sofort geworfen - sie werden nicht wiederholt.

Die CLI in CI verwenden

aether365 scan results <id> --fail-on-findings beendet sich mit Exit-Code 2, sobald mindestens ein fehlgeschlagenes Finding vorliegt - damit kann eine Pipeline auf Scan-Ergebnisse gaten:

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

Die CLI schreibt Fehler nach stderr und beendet sich mit 1 bei jedem API-Fehler und mit 2 am Findings-Gate.

War diese Seite hilfreich?