Skip to content

v2.0.0

Latest

Choose a tag to compare

@bencehezso bencehezso released this 25 Oct 17:21
· 8 commits to main since this release

🚨 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.py and HOST/KEY are no longer read, and import paths changed. The cloudexit command 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-run writes 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, and cloudexit upload for air-gapped delivery. A spooled sync is bound to the key that created it and is never delivered with another key.

  • cloudexit status checks the settings, the TLS chain, the key and the platform (/meta and /whoami) in one place.

  • CI-friendly. --strict fails the run on platform warnings; --output json prints 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 /meta before 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 with cloudexit config path and cloudexit 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 except localhost.

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 with cloudexit 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.db is installed only on purpose with cloudexit catalogue import rather 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. --egress estimates one-time egress fees from tiered list prices. --egress-names hashed replaces 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. --tfstate assesses 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.py still works from a checkout.
  • One cloudexit package. The code is reorganised under a single top-level package (the generic core/utils/main modules 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; -vv no longer logs cloud credentials; catalogue-supplied asset paths are constrained to the report folder.

⚠️ Breaking changes

  • config.py and the HOST / KEY environment variables are no longer read. A clear message points to CLOUDEXIT_HOST and CLOUDEXIT_API_KEY_FILE.
  • Python import paths changed (core/utils → cloudexit). The cloudexit command 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/ with providers/, platform/, catalogue/, report/ and cli/ 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