Safeguard
Developer Tools•

Safeguard on Windows: WSL and PowerShell Tips for Daily Work

Run the Windows Safeguard CLI in PowerShell for code on Windows drives and the Linux build in WSL for code in your Linux home, with setup steps and fixes.

Safeguard Security Team
19 min read

On Windows you can run the Safeguard CLI two ways: the native Windows build in PowerShell, and the Linux build inside WSL. Pick the one that matches where your code lives. Projects under C:\ get the PowerShell build; projects in your WSL home folder get the Linux build. Both scan on your machine and upload only results.

You keep the AI you already pay for, on either side. 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 would rather stay in the chat you already use, connect Claude or ChatGPT to the Safeguard MCP server and ask about your findings from there.

This is a working guide. If you have never installed the CLI on Windows, start with installing the Safeguard CLI on Windows, then come back for the WSL side and the daily habits.

What you will have at the end

By the end of this guide you will have:

  • The Windows CLI in PowerShell and the Linux CLI in your WSL distribution, each signed in and each scanning the projects that live on its own file system.
  • A PowerShell profile with tab completion for every safeguard command and flag, plus your proxy settings if you need them.
  • A Windows Terminal key binding so shift+enter adds a new line in the Safeguard prompt.
  • A short set of habits for exit codes, JSON output, stdin prompts and undo that work the same in both shells.
  • The Windows desktop app and your phone showing the same sessions, so you can start in a terminal and finish somewhere else.

Pick the right build: PowerShell, WSL or both

The Safeguard CLI is a single static binary with no Node, Python or JVM to install. The support matrix lists one Windows build (x86_64) and two Linux builds (x86_64 and arm64), and says that what matters is the operating system and architecture, not the distribution. Inside a WSL distribution you are running Linux, so you use the Linux install line there.

Microsoft's WSL guidance gives the rule that decides everything else: for the fastest performance, keep files in the WSL file system when you work from a Linux command line, and keep them in the Windows file system when you work from PowerShell or Command Prompt. Working across the boundary, such as running Linux tools against /mnt/c/..., is possible but slower.

Where the project livesShell to useInstall lineBuild you get
C:\src\... or anywhere on a Windows drivePowerShellirm https://cli.safeguard.sh/install.ps1 piped to iexWindows x86_64, in %LOCALAPPDATA%\Safeguard\bin
/home/you/... inside WSLBash or your WSL shellcurl -fsSL https://cli.safeguard.sh/install piped to bashLinux x86_64 or arm64, in /usr/local/bin or ~/.local/bin
Both kinds of projectBothBoth linesTwo installs, two sign-ins

Two installs means two separate copies of everything. Each keeps its own sign-in token in its own home folder, its own scanner tools and its own logs. Signing in on one does not sign in the other, and updating one does not update the other.

Check the architecture on each side. In PowerShell, run $env:PROCESSOR_ARCHITECTURE. AMD64 is the native Windows build. On ARM64, the Windows installer warns and installs the x86_64 binary to run under emulation, because there is no native Windows on ARM build. Inside WSL, run uname -m; the Linux installer detects the architecture and picks the matching Linux build.

Set up the PowerShell side, step by step

If the CLI is already installed in PowerShell, skim this and jump to step 4.

  1. Read the installer, then run it. The one liner fetches a script and runs it. To read it first:

    $script = irm https://cli.safeguard.sh/install.ps1
    $script | more
    $script | iex
    

    Watch the output. The PowerShell installer prints a warning and continues if checksums.txt is missing, where the shell installer stops. Treat that warning as a reason to verify the archive by hand before you use it.

  2. Open a new window and confirm. The installer adds its folder to your user PATH, and windows that were already open do not see the change.

    safeguard --version
    Get-Command safeguard -All
    

    The first entry from Get-Command is the copy that runs. An older build earlier on the PATH is the usual reason for an unexpected version.

  3. Finish first run setup and sign in. Run safeguard once with no arguments. The first interactive run downloads the scanner tools; safeguard update only refreshes databases for scanners you already have. Type /login, approve in the browser, then /whoami to confirm.

  4. Create a PowerShell profile. A profile is a script PowerShell runs at startup. PowerShell does not create one for you. Microsoft's documented way to create it without overwriting an existing one:

    if (!(Test-Path -Path $PROFILE)) {
      New-Item -ItemType File -Path $PROFILE -Force
    }
    notepad $PROFILE
    
  5. Add tab completion. The CLI generates a completion script from its live command tree, so it covers every command and flag in your build. Add this line to the profile:

    safeguard completion powershell | Out-String | Invoke-Expression
    
  6. Add proxy settings if your network needs them. The CLI uses HTTPS on port 443. Behind a corporate proxy, set the variables in the profile so every session has them:

    $env:HTTP_PROXY  = "http://proxy.example.com:8080"
    $env:HTTPS_PROXY = "http://proxy.example.com:8080"
    

    If your network inspects TLS with a company certificate authority, point SSL_CERT_FILE at the CA file IT gives you, or install it in the system trust store. Never turn certificate checks off.

  7. Restart PowerShell. Changes to the profile apply in new sessions. If nothing happens, check the execution policy: Microsoft's profile docs note that under the Restricted policy, profiles do not run at all. If your organisation manages this through Group Policy, ask IT rather than changing it yourself.

  8. Bind shift+enter to a new line in Windows Terminal. In the Safeguard prompt, Enter sends the message. ctrl+j adds a new line anywhere, and a trailing backslash followed by Enter continues the message. alt+enter does not work in Windows consoles, which use it to toggle full screen. To make shift+enter insert a new line, open Windows Terminal settings, choose to open the JSON file, and add an action and a key binding:

    "actions": [
      { "command": { "action": "sendInput", "input": "\n" }, "id": "User.SafeguardNewline" }
    ],
    "keybindings": [
      { "keys": "shift+enter", "id": "User.SafeguardNewline" }
    ]
    

    If those arrays already exist, add the entries to them. The binding applies to every tab.

