From ce95d95d2ae5674a84e3721a256cde1df095036b Mon Sep 17 00:00:00 2001 From: taurusismysign Date: Mon, 22 Jun 2026 00:06:21 +0530 Subject: [PATCH] Rename installer cloudanix-guard -> cdxai Mirror the binary rebrand: the installer file, install URL (install.cloudanix.com/cdxai), install dir (~/.cdxai/bin/cdxai), tarball name (cdxai_*.tar.gz), and the CLOUDANIX_* -> CDXAI_* env knobs. The artifacts path (coding-agent-guard/) and the Cloudanix org/domain are unchanged. The legacy note now points at the old ~/.cloudanix-guard dir so migrating users get a correct cleanup hint. RELEASE-GATED: serve this only once cdxai_*.tar.gz is published to artifacts. Old install.cloudanix.com/cloudanix-guard URL will 404 after cutover unless a redirect/shim is added (flagged for decision). Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/CODEOWNERS | 2 +- .github/workflows/pages.yml | 4 +- .github/workflows/shellcheck.yml | 4 +- README.md | 30 ++++---- cloudanix-guard => cdxai | 113 ++++++++++++++++--------------- index.html | 6 +- lib/common | 14 ++-- 7 files changed, 87 insertions(+), 86 deletions(-) rename cloudanix-guard => cdxai (79%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a6546ed..321fe18 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -15,7 +15,7 @@ # Security-sensitive areas — the actual installer surface customers run, # plus the served landing page and CI. Same owner today; placeholder for # when more reviewers join. -/cloudanix-guard @taurusismysign +/cdxai @taurusismysign /lib/ @taurusismysign /index.html @taurusismysign /CNAME @taurusismysign diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index c7edcc7..13e20ba 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -1,6 +1,6 @@ # Deploy this repo's content to GitHub Pages on every push to main. # The repo root is published as-is: -# ./cloudanix-guard → install.cloudanix.com/cloudanix-guard +# ./cdxai → install.cloudanix.com/cdxai # ./lib/common → install.cloudanix.com/lib/common # ./index.html → install.cloudanix.com/ @@ -34,7 +34,7 @@ jobs: - name: Sanity-check the install scripts are executable run: | set -euo pipefail - for f in cloudanix-guard; do + for f in cdxai; do [ -x "$f" ] || { echo "$f is not executable"; exit 1; } done diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 9671617..4b6c82b 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -29,7 +29,7 @@ jobs: with: severity: warning # Scan everything that looks like a bash script. The product - # installers (cloudanix-guard, etc.) have no extension and + # installers (cdxai, etc.) have no extension and # are at the repo root; the lib lives under _lib/. scandir: '.' - additional_files: 'cloudanix-guard' + additional_files: 'cdxai' diff --git a/README.md b/README.md index 6310ae1..7d8b424 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ One-line installers for Cloudanix products. Served at **[install.cloudanix.com](https://install.cloudanix.com)**. ```bash -curl -fsSL https://install.cloudanix.com/cloudanix-guard | bash +curl -fsSL https://install.cloudanix.com/cdxai | bash ``` > **Env vars go on the `bash` side of the pipe**, not on `curl`. Vars @@ -36,28 +36,28 @@ live in their own repositories and carry their own licenses. | Product | URL | |--------------------|----------------------------------------------| -| Cloudanix Guard | `install.cloudanix.com/cloudanix-guard` | +| Cloudanix Guard | `install.cloudanix.com/cdxai` | --- ## How a customer installs Cloudanix Guard ```bash -curl -fsSL https://install.cloudanix.com/cloudanix-guard | bash +curl -fsSL https://install.cloudanix.com/cdxai | bash ``` -What that does (paraphrased from the [script itself](./cloudanix-guard)): +What that does (paraphrased from the [script itself](./cdxai)): 1. Verifies `curl` and `tar` are available and detects your OS/arch. 2. Downloads the matching release archive - (`cloudanix-guard___.tar.gz`) + its SHA256 + (`cdxai___.tar.gz`) + its SHA256 sidecar from `github.com/Cloudanix/artifacts/raw/main/coding-agent-guard/`. 3. Verifies the archive against its SHA256 — aborts on mismatch. -4. Extracts the self-contained `cloudanix-guard` binary — no Python, +4. Extracts the self-contained `cdxai` binary — no Python, no runtime to manage. 5. Installs it at the stable path - `~/.cloudanix-guard/bin/cloudanix-guard`, so upgrades replace the + `~/.cdxai/bin/cdxai`, so upgrades replace the binary in place and never invalidate paths other tools have registered (e.g. Codex's hook trust-hash). 6. Prints next-step instructions, including how to wire the guard @@ -66,12 +66,12 @@ What that does (paraphrased from the [script itself](./cloudanix-guard)): ### Pin a version ```bash -curl -fsSL https://install.cloudanix.com/cloudanix-guard \ - | CLOUDANIX_VERSION="0.1.1" bash +curl -fsSL https://install.cloudanix.com/cdxai \ + | CDXAI_VERSION="0.1.1" bash ``` The named version must exist in `Cloudanix/artifacts/coding-agent-guard/` -as `cloudanix-guard___.tar.gz` (with a matching +as `cdxai___.tar.gz` (with a matching `.sha256` sidecar) for your platform. Otherwise the installer aborts with a 404 from the artifact CDN. @@ -92,12 +92,12 @@ with a 404 from the artifact CDN. - **Strict mode + ShellCheck on CI** — `set -euo pipefail`; no unguarded `command-not-found`; no implicit word-split bugs. - **Dev-only env-var overrides are gated** behind - `CLOUDANIX_INSTALL_DEV=1`. Without that flag, the overrides - (`CLOUDANIX_LOCAL_LIB`, `CLOUDANIX_LOCAL_BINARY`, - `CLOUDANIX_LOCAL_TARBALL`, `CLOUDANIX_INSTALL_BASE`, - `CLOUDANIX_ARTIFACTS_URL`) refuse to apply — closes a phishing path + `CDXAI_INSTALL_DEV=1`. Without that flag, the overrides + (`CDXAI_LOCAL_LIB`, `CDXAI_LOCAL_BINARY`, + `CDXAI_LOCAL_TARBALL`, `CDXAI_INSTALL_BASE`, + `CDXAI_ARTIFACTS_URL`) refuse to apply — closes a phishing path where someone tricks a developer into pasting - `CLOUDANIX_LOCAL_BINARY=/tmp/evil curl … | bash`. + `CDXAI_LOCAL_BINARY=/tmp/evil curl … | bash`. Found a bug? Open an issue on this repo. For sensitive disclosures contact `security@cloudanix.com`. diff --git a/cloudanix-guard b/cdxai similarity index 79% rename from cloudanix-guard rename to cdxai index d270d1e..011a92d 100755 --- a/cloudanix-guard +++ b/cdxai @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Cloudanix Guard — one-line installer. # -# curl -fsSL https://install.cloudanix.com/cloudanix-guard | bash +# curl -fsSL https://install.cloudanix.com/cdxai | bash # # Installs the Cloudanix Guard binary — a single, self-contained # executable (no Python, no runtime to manage). The binary is published @@ -9,50 +9,50 @@ # verified locally against a SHA256 sidecar before it is installed. # # Optional env: -# CLOUDANIX_VERSION Pin a specific version, e.g. "1.0.0". +# CDXAI_VERSION Pin a specific version, e.g. "1.0.0". # Defaults to "latest" (the alias updated on # every release). -# CLOUDANIX_INSTALL_DIR Base install dir. Defaults to -# ~/.cloudanix-guard . The binary lands at -# /bin/cloudanix-guard . -# CLOUDANIX_NO_MODIFY_PATH Set to "1" to skip adding the install dir to +# CDXAI_INSTALL_DIR Base install dir. Defaults to +# ~/.cdxai . The binary lands at +# /bin/cdxai . +# CDXAI_NO_MODIFY_PATH Set to "1" to skip adding the install dir to # your shell PATH; the installer then just prints # the line to add manually. # NO_COLOR Disable colour output. # -# Dev-only overrides (require CLOUDANIX_INSTALL_DEV=1): -# CLOUDANIX_INSTALL_DEV Set to "1" to enable any of: -# CLOUDANIX_LOCAL_LIB Path to a local lib/common -# CLOUDANIX_LOCAL_BINARY Path to a prebuilt binary (skips download) -# CLOUDANIX_LOCAL_TARBALL Path to a local release tarball (skips download) -# CLOUDANIX_INSTALL_BASE Override install.cloudanix.com URL -# CLOUDANIX_ARTIFACTS_URL Override the artifacts CDN URL +# Dev-only overrides (require CDXAI_INSTALL_DEV=1): +# CDXAI_INSTALL_DEV Set to "1" to enable any of: +# CDXAI_LOCAL_LIB Path to a local lib/common +# CDXAI_LOCAL_BINARY Path to a prebuilt binary (skips download) +# CDXAI_LOCAL_TARBALL Path to a local release tarball (skips download) +# CDXAI_INSTALL_BASE Override install.cloudanix.com URL +# CDXAI_ARTIFACTS_URL Override the artifacts CDN URL # # Exit codes: # 0 success # 1 user-facing error (unsupported OS, missing tools, dev override -# used without CLOUDANIX_INSTALL_DEV=1, etc.) +# used without CDXAI_INSTALL_DEV=1, etc.) # 2 network / artifact integrity error (download failed or SHA256 # mismatch) # # This installer is open source (MIT). Audit at: -# https://github.com/Cloudanix/install-scripts/blob/main/cloudanix-guard +# https://github.com/Cloudanix/install-scripts/blob/main/cdxai set -euo pipefail # ─── dev-only override gating ─────────────────────────────────────── # # Phishing defence: a customer can be tricked into pasting -# CLOUDANIX_LOCAL_BINARY=/tmp/evil curl ... | bash -# into their terminal. Requiring CLOUDANIX_INSTALL_DEV=1 makes it +# CDXAI_LOCAL_BINARY=/tmp/evil curl ... | bash +# into their terminal. Requiring CDXAI_INSTALL_DEV=1 makes it # obvious that something dev-only is happening. -if [ -z "${CLOUDANIX_INSTALL_DEV:-}" ]; then - for _v in CLOUDANIX_LOCAL_LIB CLOUDANIX_LOCAL_BINARY CLOUDANIX_LOCAL_TARBALL CLOUDANIX_INSTALL_BASE CLOUDANIX_ARTIFACTS_URL; do +if [ -z "${CDXAI_INSTALL_DEV:-}" ]; then + for _v in CDXAI_LOCAL_LIB CDXAI_LOCAL_BINARY CDXAI_LOCAL_TARBALL CDXAI_INSTALL_BASE CDXAI_ARTIFACTS_URL; do eval _val="\${${_v}:-}" if [ -n "${_val:-}" ]; then echo "error: ${_v} is a development-only override." >&2 - echo " Set CLOUDANIX_INSTALL_DEV=1 to enable it." >&2 + echo " Set CDXAI_INSTALL_DEV=1 to enable it." >&2 exit 1 fi done @@ -60,11 +60,11 @@ fi # ─── source the shared helpers ────────────────────────────────────── -INSTALL_BASE="${CLOUDANIX_INSTALL_BASE:-https://install.cloudanix.com}" +INSTALL_BASE="${CDXAI_INSTALL_BASE:-https://install.cloudanix.com}" -if [ -n "${CLOUDANIX_LOCAL_LIB:-}" ] && [ -f "${CLOUDANIX_LOCAL_LIB}" ]; then +if [ -n "${CDXAI_LOCAL_LIB:-}" ] && [ -f "${CDXAI_LOCAL_LIB}" ]; then # shellcheck source=lib/common - source "${CLOUDANIX_LOCAL_LIB}" + source "${CDXAI_LOCAL_LIB}" else # Fetch common to a real temp file so we can: # 1. Check the HTTP fetch succeeded. @@ -96,17 +96,17 @@ cdx::init_strict # ─── product-specific config ──────────────────────────────────────── -readonly PRODUCT="cloudanix-guard" -INSTALL_DIR="${CLOUDANIX_INSTALL_DIR:-${HOME}/.cloudanix-guard}" +readonly PRODUCT="cdxai" +INSTALL_DIR="${CDXAI_INSTALL_DIR:-${HOME}/.cdxai}" readonly INSTALL_DIR readonly BIN_DIR="${INSTALL_DIR}/bin" readonly LAUNCHER_PATH="${BIN_DIR}/${PRODUCT}" # Public CDN that holds the release binaries. Override only via the -# dev-gated CLOUDANIX_ARTIFACTS_URL above. -readonly ARTIFACTS_URL="${CLOUDANIX_ARTIFACTS_URL:-https://github.com/Cloudanix/artifacts/raw/main/coding-agent-guard}" +# dev-gated CDXAI_ARTIFACTS_URL above. +readonly ARTIFACTS_URL="${CDXAI_ARTIFACTS_URL:-https://github.com/Cloudanix/artifacts/raw/main/coding-agent-guard}" -VERSION="${CLOUDANIX_VERSION:-latest}" +VERSION="${CDXAI_VERSION:-latest}" # Set by the resolve step (download+extract, or a dev-provided local # binary/tarball). Always ends up pointing at the executable to install. @@ -144,7 +144,7 @@ main() { cdx::step "Installing" install_binary "${BINARY_PATH}" "${LAUNCHER_PATH}" cdx::ok "installed: ${LAUNCHER_PATH}" - note_legacy_venv + note_legacy_install cdx::step "Configuring PATH" ensure_on_path @@ -158,20 +158,20 @@ main() { resolve_binary() { local version="$1" - if [ -n "${CLOUDANIX_LOCAL_BINARY:-}" ]; then - [ -f "${CLOUDANIX_LOCAL_BINARY}" ] \ - || cdx::die "CLOUDANIX_LOCAL_BINARY=${CLOUDANIX_LOCAL_BINARY} is not a file" - cdx::warn "using local binary (skipping download + checksum): ${CLOUDANIX_LOCAL_BINARY}" - BINARY_PATH="${CLOUDANIX_LOCAL_BINARY}" + if [ -n "${CDXAI_LOCAL_BINARY:-}" ]; then + [ -f "${CDXAI_LOCAL_BINARY}" ] \ + || cdx::die "CDXAI_LOCAL_BINARY=${CDXAI_LOCAL_BINARY} is not a file" + cdx::warn "using local binary (skipping download + checksum): ${CDXAI_LOCAL_BINARY}" + BINARY_PATH="${CDXAI_LOCAL_BINARY}" return 0 fi local tarball - if [ -n "${CLOUDANIX_LOCAL_TARBALL:-}" ]; then - [ -f "${CLOUDANIX_LOCAL_TARBALL}" ] \ - || cdx::die "CLOUDANIX_LOCAL_TARBALL=${CLOUDANIX_LOCAL_TARBALL} is not a file" - cdx::warn "using local tarball (skipping download + checksum): ${CLOUDANIX_LOCAL_TARBALL}" - tarball="${CLOUDANIX_LOCAL_TARBALL}" + if [ -n "${CDXAI_LOCAL_TARBALL:-}" ]; then + [ -f "${CDXAI_LOCAL_TARBALL}" ] \ + || cdx::die "CDXAI_LOCAL_TARBALL=${CDXAI_LOCAL_TARBALL} is not a file" + cdx::warn "using local tarball (skipping download + checksum): ${CDXAI_LOCAL_TARBALL}" + tarball="${CDXAI_LOCAL_TARBALL}" else download_tarball "${version}" # sets TARBALL_PATH tarball="${TARBALL_PATH}" @@ -195,7 +195,7 @@ _goarch() { # see the cdx::ensure_tmpdir comment on why the tmpdir trap must stay in # main()'s shell. # -# Archives are named cloudanix-guard___.tar.gz (the +# Archives are named cdxai___.tar.gz (the # goreleaser convention) with a sibling .sha256 sidecar in coreutils # format (" "). We download both and verify locally — if the # public mirror is ever tampered with and a malicious archive is pushed @@ -228,7 +228,7 @@ download_tarball() { cdx::info "fetching ${url}" curl -fsSL -o "${tmp}/${fn}" "${url}" || { cdx::err "binary download failed: ${url}" - cdx::err " (Is CLOUDANIX_VERSION=${tag} published for ${CDX_OS}/${arch}?" + cdx::err " (Is CDXAI_VERSION=${tag} published for ${CDX_OS}/${arch}?" cdx::err " Check https://github.com/Cloudanix/artifacts/tree/main/coding-agent-guard )" exit 2 } @@ -267,7 +267,7 @@ sha256_verify() { fi } -# Extract the tarball into CDX_TMPDIR and locate the cloudanix-guard +# Extract the tarball into CDX_TMPDIR and locate the cdxai # binary. Sets the global BINARY_PATH. extract_binary() { local tarball="$1" @@ -288,7 +288,7 @@ extract_binary() { # ─── install the binary at the stable launcher path ───────────────── # -# The binary lives at ~/.cloudanix-guard/bin/cloudanix-guard for the +# The binary lives at ~/.cdxai/bin/cdxai for the # life of the install. Coding agents (especially Codex, which # trust-hashes the exact path of every hook command) record THIS path, # so keeping it stable across upgrades means replacing the binary in @@ -314,8 +314,8 @@ install_binary() { # ─── PATH wiring (multi-shell) ────────────────────────────────────── # -# The binary installs to ~/.cloudanix-guard/bin, which is almost never on a -# fresh machine's PATH — so a bare `cloudanix-guard` returns "command not +# The binary installs to ~/.cdxai/bin, which is almost never on a +# fresh machine's PATH — so a bare `cdxai` returns "command not # found" even though the install succeeded (the agent hooks are unaffected: # they invoke the binary by absolute path). Append the right line, with the # right syntax, to the rc the user's shell actually reads: @@ -326,7 +326,7 @@ install_binary() { # else → ~/.profile (POSIX login fallback) export PATH=... # # Idempotent (skips if BIN_DIR is already referenced). Opt out with -# CLOUDANIX_NO_MODIFY_PATH=1; falls back to printing the line if it can't +# CDXAI_NO_MODIFY_PATH=1; falls back to printing the line if it can't # determine the shell or write the file. ensure_on_path() { # Already resolvable in this process → future shells inherit it; done. @@ -335,8 +335,8 @@ ensure_on_path() { return 0 fi - if [ -n "${CLOUDANIX_NO_MODIFY_PATH:-}" ]; then - cdx::info "CLOUDANIX_NO_MODIFY_PATH set — not editing your shell profile." + if [ -n "${CDXAI_NO_MODIFY_PATH:-}" ]; then + cdx::info "CDXAI_NO_MODIFY_PATH set — not editing your shell profile." _print_path_instructions return 0 fi @@ -368,7 +368,7 @@ ensure_on_path() { # present afterwards (added or already there), 1 if the file couldn't be written. _append_path_line() { local rc="$1" line="$2" - local marker="# added by cloudanix-guard installer" + local marker="# added by cdxai installer" mkdir -p "$(dirname "${rc}")" 2>/dev/null || true @@ -394,13 +394,14 @@ _print_path_instructions() { cdx::warn " fish: fish_add_path \"${BIN_DIR}\"" } -# Older Python installs left a venv at ~/.cloudanix-guard/venv. The Go -# binary doesn't use it; mention it but don't delete it — that's the -# user's call. -note_legacy_venv() { - local venv="${INSTALL_DIR}/venv" - if [ -d "${venv}" ]; then - cdx::info "note: a previous Python install's venv at ${venv} is no longer used (safe to delete)." +# A prior install lived at ~/.cloudanix-guard (the binary was renamed +# cloudanix-guard -> cdxai and the install dir moved to ~/.cdxai). Note any +# leftover old install dir — and the even-older Python venv inside it — but +# don't delete it; that's the user's call (re-run `cdxai configure` first). +note_legacy_install() { + local legacy="${HOME}/.cloudanix-guard" + if [ -d "${legacy}" ]; then + cdx::info "note: a previous install at ${legacy} is superseded by ${INSTALL_DIR} (safe to delete after you re-run 'cdxai configure')." fi } diff --git a/index.html b/index.html index c523f21..c7f2985 100644 --- a/index.html +++ b/index.html @@ -135,14 +135,14 @@

Cloudanix Guard

— inspects prompts and tool calls for secrets, PII, and sensitive files before they reach the LLM.

-
curl -fsSL https://install.cloudanix.com/cloudanix-guard | bash
+
curl -fsSL https://install.cloudanix.com/cdxai | bash
Options

Pin a specific version:

-
curl -fsSL https://install.cloudanix.com/cloudanix-guard \
-  | CLOUDANIX_VERSION="0.1.1" bash
+
curl -fsSL https://install.cloudanix.com/cdxai \
+  | CDXAI_VERSION="0.1.1" bash

Env vars go on the bash side of the pipe, not on diff --git a/lib/common b/lib/common index b5b4336..5506679 100644 --- a/lib/common +++ b/lib/common @@ -1,6 +1,6 @@ # shellcheck shell=bash # Cloudanix installers — shared helpers sourced by each product -# installer (./cloudanix-guard, etc.). +# installer (./cdxai, etc.). # # Provides: # - `cdx::info`, `cdx::warn`, `cdx::err`, `cdx::ok` — coloured stderr @@ -65,9 +65,9 @@ cdx::require_cmd() { } # Echo a python executable >= 3.9 found on PATH, or die. -# Honours an explicit CLOUDANIX_PYTHON if set. +# Honours an explicit CDXAI_PYTHON if set. cdx::python_bin() { - local override="${CLOUDANIX_PYTHON:-}" + local override="${CDXAI_PYTHON:-}" local candidates=() if [ -n "$override" ]; then candidates+=("$override") @@ -81,7 +81,7 @@ cdx::python_bin() { return 0 fi done - cdx::die "no Python ≥ 3.9 found on PATH. Tried: ${candidates[*]}. Set CLOUDANIX_PYTHON=/path/to/python to override." + cdx::die "no Python ≥ 3.9 found on PATH. Tried: ${candidates[*]}. Set CDXAI_PYTHON=/path/to/python to override." } # Internal: returns 0 iff $1 is python ≥ 3.9. @@ -121,11 +121,11 @@ cdx::is_interactive() { } # Y/n prompt with default Y. -# In non-interactive contexts, auto-answers yes UNLESS CLOUDANIX_ASSUME_NO=1. +# In non-interactive contexts, auto-answers yes UNLESS CDXAI_ASSUME_NO=1. cdx::confirm() { local prompt="$1" if ! cdx::is_interactive; then - if [ "${CLOUDANIX_ASSUME_NO:-}" = "1" ]; then + if [ "${CDXAI_ASSUME_NO:-}" = "1" ]; then return 1 fi return 0 @@ -166,7 +166,7 @@ cdx::ensure_tmpdir() { # ─── required env var helper ─────────────────────────────────────── # Read a required env var; if missing/empty, print a helpful error and die. -# Usage: token=$(cdx::resolve_token CLOUDANIX_INSTALL_TOKEN "Get one at https://console.cloudanix.com/install-token") +# Usage: token=$(cdx::resolve_token CDXAI_INSTALL_TOKEN "Get one at https://console.cloudanix.com/install-token") cdx::resolve_token() { local varname="$1" local where="${2:-}"