Self-Install auspex on Linux
Last updated: September 3, 2026
This guide is for individual engineers installing the Span agent (auspex) on their own Linux machine, without an MDM. It installs entirely in your user account — no root, no sudo, and no install script required.
⚠️ Beta. Linux support is a beta release. The install flow and this guide work end-to-end, but the Linux path is newer and less battle-tested than macOS and Windows — expect the occasional rough edge, and please report anything unexpected to the Span team.
This is the self-service path for Linux. There is no managed (MDM) Linux install today, so on Linux this download-and-run flow is how auspex runs — on a personal or self-managed host you install it yourself, as below.
It targets Ubuntu 24.04 (the validated laptop distro), amd64 and arm64. To run auspex inside a container instead — including on Amazon Linux 2023 — see the container install guide.
Before you start
- A Linux machine running Ubuntu 24.04 (amd64 or arm64), with
systemd— the default on Ubuntu - Your Span auth token (provided by your Span administrator)
- NOTE: this needs to be the global org auth token, not a PAT
- Your work email
No root access is needed — everything installs under your home directory (~/.auspex), with a launcher symlinked into ~/.local/bin (already on your PATH on a default Ubuntu shell). In fact the installer refuses to run as root: a per-user install from sudo would place files your own account can't manage.
Which build do I need — amd64 or arm64?
Almost certainly amd64 (every Intel/AMD machine). Pick arm64 only on an Arm host — an Arm server (AWS Graviton and similar) or an Arm laptop / VM. The download command below detects this for you with uname -m, so you don't have to choose.
Step 1: Download the agent
Open a terminal. Pick any folder to work in — we'll call it <WORKDIR> (e.g. ~/Downloads). This command detects your machine's architecture and downloads the matching archive:
cd <WORKDIR>
ARCH=$(uname -m); [ "$ARCH" = "aarch64" ] && ARCH=arm64; [ "$ARCH" = "x86_64" ] && ARCH=amd64
curl -fLO "https://auspex.span.app/releases/latest/linux/archive/auspex_linux_${ARCH}.tar.gz"
Step 2: Install
Unpack the archive, then install. So your token never lands in your shell history or the process list (ps), paste it into an environment variable with a silent prompt — nothing is echoed as you paste — and let the installer read it from there. Replace <EMAIL> with your work email:
tar -xzf "auspex_linux_${ARCH}.tar.gz"
printf 'Paste your Span token, then press Enter: '; read -rs AUSPEX_CLOUD_TOKEN; echo; export AUSPEX_CLOUD_TOKEN
./auspex install --service --email <EMAIL>
install reads the token from AUSPEX_CLOUD_TOKEN, writes it to a private (0600) identity file only you can read, and the daemon reads it from that file thereafter — not from your shell environment.
Other ways to supply the token.
- From a file (e.g. exported by a secrets manager) — the secret stays out of the process list:
./auspex install --service --token-file ~/span-token.txt --email <EMAIL>(auspex trims the file, and tolerates a UTF-16/BOM-encoded one).- Inline —
./auspex install --service --token <TOKEN> --email <EMAIL>also works, but is discouraged: the token is then visible in your shell history and tops. auspex prefers--token-fileorAUSPEX_CLOUD_TOKENfor exactly this reason.
What this does, all within your user account (no sudo):
- places the
auspexbinary under~/.auspex/binand symlinks a launcher into~/.local/bin, - wires the capture hooks into your AI coding tools (Claude Code, Cursor, Codex, GitHub Copilot, VS Code),
- saves your token and work email to a private (0600) identity file only you can read,
- registers a per-user
systemd --userservice (--service) so the daemon starts now and at every login.
✅ Done when the installer prints auspex installed: with your binary path, status: capture live ✓, and identity: user tier provisioned. If it warns that ~/.local/bin isn't on your PATH, either follow the printed hint or open a new terminal before the next step.
Headless or SSH-only host? A per-user
systemdservice starts at login, which a machine you only reach over SSH may never have. See Headless / SSH-only hosts below before or after installing.
Step 3: Verify
auspex status
auspex auth show
auspex statusshould reportauspex daemon: okand, on the line above,auspex: install mode: user.auspex auth showshould show your work email and a masked token (never the token in clear text).
Then use Claude Code or Cursor briefly and confirm your traces appear in the Span dashboard (ask your Span rep to enable the feature for your org if you don't see anything yet).
Headless / SSH-only hosts
--service registers a per-user systemd service that runs inside your user's systemd manager. On a normal desktop or laptop where you log in interactively, that manager is always running and there's nothing more to do. On a headless or SSH-only host there may be no persistent login session, so between logins the user manager isn't running — the service would stop when you disconnect and wouldn't start on boot.
The systemd-native fix is to enable lingering for your user once — the single step here that needs sudo:
sudo loginctl enable-linger $USER
Lingering keeps your user's systemd manager running without an interactive login, so the auspex service starts at boot and survives logout. auspex does not enable lingering for you — whether a user may linger is a host policy choice, so you make it explicitly. If you enable it after installing, re-apply the service with:
systemctl --user restart app.span.auspex
If auspex install --service (or any systemctl --user …) reports it can't reach your user systemd manager in a bare SSH session, point it at your runtime directory first, then re-run:
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
No systemd, or you'd rather not use it? Use the supervised posture instead — auspex install --supervised plus a long-running auspex daemon --supervise (kept alive by tmux/screen or your own process manager). This is the same posture the container install guide documents; see it for the full recipe.
Step 4: Clean up (optional)
Once the health check passes, the downloaded archive is no longer needed — the installer placed its own copy under ~/.auspex/bin (from <WORKDIR>):
rm <WORKDIR>/auspex_linux_*.tar.gz
(Optional) Pin and verify an exact build
The download in Step 1 uses the version-less latest alias — the simplest path. If you'd like a reproducible, tamper-evident install (recommended for security-conscious setups), you can pin an exact release and verify its bytes against auspex's cryptographic signature before installing.
Each release publishes a cosign-signed manifest.json that binds the version to the exact SHA-256 of every artifact, and every artifact is also stored at a global, content-addressed path (https://auspex.span.app/blobs/sha256/<digest>) — so a digest is a version-free pin that always resolves to the same bytes. This needs two small tools: jq (sudo apt-get install -y jq) and cosign on your PATH.
cd <WORKDIR>
V=v0.2.0 # the exact release you want (ask your admin or see the changelog)
ARCH=$(uname -m); [ "$ARCH" = "aarch64" ] && ARCH=arm64; [ "$ARCH" = "x86_64" ] && ARCH=amd64
# 1. Fetch the signed version→digest manifest and verify it came from auspex's release pipeline:
curl -fsSLO "https://auspex.span.app/releases/${V}/manifest.json"
curl -fsSLO "https://auspex.span.app/releases/${V}/manifest.json.cosign.bundle"
cosign verify-blob \
--bundle manifest.json.cosign.bundle \
--certificate-identity-regexp '^https://github\.com/(?i:attuned-corp)/auspex/\.github/workflows/release\.yml@refs/tags/v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
manifest.json
# 2. Confirm the manifest is for the version you asked for, then read the Linux archive's signed digest:
test "$(jq -r '.annotations["org.opencontainers.image.version"]' manifest.json)" = "$V"
DIGEST=$(jq -r --arg arch "$ARCH" \
'.manifests[] | select(.mediaType=="application/gzip" and .platform.os=="linux" and .platform.architecture==$arch) | .digest' manifest.json)
# 3. Fetch the archive BY DIGEST (version-free) and confirm its bytes match the signed digest:
D=${DIGEST#sha256:}
curl -fL -o "auspex_linux_${ARCH}.tar.gz" "https://auspex.span.app/blobs/sha256/${D}"
echo "${D} auspex_linux_${ARCH}.tar.gz" | sha256sum -c -
If the final check prints auspex_linux_${ARCH}.tar.gz: OK, the archive is verified — continue from Step 2 (tar -xzf …). A failed cosign verify-blob or a checksum mismatch means do not install — contact the Span team.
The
sha256:<digest>you verified once is a durable pin:https://auspex.span.app/blobs/sha256/<digest>returns those exact bytes regardless of version, so you can record it in a setup script or lockfile.
Verify anytime
auspex status
Uninstall
auspex uninstall
This removes the agent, its systemd --user service, and the hooks auspex wrote. Your own custom hooks in Cursor and Claude Code are preserved, and your config and captured data under ~/.auspex are kept. To remove those too:
rm -rf ~/.auspex
Troubleshooting
auspex: command not found—~/.local/binisn't on yourPATHyet. Open a new terminal, or run it by full path:~/.auspex/bin/auspex status.refusing to run as root— you ran the installer withsudo. Run it as your normal user; auspex installs per-user by design.provisioning was requested but no token was supplied, or no token after install —AUSPEX_CLOUD_TOKENwasn't set in the shell that raninstall(a new terminal doesn't inherit it). Re-run the silent-prompt line andinstallin the same shell, or pass--token-file <path>. Confirm withauspex auth show.- Service isn't running after you log out / reboot (headless host) — your user's
systemdmanager only runs during a login session. Enable lingering once:sudo loginctl enable-linger $USER(see Headless / SSH-only hosts). Failed to connect to bus/systemctl --usererrors in an SSH session — setexport XDG_RUNTIME_DIR="/run/user/$(id -u)"and re-run, and enable lingering as above if it's a headless host.- No traces in the dashboard — expected on a fresh install until you've used a coding tool and your org has the feature enabled. Use Claude Code or Cursor briefly, then re-check
auspex status. If it persists, contact the Span team.
If you are stuck on an issue not listed here, please share the full terminal output (and the output of auspex status) with the Span team.