Set up the WSL side, step by step

  1. Install WSL if you have not. On Windows 10 version 2004 or later, or Windows 11, open PowerShell as administrator and run wsl --install, then restart. It installs Ubuntu by default; wsl --install -d followed by a distribution name picks another. New installs use WSL 2. Check with:

    wsl -l -v
    
  2. Open your distribution and install the Linux CLI. From the Start menu or a Windows Terminal tab:

    uname -m
    curl -fsSL https://cli.safeguard.sh/install | bash
    safeguard --version
    which -a safeguard
    

    The shell installer tries /usr/local/bin and falls back to ~/.local/bin when the first is not writable. It aborts if the checksum file is missing. If the shell cannot find safeguard afterwards, add the folder to your PATH:

    echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
    source ~/.bashrc
    
  3. Run it once, then sign in with a device code. Run safeguard to finish first run setup. A WSL shell may not be able to open your Windows browser, so the device code route is the dependable one:

    safeguard login --no-browser
    

    It prints a URL and a short code. Open the URL in your Windows browser or on your phone, enter the code and approve. To stop /login inside the interactive terminal from trying to open a browser at all, export SAFEGUARD_NO_BROWSER in ~/.bashrc.

  4. Keep Linux projects on the Linux file system. Clone into your WSL home rather than working from /mnt/c:

    mkdir -p ~/src && cd ~/src
    git clone https://github.com/your-org/payments-api.git
    cd payments-api
    safeguard
    

    To see the folder in File Explorer, run explorer.exe . from inside it. Every distribution's files are also reachable at \\wsl$ in the Explorer address bar.

  5. Repeat proxy and CA settings. WSL has its own environment. Put HTTP_PROXY, HTTPS_PROXY and, if needed, SSL_CERT_FILE in ~/.bashrc. On Ubuntu or Debian you can add a company CA to the system store and run sudo update-ca-certificates.

  6. Add completion for bash. The CLI prints the command for each shell. For bash the documented target is the system completion folder:

    safeguard completion bash | sudo tee /etc/bash_completion.d/safeguard > /dev/null
    
  7. Know what WSL does not do for you. You can turn on systemd in a distribution by adding systemd=true under [boot] in /etc/wsl.conf and running wsl.exe --shutdown. Microsoft notes that systemd services do not keep a WSL instance alive. So a WSL distribution is a fine place to work, but not the place for an always on runner. Use a real Linux server or the Windows side for that.

Daily habits that work in both shells

These are the small things that save time once both installs are in place.

Read exit codes, not just output. safeguard scan returns 0 when the scan ran, whatever it found, 1 when the command failed, and 2 when results were written but the vulnerability scan did not run. It never fails because of findings; gating happens in the platform through policies and gates. In PowerShell read $LASTEXITCODE; in bash read $?.

safeguard scan --dir . --output .\safeguard-results
if ($LASTEXITCODE -eq 2) { safeguard doctor }

Open the JSON without guessing. Each scan writes a folder under the output directory with files such as vuln.json, license.json and collection.json. In PowerShell:

Get-ChildItem .\safeguard-results -Recurse -Filter vuln.json
$vulns = Get-Content (Get-ChildItem .\safeguard-results -Recurse -Filter vuln.json)[0] -Raw | ConvertFrom-Json
$vulns | Get-Member

