The Safeguard local runner is the part of the Safeguard CLI that does the platform's work on your own machine. Sign in once and it polls for scan jobs and assistant turns, runs them where your code lives, and uploads only the SBOM and findings. Commands and file edits wait for your approval.
This guide takes you from a fresh install to a runner that stays reachable while you are away from the desk. By the end you will have:
- The Safeguard CLI installed, verified and signed in on a Mac, Linux box or Windows PC.
- A runner that picks up scan jobs routed to it from the platform, with nothing listening on a network port.
- A headless runner that starts at login, so your phone or the desktop app can send it work from any network.
- A clear permission mode for each machine, and a short list of commands for when something goes wrong.
You also keep the AI you already use. Bring the Claude, ChatGPT or Codex plan you already pay for and use it inside the Safeguard CLI. Safeguard adds no extra charge for that usage; your plan's own usage limits and terms still apply. If you prefer to stay in the Claude or ChatGPT chat, you can connect either one to the Safeguard MCP server and use Safeguard from there.
What the local runner is and when to use it
The runner is not a separate product. The Safeguard docs put it plainly: it is built into the safeguard CLI. When you open the interactive terminal and sign in, the machine starts polling the platform for work assigned to it. When you run it headless, it does the same job without the terminal UI.
The docs list three situations where it fits:
- Your repository is private and you cannot, or will not, give a cloud service OAuth access to it.
- You work on a restricted network where only outbound HTTPS is allowed.
- You want the assistant to fix vulnerabilities in code you have not pushed yet.
How it works
- The runner sends a heartbeat and polls the platform for jobs assigned to this machine. All traffic is outbound HTTPS that the runner opens. Nothing connects to it.
- It runs each claimed job with its own local scan server.
- It uploads the result files (the SBOM and findings) and reports the job status. Source code stays on the machine.
One detail worth knowing if your build includes source analysis: the runner scan-jobs help says quoted source lines are removed from those findings before upload, and they are only sent if you set SAFEGUARD_UPLOAD_CODE_SNIPPETS=true. Leave that variable unset unless your team has decided otherwise.
The ways to run it
The same binary gives you several entry points. Pick by what the machine is for.
| How you start it | What it serves | Stops when | Good for |
|---|---|---|---|
safeguard then /login | Scan jobs, plus your own chat in the terminal | You quit the terminal or /logout | Your laptop while you work |
safeguard runner | The same interactive terminal | You quit | Same as above, if you prefer the explicit name |
safeguard runner start --workspace <folder> | Assistant turns sent to this machine, in that folder | safeguard runner stop, or the parent process exits when you use --exit-with-parent | A shell session or a script |
safeguard runner install | runner start as a per user login service | safeguard runner uninstall | A machine you want to reach from your phone or desktop app |
safeguard runner scan-jobs | The platform's repository, image, directory and SBOM scans, headless | Ctrl+C or SIGTERM | A build box or a server that only scans |
One limit from the help text: only one headless machine runner may run per OS user. Terminal sessions you open yourself stay independent of it.
Set up the runner step by step
The walkthrough below uses a Mac or Linux shell. Windows differences follow the steps. The macOS install guide goes deeper on Mac specifics.
-
Install the CLI. The runner ships inside it, so there is nothing else to download.
curl -fsSL https://cli.safeguard.sh/install | bashThe installer detects your OS and architecture, downloads the release, checks it against the published
checksums.txtand puts a single static binary on your PATH. On macOS and Linux it aborts if the checksum file is missing. It tries/usr/local/binfirst and falls back to~/.local/bin. There is no Homebrew formula, winget package or container image for the runner, per the runner docs. -
Confirm the version.
safeguard --version which -a safeguardIf
which -ashows more than one copy, the first on your PATH wins. An old build in~/go/binis the usual culprit. -
Open the terminal in your project folder and sign in.
cd ~/code/payments-api safeguardType
/login. Your browser opens, you approve the session, and the runner starts polling. The first run also downloads the scanner tools and the vulnerability database, so give it a minute. -
Check the runner state. Type
/status. The docs describe it as showing the user, tenant, runner, uptime, job counts and approval mode. The bar above the input also shows whether the runner is idle and polling or running a scan. -
Run your first scan. Type
/scan .. The CLI builds an SBOM on your machine, checks the packages, and uploads only the results to your project on the web./jobsshows recent scan history. -
Ask for something. Type a request in plain words, such as
fix the lodash CVE in this repo. The assistant reads the finding, the files and the advisory, then asks before it runs a command or edits a file.
The recorded session below shows steps 1 to 6 on a real Mac with a sample project called payments-api.
Click through it at your own pace, or open it full screen.
In the recording, the assistant asks before each command (press y or n), edits package.json to lodash 4.17.21, runs npm install and npm test with approval, and prints a summary with a suggested commit message. It pushes nothing. The session ends with /permissions, /model and /scan ..
Windows differences
Install from PowerShell:
irm https://cli.safeguard.sh/install.ps1 | iex
The Windows installer puts the binary in %LOCALAPPDATA%\Safeguard\bin and adds that folder to your user PATH, so open a new PowerShell window before you type safeguard. Windows builds are x86_64 only; on an ARM laptop the x86_64 binary runs under emulation. Use Get-Command safeguard -All in place of which -a. The Windows install guide covers this in more detail.
Machines with no browser
On a server or a VM you reach over SSH, the browser cannot open. Use the device code flow:
safeguard login --no-browser
The CLI prints a URL and a code. Open the URL on your laptop or phone, enter the code, and the server is signed in. The token stays on the machine that signed in, and the CLI does not read an API key from the environment for this.
Connecting from the web app instead
If you start from the Safeguard web app, the runner card walks you through the same thing in the browser: pick the machine's platform, run the start command it gives you, then approve the runner with the short verification code it prints. The "Try it yourself" demo at the end of this guide clicks through that route.
Run it headless and keep it running
An interactive terminal is fine while you are at the keyboard. For a machine you want to reach later, run the runner without the UI.
Start, check and stop
# Serve assistant turns for this folder, without the terminal UI
safeguard runner start --workspace ~/code/payments-api
# Is it running, and what is it doing
safeguard runner status
safeguard runner status --json
# Drain in-flight work and stop
safeguard runner stop --workspace ~/code/payments-api
--workspace sets the default folder for turns that do not name one. Add --verbose while you are setting up so each turn prints its steps.
Make it start at login
safeguard login
safeguard runner install --workspace ~/code/payments-api
runner install registers safeguard runner start as a per user login service so your phone or browser can send turns to this machine from any network for as long as it is on. On Linux it is a systemd user unit, on macOS a LaunchAgent, and on Windows a scheduled task that runs at logon. Nothing listens on a port. Undo it with safeguard runner uninstall.
Each of those service types runs as your user, so plan for when your user is logged in:
- macOS. Apple's launchd documentation says a user agent is specific to a logged in user and runs only while that user is logged in. A Mac sitting at the login window will not serve turns.
- Linux servers. A systemd user unit runs under your user's service manager. The
loginctlmanual says that with lingering enabled, a user manager is spawned for the user at boot and kept around after logouts, which lets users who are not logged in run long running services. On a headless box, runloginctl enable-linger "$USER"once. - Windows. A logon task starts when you sign in to Windows.
Only scan jobs, no assistant
For a build machine that should only take the platform's scans:
safeguard login
safeguard runner scan-jobs
It takes repository, image, directory and SBOM scans the platform routes to this machine, runs them there, and uploads only the results. Each event prints as a line. Stop it with Ctrl+C or SIGTERM.
Polling on strict networks
runner start long polls by default: the server may hold each poll for up to 25 seconds and answers the moment a turn arrives. Some proxies drop held connections. On those networks:
export SAFEGUARD_POLL_INTERVAL=10
safeguard runner start --poll-wait 0 --workspace ~/code/payments-api
With --poll-wait 0 every poll answers at once and the runner asks again every SAFEGUARD_POLL_INTERVAL seconds (10 by default). If your network needs a proxy, set HTTPS_PROXY and HTTP_PROXY before you start it, and allow outbound HTTPS on port 443.
Choose a permission mode for the headless runner
runner start and runner install take --permission-mode (short form -a) with one of supervised, edits, plan, guarded, strict or autonomous. The runner docs describe the range as running from supervised to autonomous, meaning how much the assistant may do without asking.
A practical rule: start the headless runner with the most careful mode that still lets the work finish, because you will usually approve from a phone. autonomous outside a sandbox runner needs --dangerously-skip-permissions (its alias is --yolo). Keep that for throwaway sandboxes only, never for a machine that holds real code or credentials.
Send work to the runner from your desktop or phone
Once a runner is up, your CLI session is live. It shows in the web app, the desktop app and the phone app, and those devices can send work to it.
From the desktop or phone app:
- Start a chat and choose to work on your computer.
- Pick the computer from the list of machines running the Safeguard CLI, then browse to the folder and choose it.
- Type the task in plain words. The work runs on the computer, not on the phone.
- Approve each command and file edit as it comes up. On the phone you get Allow once, Allow for turn or Deny. In the desktop app you get Approve or Deny.
The recording below is a real session in the Android app working with the same Mac and project as the CLI demo above.
Click through it at your own pace, or open it full screen.
The same conversations appear on the phone. Work on my computer picks a computer running the CLI and a folder, the command waits for Allow once, Allow for turn or Deny, and the answer shows the tests passed. The Android guide covers the phone side in full.
Pass links and notes between devices
The CLI can also send and receive small items with your other signed in devices:
# Which devices can send and receive
safeguard devices
# Send a link or a note to one of them
safeguard send --to "Pixel" --link https://app.safeguard.sh
safeguard send --to "Pixel" --text "payments-api fix is ready for review"
# What your other devices sent here
safeguard inbox
safeguard inbox open <id> --browser
--to takes a device name, a unique name prefix or an id from safeguard devices. Text can be up to 8,000 characters, and --stdin reads it from a pipe.
Do the work properly with the Safeguard CLI
The runner is the plumbing. The CLI is where you get work done, and it does more than scan.
Install
One command on macOS and Linux, curl -fsSL https://cli.safeguard.sh/install | bash, and one on Windows, irm https://cli.safeguard.sh/install.ps1 | iex. It is a single static binary with no Node, Python or JVM to install, for macOS, Linux and Windows on x86_64 or arm64 (Windows is x86_64 only). Keep it current with safeguard self-update, which verifies a signed release manifest before it replaces anything. safeguard update is a different command: it refreshes the vulnerability databases, not the binary.
Your first session
Run safeguard with no arguments to open the interactive terminal. /login signs in through the browser, /scan . scans the current folder, and you can ask in plain language, such as "how many critical vulns do we have". Type @ to attach a file from the folder you started in, /model to show or switch the AI model, and /resume to pick up the last session in that folder.
Writing and fixing code
The CLI writes code, not only scans it. The assistant has tools for your local files and for your Safeguard data, and it picks whichever the question needs. It can read files, edit code and run commands, with your approval. That makes it a general terminal assistant for your machine as well as a security one: "fix the lodash CVE in this repo", "add a test for the refund handler", "what's the latest file in ~/Downloads". Because it knows your findings, a fix starts from the actual vulnerability and ends with your tests running.
For dependency work from the shell, safeguard scan --dir . builds an SBOM and matches it against vulnerability databases, writing JSON files such as vuln.json and license.json under ./output. safeguard scan --image <name>, --repo <url> and --sbom <file> cover images, repositories and existing SBOMs. safeguard validate checks CycloneDX, SPDX and VEX documents, and safeguard review reviews your working tree changes for correctness and security before you commit.
Using your Claude or ChatGPT plan
You do not have to give up the assistant plan you already have. Connect a model with /model, and see the CLI docs for the current options. If you would rather work from the Claude or ChatGPT chat, connect it to the Safeguard MCP server; the Claude connection guide shows how.
Approvals
/permissions sets how much the assistant may do on its own:
- Ask: reads run; edits and commands ask first.
- Accept edits: edits in this folder and read only commands run; other commands ask.
- Plan: read and plan only.
- Auto: read only commands and what the policy allows run; anything else asks. This is the default.
- Strict: pre-approved actions only, for CI.
There is also a --yolo flag that approves everything. Use it only in a throwaway sandbox. If an edit goes wrong, safeguard checkpoints list --session <id> shows the snapshots taken before each file change, and safeguard checkpoints restore <checkpoint> --session <id> --dry-run previews a rollback as a diff. These are the same checkpoints /rewind uses.
CI with safeguard exec
safeguard exec "summarise the critical findings in this repository" runs one non-interactive assistant turn and exits. It defaults to strict permissions, so nothing is asked and anything the policy file has not pre-approved is denied. It refuses to run outside a git repository, because there would be no way to undo what it changes. Policies and gates are evaluated in the platform, not by the CLI. The CI guide has full pipeline examples.
Troubleshooting and common mistakes
Start every investigation with one command:
safeguard doctor
It checks the environment, sign in, tools and policy, and changes nothing. Its exit code is 0 whenever the checks ran, so read the lines, not the status. The log lives at ~/.sg/logs/safeguard.log.
Problems and fixes
- "Not authenticated" or HTTP 401. Run
safeguard whoamito see the identity and token expiry. Thensafeguard logoutandsafeguard login --force. - The browser sign in never finishes. Use
safeguard login --no-browserand enter the code on another device. - "Connection refused" or "Network error". Test with
curl -I https://api.safeguard.sh/auth. Behind a firewall, setHTTP_PROXYandHTTPS_PROXY, and allow outbound HTTPS on 443. - Certificate or SSL handshake errors. Point the CLI at your corporate CA with
export SSL_CERT_FILE=/path/to/corporate-ca.crt, or add it to the system trust store. Do not turn off certificate checks. - The runner shows online but never picks up turns. Your proxy may be dropping held connections. Restart with
--poll-wait 0. - "syft binary not found" on a new machine. The CLI downloads its scanner toolchain on first use. Run
safeguardonce interactively and let setup finish, thensafeguard update. - "No dependencies found" or an incomplete SBOM. Check that a manifest and lock file exist, run
npm install,pip install -r requirements.txtorgo mod downloadfirst, and confirm the folder withpwd. - "Command not found: safeguard". Open a new shell. On Windows the installer updated your user PATH, which shells already open will not see.
Common mistakes
- Pointing the runner at your home folder. Set
--workspaceto the project, not~. The narrower the folder, the less the assistant can touch. - Expecting a Mac at the login window to answer. A LaunchAgent runs only while you are logged in.
- Forgetting lingering on Linux servers. Without
loginctl enable-linger, the user service may not be running when nobody is logged in. - Running two headless runners as the same user. Only one is allowed per OS user. Use separate workspaces in your requests instead.
- Using
--yoloon a real machine. It approves everything. It belongs in a disposable sandbox. - Mixing up
updateandself-update. One refreshes databases, the other replaces the binary. - Assuming checkpoints cover everything. Files the assistant writes or edits are snapshotted; anything a shell command writes is not. Commit before a large change.
FAQ
Is the local runner a separate download?
No. It is built into the Safeguard CLI. Install the CLI with the one line installer and you have the runner. safeguard runner opens the same interactive terminal as safeguard.
Does my source code leave the machine?
When the runner runs platform scan jobs, only SBOMs and findings are uploaded. The runner opens outbound HTTPS connections only, and nothing connects in to it.
Can I use my Claude or ChatGPT plan with the runner?
Yes. Bring the Claude, ChatGPT or Codex plan you already pay for and use it inside the Safeguard CLI. Safeguard adds no extra charge for that usage; your plan's own usage limits and terms still apply. Use /model and the CLI docs to connect it. You can also connect Claude or ChatGPT to the Safeguard MCP server and work from their chat.
Does the runner open a port on my network?
No. runner install and runner scan-jobs both say the runner only opens outbound HTTPS. Your firewall needs to allow outbound 443, and nothing inbound.
Can I approve the runner's actions from my phone?
Yes. The CLI session is live in the phone app. When a command or file edit needs approval, you choose Allow once, Allow for turn or Deny.
How do I keep the runner running after a reboot?
Run safeguard runner install. It registers a login service: a systemd user unit on Linux, a LaunchAgent on macOS and a logon scheduled task on Windows. On Linux servers, also enable lingering.
Does the runner enforce our policies and gates?
No. Policies and gates are defined and evaluated in the Safeguard platform. The CLI scans and uploads results; the platform decides whether a gate passes.
How do I remove it?
safeguard runner uninstall removes the login service. To remove the CLI, run safeguard logout --yes, delete the binary, and remove ~/.sg, ~/.scanner and ~/.cli (on Windows, %LOCALAPPDATA%\Safeguard). Nothing on the platform is affected.
Try it yourself
This demo sets up the runner on your own machine: pick the platform, start it, approve it with its device code, then use the same CLI to scan from the terminal.
Click through it at your own pace, or open it full screen.
Get the CLI, the desktop app and the phone apps from https://safeguard.sh/download, and keep https://docs.safeguard.sh/docs/cli open for the commands.
Quick check
Which command keeps the runner reachable from your phone after you log out of the terminal?
safeguard runner install. It registers safeguard runner start as a per user login service. On a Linux server, also run loginctl enable-linger so your user's service manager runs without a login.
The runner is online but turns never arrive, and your proxy drops long connections. What do you change?
Start it with --poll-wait 0. It then polls at a fixed interval set by SAFEGUARD_POLL_INTERVAL, which defaults to 10 seconds.
What leaves the machine when the runner runs a platform scan job?
Only the SBOM and the findings. The source code stays on the machine.
Sources
- Safeguard CLI overview
- Safeguard local runner docs
- Safeguard CLI installation
- Safeguard CLI interactive terminal
- Safeguard CLI slash commands
- Safeguard CLI usage
- Safeguard CLI troubleshooting
- Safeguard CI/CD integration
- Safeguard downloads
- systemd loginctl manual
- Apple: Creating launch daemons and agents
Last reviewed: 21 October 2026.