Python SDK & CLI
Onderhouden door: Aether365 Team Doelgroep: Developers en DevOps-engineers Scope: Installatie en gebruik van de officiële aether365 Python SDK en command line interface
Het pakket aether365 is de officiële Python SDK en command line interface voor de Aether365 API. Het wikkelt https://api.aether365.io in, regelt de authenticatie, pakt de response-envelope uit en probeert tijdelijke fouten automatisch opnieuw. Alles wat met curl kan, kan ook met de SDK of de CLI.
De SDK en CLI gebruiken een API key (ak_live_...) en richten zich op het unified endpoint - verzoeken worden automatisch naar de thuisregio van je tenant gerouteerd. Zie Authenticatie voor hoe keys werken.
Installatie
Het pakket wordt intern gedistribueerd (niet via PyPI). Installeer het rechtstreeks vanuit de repository of een lokale checkout.
bash
# From a local checkout of the monorepo
pip install ./packages/cli
# Or with Poetry, from a path
poetry add ./packages/cliPython 3.12 of nieuwer is vereist. Bij installatie komt ook het commando aether365 op je PATH te staan.
Configuratie
Zowel de SDK als de CLI lezen dezelfde omgevingsvariabelen:
| Variabele | Doel | Standaard |
|---|---|---|
AETHER365_API_KEY | Je API key (ak_live_...). Verplicht. | - |
AETHER365_API_URL | Overschrijft de basis-URL (bijvoorbeeld het dev-endpoint). | https://api.aether365.io |
AETHER365_OUTPUT | Uitvoerformaat van de CLI: table of json. | table |
bash
export AETHER365_API_KEY="ak_live_..."De regio gaat vanzelf: de API leidt je tenant af uit de key en stuurt door naar de juiste regio, dus je hoeft nooit een regio te configureren of mee te geven.
Snelstart: 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")Snelstart: 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-findingsWat een API key wel en niet kan
Een API key is beperkt tot een veilig, lezend en operationeel oppervlak. Hij kan je gegevens lezen, scans starten en beheren, rapporten genereren en attack-surface-targets beheren. Hij kan geen acties uitvoeren die het account besturen of de directory kunnen buitensluiten - API key-beheer, facturering, teamlidmaatschap, het aan- en afkoppelen van verbindingen, SSO, het toepassen van een remediation-plan of de conditional-access-/break-glass-writes van AI Pilot. Die blijven alleen beschikbaar voor een ingelogde sessie in het dashboard. Een verzoek naar een niet-toegestane route geeft 403 AUTH_INSUFFICIENT_SCOPE.
Commando- en methodereferentie
Elke rij toont dezelfde operatie op drie manieren: als kale curl, als SDK-methode en als CLI-commando.
Tenant en account
| Operatie | curl | SDK | CLI |
|---|---|---|---|
| Tenantprofiel opvragen | GET /tenants/me | client.tenants.me() | aether365 tenant me |
| Verbindingen weergeven | GET /tenants/me/connections | client.connections.list() | aether365 tenant connections |
| Notificatievoorkeuren | GET /tenants/me/notifications | client.notifications.get() | aether365 tenant notifications |
| Geplande scans | GET /tenants/me/scheduled-scans | client.scheduled_scans.list() | aether365 tenant scheduled-scans |
Scans
| Operatie | curl | SDK | CLI |
|---|---|---|---|
| Scans weergeven | GET /tenants/me/scans | client.scans.list() | aether365 scan list |
| Scan starten | POST /tenants/me/scans | client.scans.create("compliance") | aether365 scan run --type compliance |
| Scan opvragen | GET /scans/{id} | client.scans.get(id) | aether365 scan get <id> |
| Resultaten lezen | GET /scans/{id}/results | client.scans.results(id) | aether365 scan results <id> |
| Scan annuleren | POST /scans/{id}/cancel | client.scans.cancel(id) | aether365 scan cancel <id> |
| Scan verbergen | PATCH /scans/{id}/hide | client.scans.hide(id) | aether365 scan hide <id> |
| Scan weer tonen | PATCH /scans/{id}/unhide | client.scans.unhide(id) | aether365 scan unhide <id> |
| Scan verwijderen | DELETE /scans/{id} | client.scans.delete(id) | aether365 scan delete <id> |
De curl om een scan te starten:
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"}'Rapporten
| Operatie | curl | SDK | CLI |
|---|---|---|---|
| Rapportstatus | GET /scans/{id}/report | client.reports.status(id) | aether365 report status <id> |
| Rapport genereren | POST /scans/{id}/report/generate | client.reports.generate(id) | aether365 report generate <id> |
| Rapporten weergeven | GET /tenants/me/reports | client.reports.list() | aether365 report list |
| Rapport downloaden | GET /scans/{id}/report (presigned) | client.reports.download(id, path) | aether365 report download <id> -o out.pdf |
De rapportstatus is een van ready, rendering, orgNameRequired of locked. Het genereren van een rapport kan een rapportcredit kosten (een eenmalige betaling wanneer geen tegoed is inbegrepen) - de eigenaar van de key kiest daar zelf voor door generate aan te roepen.
De rapportlijst is offset-gepagineerd: geef meta["nextCursor"] (een integer rij-offset, of None op de laatste pagina) terug als cursor. client.reports.iter_all() volgt de cursor voor je.
Attack surface
| Operatie | curl | SDK | CLI |
|---|---|---|---|
| Overzicht | GET /tenants/me/attack-surface | client.attack_surface.summary() | aether365 eas summary |
| Geschiedenis | GET /tenants/me/attack-surface/history | client.attack_surface.history() | aether365 eas history |
| Targets weergeven | GET /tenants/me/attack-surface/targets | client.attack_surface.targets() | aether365 eas targets list |
| Target toevoegen | POST /tenants/me/attack-surface/targets | client.attack_surface.add_target(host) | aether365 eas targets add <host> |
| Target bijwerken | PATCH /tenants/me/attack-surface/targets/{id} | client.attack_surface.update_target(id, ...) | aether365 eas targets update <id> --label ... |
| Target verwijderen | DELETE /tenants/me/attack-surface/targets/{id} | client.attack_surface.remove_target(id) | aether365 eas targets remove <id> |
| Target verifiëren | POST /tenants/me/attack-surface/targets/{id}/verify | client.attack_surface.verify_target(id) | aether365 eas targets verify <id> |
| EAS-scan uitvoeren | POST /tenants/me/attack-surface/scan | client.attack_surface.scan() | aether365 eas scan |
Posture, remediation en AI Pilot
| Operatie | curl | SDK | CLI |
|---|---|---|---|
| Dreigings-/risicoweergave | GET /tenants/me/threats | client.threats.list() | aether365 threats |
| Policy-posture | GET /tenants/me/policies | client.policies.list() | aether365 policies |
| Remediation-mogelijkheden | GET /tenants/me/remediation/capabilities | client.remediation.capabilities() | aether365 remediation capabilities |
| Remediation-plannen weergeven | GET /tenants/me/remediation-plans | client.remediation.plans() | aether365 remediation plans |
| Remediation-plan opvragen | GET /tenants/me/remediation-plans/{id} | client.remediation.plan(id) | aether365 remediation plan <id> |
| AI Pilot remediable | GET /tenants/me/ai-pilot/remediable | client.ai_pilot.remediable() | aether365 ai-pilot remediable |
| AI Pilot break-glass | GET /tenants/me/ai-pilot/break-glass | client.ai_pilot.break_glass() | aether365 ai-pilot break-glass |
| AI Pilot CA-policies | GET /tenants/me/ai-pilot/conditional-access | client.ai_pilot.conditional_access() | aether365 ai-pilot conditional-access |
Remediation is voor API keys alleen-lezen. Het toepassen van een plan is niet beschikbaar: de action-registry-items van een plan kunnen conditional-access-/authorization-policy-patches bevatten die een tenant uit zijn eigen directory zouden buitensluiten (AADSTS50097), dus toepassen blijft in het dashboard met een operator in de loop. AI Pilot conditional-access en break-glass zijn om dezelfde reden eveneens alleen-lezen.
Foutafhandeling en retries
Elke API-fout wordt afgebeeld op een getypeerde exception-subklasse van 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.")De client probeert 429 RATE_LIMITED en 503 SERVICE_STARTING (het opwarmen van de koude dev-database) automatisch opnieuw met exponentiële backoff en respecteert daarbij de Retry-After-header. Quotafouten zoals SCAN_PLAN_LIMIT_REACHED worden direct opgegooid - die worden niet opnieuw geprobeerd.
De CLI gebruiken in CI
aether365 scan results <id> --fail-on-findings stopt met exitcode 2 zodra er ook maar één gefaalde bevinding is, zodat een pipeline de scanresultaten als gate kan gebruiken:
bash
aether365 scan run --type compliance --watch
aether365 scan results "$SCAN_ID" --fail-on-findingsDe CLI schrijft fouten naar stderr en stopt met 1 bij elke API-fout en met 2 bij de findings-gate.