Get-Member shows the fields your build writes before you script against them.

Keep stdout clean. Logs and notices go to stderr, so redirecting stdout alone gives you clean JSON in both shells:

safeguard exec --output-format json "summarise the critical findings in this repository" > summary.json

Feed long prompts from a file. safeguard exec reads the prompt from stdin when you pass -. Keep your team's standard prompts in the repository:

Get-Content .\.prompts\weekly-triage.txt -Raw | safeguard exec -
safeguard exec - < .prompts/weekly-triage.txt

Check locally with nothing uploaded. safeguard findings sca --dir . --json runs one scanner on your machine and prints findings in one normalised shape. No project is registered and nothing is uploaded, even when you are signed in. Use it when you want a quick look before a commit.

Cross over only for one off checks. Microsoft's interop runs a Linux command in the current PowerShell folder when you put wsl in front of it, so wsl safeguard scan --dir . scans a Windows folder with your WSL install and its sign-in. It needs the WSL copy in a folder on the default PATH, such as /usr/local/bin, and it reads across the file system boundary, which is slower, so do not make it routine.

Send a result to your phone. safeguard devices lists your signed-in devices that can send and receive. Then:

safeguard send --to "Pixel" --text "payments-api: 2 critical findings, see summary.json"

safeguard inbox shows what your other devices sent to this CLI: links, text, files and conversations.

Undo an assistant edit. Files the assistant writes or edits are snapshotted before each change. /rewind in the interactive terminal steps back, and from the shell:

safeguard checkpoints list --session <id>
safeguard checkpoints restore <checkpoint> --session <id> --dry-run

--dry-run shows what would change as a diff. Anything a shell command wrote is not snapshotted, so commit before you start larger work.

Do the work properly with the Safeguard CLI

The Safeguard CLI scans code, container images and SBOMs on your own machine, sends only the results to the platform, and includes an assistant that can fix what it finds. It writes code, not only scans it. On Windows that gives you one tool in PowerShell and one in WSL for the scan, the fix and the check afterwards.

Install

PowerShell: irm https://cli.safeguard.sh/install.ps1 | iex. WSL, macOS and Linux: curl -fsSL https://cli.safeguard.sh/install | bash. Single static binary either way.

First session

Run safeguard with no arguments in a project folder. /login signs in, /scan . scans the folder, and anything that does not start with / goes to the assistant. Type @ to attach a file from the folder you started in, and /resume picks up your last session in that folder next time.

Writing and fixing code

The assistant has tools for your local files and for your Safeguard data, and picks whichever the question needs. It can find and read files, edit code and run commands, with your approval. A typical fix:

fix the lodash CVE in this repo, then run the tests

This recorded session shows that exact loop on the sample project payments-api. It installs with the curl line (checksum verified), checks safeguard --version, opens the interactive terminal and asks "fix the lodash CVE in this repo". The assistant reads the finding, the files and the advisory, then 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 while pushing nothing. It ends with /permissions, /model and /scan .. The recording was made on a Mac with the same line you use inside WSL; in PowerShell use the irm line instead.

Click through it at your own pace, or open it full screen.

Using your Claude, ChatGPT or Codex plan

Your existing plan works inside the CLI on both sides of the machine, with no extra Safeguard charge and within your plan's own limits and terms. /model shows or switches the model; for connecting your own plan, follow the CLI docs and the /model picker.

Approvals

/permissions sets how much the assistant may do before it asks:

ModeWhat runs without askingGood for
AskReads; edits and commands ask firstA repository you do not know well
Accept editsEdits in this folder and read-only commands; other commands askFocused refactors
PlanRead and plan onlyExploring before you change anything
Auto (default)Read-only commands and what the policy allows; anything else asksDaily work
StrictPre-approved actions onlyCI

There is also a --yolo flag that approves everything. Keep it for throwaway sandboxes, never your main Windows profile or a WSL distribution that holds real keys.

CI with safeguard exec

safeguard exec runs one non-interactive assistant turn and exits. Its default permission mode is strict: nothing is asked, and anything your policy file has not pre-approved is denied. It refuses to run outside a git repository unless you pass --skip-git-repo-check. That suits a Windows build agent or a WSL based script equally well. For pipeline detail, see running the Safeguard CLI in CI with safeguard exec.

Continue on the desktop app and your phone

A CLI session is live: it shows in the web app, the desktop app and the phone app, and other devices can send work to it. On Windows that makes the desktop app a natural second screen.

The desktop app 3.2.2 for Windows 10 and 11 is one installer covering x64 and ARM, with architecture specific installers also listed. It installs per user with no administrator rights. It is not yet code-signed, so SmartScreen may warn. Verify the SHA-256 first, then choose More info and Run anyway:

