# Installing Salt CLI

For generating attestations in CI/CD pipelines, you may run download and run the Salt CLI.

Xygeni offers custom tasks that simplify installation on certain CI/CD platforms. For Azure DevOps, you can use [Xygeni Build Attestation](https://marketplace.visualstudio.com/items?itemName=xygeni-security.xygeni-salt) to generate SLSA provenance attestations and [Xygeni Attestation Verifier](https://marketplace.visualstudio.com/items?itemName=xygeni-security.xygeni-attestation-verifier) to verify software attestations.

## Install Salt CLI

Xygeni provides bootstrap scripts (`get-salt.sh` for mac/Linux, `get-salt.ps1` for Windows) that download the Salt CLI, verify its SHA-256 checksum, and install it in a single step.

{% tabs %}
{% tab title="mac/Linux" %}
**1. Download the bootstrap script**

```bash
curl -sSfLO https://get.xygeni.io/latest/salt/get-salt.sh
```

**2. Review the script**

The script downloads the Salt CLI, verifies its SHA-256 checksum (from a separate source on GitHub), and installs it. You can review its contents — it is intentionally kept short:

```shell
set -e
# Download helper: uses curl if available, falls back to wget
fetch() { curl -sSfL "$1" 2>/dev/null || wget -qO- "$1"; }
DIR="${1:-$HOME/.xygeni_salt}"
# Check and exit if already installed
[ -x "$DIR/salt" ] && { echo "Salt CLI already installed in $DIR" >&2; exit 0; }
ZIP="$(mktemp).zip"
trap 'rm -f "$ZIP"' EXIT
# Download Salt CLI and checksum
fetch https://get.xygeni.io/latest/salt/salt.zip > "$ZIP"
EXPECT=$(fetch https://raw.githubusercontent.com/xygeni/xygeni/main/checksum/latest/salt.zip.sha256)
ACTUAL=$(sha256sum "$ZIP" 2>/dev/null || shasum -a 256 "$ZIP")
ACTUAL=$(echo "$ACTUAL" | awk '{print $1}')
# Verify checksum
[ "$EXPECT" = "$ACTUAL" ] || { echo "Checksum mismatch: expected $EXPECT, got $ACTUAL" >&2; exit 1; }
# Extract Salt CLI: uses unzip if available, falls back to jar
mkdir -p "$DIR"
unzip -qo "$ZIP" -d "$DIR" 2>/dev/null || (cd "$DIR" && jar xf "$ZIP")
mv "$DIR/xygeni_salt"/* "$DIR/" && rmdir "$DIR/xygeni_salt"  # flatten nested dir
echo "Salt CLI installed in $DIR"
```

**3. Verify the script checksum**

```bash
h=$(curl -s https://raw.githubusercontent.com/xygeni/xygeni/main/checksum/latest/get-salt.sh.sha256)
echo "$h get-salt.sh" | sha256sum -c
```

{% hint style="warning" %}
On macOS, `sha256sum` may not be available. Replace `sha256sum -c` with `shasum -a 256 -c` in the command above.
{% endhint %}

If the checksum matches, you will see:

```
get-salt.sh: OK
```

If it does not match, you will see:

```
get-salt.sh: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
```

{% hint style="danger" %}
If the checksum verification fails, do not run the script. Delete the downloaded file and try downloading it again. If the problem persists, contact [Xygeni support](https://xygeni.io/contact).
{% endhint %}

**4. Run the script**

```bash
# Default installs to ~/.xygeni_salt, or pass a custom directory
sh get-salt.sh [install_dir]
```

{% endtab %}

{% tab title="Windows" %}
**1. Download the bootstrap script**

```powershell
Invoke-WebRequest https://get.xygeni.io/latest/salt/get-salt.ps1 -OutFile get-salt.ps1
```

**2. Review the script**

The script downloads the Salt CLI, verifies its SHA-256 checksum (from a separate source on GitHub), and installs it. You can review its contents:

```powershell
# Installation directory (default: $Home\.xygeni_salt, or pass -Dir)
param([string]$Dir = "$Home\.xygeni_salt")
$DownloadUrl = 'https://get.xygeni.io/latest/salt/salt.zip'
$ChecksumUrl = 'https://raw.githubusercontent.com/xygeni/xygeni/main/checksum/latest/salt.zip.sha256'
$ErrorActionPreference = 'Stop'
# Check and exit if already installed
if (Test-Path (Join-Path $Dir 'salt.ps1')) { Write-Host "Salt CLI already installed in $Dir"; exit 0 }

$zip = [System.IO.Path]::GetTempFileName() + '.zip'
try {
    # Download Salt CLI and checksum
    Invoke-WebRequest -URI $DownloadUrl -OutFile $zip -UseBasicParsing
    $expect = (Invoke-WebRequest -URI $ChecksumUrl -UseBasicParsing).Content.Trim()
    # Verify SHA256 checksum
    $actual = (Get-FileHash -Path $zip -Algorithm SHA256).Hash.ToLower()
    if ($expect -ne $actual) { throw "Checksum mismatch: expected $expect, got $actual" }
    # Unzip Salt CLI
    New-Item -ItemType Directory -Force -Path $Dir | Out-Null
    Expand-Archive -Force $zip -DestinationPath $Dir
    Move-Item -Force (Join-Path (Join-Path $Dir 'xygeni_salt') '*') $Dir  # flatten nested dir
    Remove-Item (Join-Path $Dir 'xygeni_salt')
    Write-Host "Salt CLI installed in $Dir"
} finally { Remove-Item -Force -ErrorAction SilentlyContinue $zip }
```

**3. Verify the script checksum**

```powershell
$h = (Invoke-WebRequest https://raw.githubusercontent.com/xygeni/xygeni/main/checksum/latest/get-salt.ps1.sha256 -UseBasicParsing).Content.Trim()
(Get-FileHash .\get-salt.ps1 -Algorithm SHA256).Hash -eq $h
```

If the checksum matches, the command returns:

```
True
```

If it does not match, the command returns:

```
False
```

{% hint style="danger" %}
If the checksum verification fails (`False`), do not run the script. Delete the downloaded file and try downloading it again. If the problem persists, contact [Xygeni support](https://xygeni.io/contact).
{% endhint %}

**4. Run the script**

```powershell
# Default installs to $Home\.xygeni_salt, or pass -Dir
.\get-salt.ps1 [-Dir C:\path\to\install]
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The script fetches the checksum from GitHub (`raw.githubusercontent.com/xygeni/xygeni`) while the Salt CLI zip is downloaded from `get.xygeni.io` — an attacker would need to compromise both sites to bypass the integrity check.
{% endhint %}

### (Recommended) Add Salt to your path

{% hint style="info" %}
This step is optional but highly recommended to facilitate running Salt commands.
{% endhint %}

{% tabs %}
{% tab title="mac/Linux" %}
**Option 1 — Symlink in `~/.local/bin`** (recommended, if `~/.local/bin` is already in PATH):

```bash
ln -s "$HOME/.xygeni_salt/salt" "$HOME/.local/bin/salt"
```

**Option 2 — Shell alias** in `~/.bashrc` or `~/.zshrc`:

```bash
echo 'alias salt="$HOME/.xygeni_salt/salt"' >> ~/.bashrc
source ~/.bashrc
```

**Option 3 — Add to PATH** (fallback):

```bash
echo 'export PATH="$PATH:$HOME/.xygeni_salt"' >> ~/.bashrc
source ~/.bashrc
```

{% endtab %}

{% tab title="Windows" %}

```powershell
setx PATH "%PATH%;$Home\.xygeni_salt"
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
You may add `--no-banner` (or `-nb`) to the alias to hide the SALT banner, so logfiles are leaner: `alias salt='$HOME/.xygeni_salt/salt -nb'`
{% endhint %}

### Execute Salt

Once installed, you can execute salt.

Please note that **you need to provide a Xygeni Token to salt to make it work**.

{% hint style="info" %}
Please see [Salt Authentication ](https://docs.xygeni.io/xygeni-products/salt-command-line-reference#salt-authentication)and [Salt Command-Line Reference ](https://docs.xygeni.io/xygeni-products/build-security/salt-command-line-reference)for further information.
{% endhint %}
