# 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/.salt}"
# Check and exit if already installed
[ -x "$DIR/salt" ] && { echo "Salt CLI already installed in $DIR" >&2; exit 0; }
ZIP="$(mktemp)"
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 (Java is required for Salt)
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 ~/.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\.salt, or pass -Dir)
param([string]$Dir = "$Home\.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()
try {
    # Download Salt CLI and checksum
    Invoke-WebRequest -URI $DownloadUrl -OutFile $zip -UseBasicParsing
    $r = (Invoke-WebRequest -URI $ChecksumUrl -UseBasicParsing)
    $expect = if ($r.Content -is [byte[]]) { [System.Text.Encoding]::UTF8.GetString($r.Content).Trim() } else { $r.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 $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
$r = (Invoke-WebRequest https://raw.githubusercontent.com/xygeni/xygeni/main/checksum/latest/get-salt.ps1.sha256 -UseBasicParsing)
$h = if ($r.Content -is [byte[]]) { [System.Text.Encoding]::UTF8.GetString($r.Content).Trim() } else { $r.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\.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/.salt/salt" "$HOME/.local/bin/salt"
```

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

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

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

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

{% endtab %}

{% tab title="Windows" %}

```powershell
setx PATH "%PATH%;$Home\.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/.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 ](/xygeni-products/build-security/salt-command-line-reference.md#salt-authentication)and [Salt Command-Line Reference ](/xygeni-products/build-security/salt-command-line-reference.md)for further information.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.xygeni.io/xygeni-products/build-security/installing-salt-cli.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