certutil -hashfile Safeguard-3.2.2.exe SHA256

Compare the result with the hash on the download page before you run the installer.

This recorded desktop session shows the hand-off. The CLI session appears in the desktop app's conversation list, and "2 connected" shows the computer, the browser and Safeguard cloud. You ask for work on your computer, it asks which computer and folder, you pick the folder, then Approve or Deny each command and file edit. It ends with the upgrade done and the tests passing.

Click through it at your own pace, or open it full screen.

The same conversations appear on the Android app from Google Play and the iOS app from the App Store. For the full desktop walkthrough, read the Safeguard desktop app guide.

Troubleshooting and common mistakes

Start with safeguard doctor on whichever side has the problem. It checks the environment, sign-in, tools and policy, lists problems in the order that matters, and changes nothing. Read its lines rather than its exit code, which is 0 whenever the checks ran.

Troubleshooting

"safeguard is not recognized" in PowerShell. The window was open before the install changed your PATH. Open a new one, then run Get-Command safeguard -All.

"command not found" in WSL. The installer used ~/.local/bin and it is not on your PATH yet. Add it in ~/.bashrc and run source ~/.bashrc.

Sign-in works in PowerShell but WSL says "Not authenticated". Expected. The WSL install has its own token. Run safeguard login --no-browser inside WSL.

"syft binary not found" or a scan that returns exit code 2. First run setup did not finish on that side. Run safeguard interactively once, then safeguard update.

Scans from WSL are slow. Check pwd. If it starts with /mnt/, you are scanning a Windows drive from Linux. Move the project into your WSL home or scan it from PowerShell.

The mouse wheel does not scroll the transcript. The CLI does not capture the mouse. Use PgUp and PgDn. Selection still works for copying, and /copy copies the last response.

Logs are written to ~/.sg/logs/safeguard.log by default, and LOG_DIR moves them.

Common mistakes

Running the PowerShell line in Command Prompt. irm and iex are PowerShell aliases. Use PowerShell.

Editing the profile and testing in the same window. Profile changes apply to new sessions.

Treating WSL as a server. systemd services do not keep a WSL instance alive. Put long running runners on a real Linux machine; see the headless runner setup in installing the Safeguard CLI on Linux.

Setting SAFEGUARD_SKIP_CHECKSUM to get past a warning. It is an explicit opt out for cases such as air-gapped mirrors. Fix the download instead.

FAQ

Do I need both the Windows and the WSL install?

Only if you have projects on both file systems. If all your code lives in WSL, the Linux install is enough. If it all lives under C:\, the PowerShell install is enough.

Can I keep using my Claude, ChatGPT or Codex plan?

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. You can also connect Claude or ChatGPT to the Safeguard MCP server; see connecting Claude to the Safeguard MCP server.

Does the CLI run natively on Windows on ARM?

Not natively. The PowerShell installer warns and installs the x86_64 binary, which runs under emulation. The desktop app does have an ARM installer.

Do I need administrator rights?

Not for the CLI in its default location, which is inside your user profile, or for the desktop app, which installs per user. Installing WSL itself needs an administrator PowerShell.

Does my source code leave the machine?

When the local runner runs platform scan jobs, only SBOMs and findings are uploaded, and the source stays on your machine. safeguard findings uploads nothing at all.

Will the assistant change files without asking?

Only in the modes you choose. In the default Auto mode, edits and commands outside what is read-only or allowed by policy ask first. --yolo approves everything and belongs in throwaway sandboxes only.

How do I update each install?

Run safeguard self-update on each side, or safeguard self-update --check to see what would change. It verifies a signed release manifest before it replaces anything, and keeps the previous binary as safeguard.previous. safeguard update is different: it refreshes vulnerability databases.

Try it yourself

This walkthrough covers installing and starting the CLI: set 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.

Ready to set up your own machine? Download Safeguard for the CLI and the Windows desktop app, and keep the CLI docs open for your first week.

Quick check

Your project lives in /home/you/src inside WSL. Which Safeguard build should scan it?

The Linux build installed inside WSL with the curl line. Microsoft recommends keeping Linux command line work on the Linux file system, and the Windows build would have to read across the boundary.

Why does alt+enter not add a new line in the Safeguard prompt on Windows?

Windows consoles use alt+enter to toggle full screen, so it never reaches the CLI. Use ctrl+j, a trailing backslash and Enter, or bind shift+enter to a sendInput action in Windows Terminal.

You signed in on PowerShell. Why does WSL still say you are not signed in?

Each install keeps its own token in its own home folder. Run safeguard login with the no-browser option inside WSL and approve the device code.

Sources

Last reviewed: 21 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.