Repository navigation
🚨 If you encounter any bugs or have suggestions, please report them here.
Changes since v1.1.7
cloudexit 2.0 is a major release. It adds optional platform integration over the new API v2 while staying offline-first — every run still collects with your own credentials and writes a local report, and nothing leaves your machine unless you connect a platform. It also moves configuration out of the repository, gives the catalogue a real version and integrity story, reorganises the code into a single cloudexit package, and hardens the whole tool. Install is from a release tag; there is no PyPI.
Upgrading from 1.x: read the migration guide first —
config.pyandHOST/KEYare no longer read, and import paths changed. Thecloudexitcommand and its arguments are unchanged.
What's Changed
Platform integration — API v2 (new)
-
Push assessments to a platform, or stay fully offline. With a host and an API key configured, a run uploads the result over API v2; with neither, it runs exactly as before. The key decides the target, and a provider/scope guard rejects a sync that doesn't fit the assessment.
export CLOUDEXIT_HOST=<platform host> export CLOUDEXIT_API_KEY_FILE=~/.config/cloudexit/key cloudexit aws --profile prod --upload required
-
Upload modes.
--upload auto(default — upload when configured, otherwise offline),required(fail before collecting if nothing is configured),off(never contact the platform).--dry-runwrites the sync document without uploading. -
Safe to retry. The sync id is the idempotency key, so a repeat never stores or charges twice. Failed uploads retry with backoff (honouring
Retry-After) and, when the budget runs out, are saved to a local spool:cloudexit spool list|flush|purge, andcloudexit uploadfor air-gapped delivery. A spooled sync is bound to the key that created it and is never delivered with another key. -
cloudexit statuschecks the settings, the TLS chain, the key and the platform (/metaand/whoami) in one place. -
CI-friendly.
--strictfails the run on platform warnings;--output jsonprints one JSON object on stdout with the logs on stderr; clear exit codes (10–15) map each platform outcome. -
Keys and TLS. TLS is always verified (custom CA bundles and proxies honoured, no way to turn verification off); the key is checked locally and against the platform's own
/metabefore anything is sent, and never appears in output or logs.
Configuration (changed)
- Settings live outside the repository. Resolved in order: command-line flags,
CLOUDEXIT_*environment variables,~/.config/cloudexit/config.toml(with[default]and[profiles.<name>]), and key files. Inspect everything withcloudexit config pathandcloudexit config show(keys masked). - Prefer a key file over a key in plain text.
--api-key-file/CLOUDEXIT_API_KEY_FILE; the CLI warns if the config file or key file is readable by others.http://hosts are rejected exceptlocalhost.
Catalogue (changed)
- The dataset is versioned and self-updating. It lives in your data directory, carries a version and hash, and each run checks for a newer one via a manifest.
cloudexit catalogue status|update|import, a--catalogue <file>run flag, and air-gapped install withcloudexit catalogue import. - Risk codes in reports. Risks now show their stable codes (e.g.
AT-2,RI-1) instead of generic numbers. - Catalogue loading is hardened: a dataset containing triggers or views is refused, and an old
./datasets/data.dbis installed only on purpose withcloudexit catalogue importrather than picked up automatically.
Reports (changed)
- One self-contained report. Each run writes a single offline
index.html(no remote resources),report.pdf(the Basic Executive Summary) and, with--egress,egress.pdf. The PDF opens with a cover and a document-information page recording where the data came from (version, run id, catalogue version and hash, self-collected or a platform link), with the same provenance in the JSON report. - Legal notices for the bundled fonts and icons travel with the report.
Data landscape & egress estimation (stable)
- No longer alpha.
--egressestimates one-time egress fees from tiered list prices.--egress-names hashedreplaces each egress resource name with a salted HMAC kept on your machine, so names never leave while the same name still matches across runs.
Infrastructure-as-Code state scan (stable)
- No longer alpha.
--tfstateassesses a Terraform/OpenTofu state file with no credentials and no API calls, as introduced in 1.1.x.
Packaging & platforms (changed)
- Install from a release tag (
git clone --branch v2.0.0 … && pip install .); no PyPI.python3 main.pystill works from a checkout. - One
cloudexitpackage. The code is reorganised under a single top-level package (the genericcore/utils/mainmodules are gone), so it no longer clashes with other installed packages. - Python 3.12–3.14, tested on Linux, macOS and Windows, with the dependencies refreshed (including the Azure SDK). Upgrading in place from 1.x works, or use a fresh virtual environment.
Security & hardening
- Untrusted platform text is never parsed as console markup; report folders are created private (
0700); credential identifiers never reach reports or logs;-vvno longer logs cloud credentials; catalogue-supplied asset paths are constrained to the report folder.
⚠️ Breaking changes
config.pyand theHOST/KEYenvironment variables are no longer read. A clear message points toCLOUDEXIT_HOSTandCLOUDEXIT_API_KEY_FILE.- Python import paths changed (
core/utils→cloudexit). Thecloudexitcommand and its arguments are unchanged. - Uploading to a platform needs a new API key (assessment or account key); 1.x keys don't carry over.
Internal
- Reorganised into
cloudexit/withproviders/,platform/,catalogue/,report/andcli/areas, enforced by a package-layering test. - Vendored API v2 definition under
docs/api-v2/, with example- and vector-based tests. - CI runs on Python 3.12–3.14 across Linux/macOS/Windows, with install and 1.x-upgrade smoke tests, a dependency-pin consistency check, and a sample-report matrix rendered through the real pipeline.
Install
git clone --branch v2.0.0 https://github.com/escapecloud/cloudexit.git
cd cloudexit && python3 -m venv .venv && . .venv/bin/activate && pip install .Full documentation: https://cloudexit.escapecloud.io