> ## Documentation Index
> Fetch the complete documentation index at: https://docs.valarhq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Roll out with MDM

> Deploy and run valar from Jamf, Kandji, Intune, or other MDM tools on macOS and Windows

Use your MDM to install `valar` on engineers' Macs and Windows 11 PCs, set it up, and keep it current without anyone typing a command. This page explains how `valar` runs under MDM and in what order to deploy it. The sections before [Windows](#windows) describe macOS.

## How valar runs under MDM

MDM scripts run as root, in the background, with no terminal. `valar` is built for a signed-in engineer, so three rules follow.

**Every command acts for one user.** `valar` changes that user's configuration in `~/.valar`, each app's settings in the user's home, and the proxy services that run in the user's login session. A command run as root with no user selected is refused (`V1A-1004`). A command acts for the user in one of two ways:

* **Proxy setup runs as root, for a selected user.** `valar proxy enable` needs administrator access: it sets the network proxy and installs the proxy services. Run it from a root policy with `SUDO_USER` set to the target account. `valar` does the user's part of the setup as that user.
* **Everything else runs as the user.** `valar configure`, `valar upgrade`, and `valar <harness> on|off` need no administrator access. Run them as the signed-in user, either through your MDM's option to run as the signed-in user or by switching to that user from a root script (see the [example](#example-run-as-the-signed-in-user)). Run `valar upgrade` this way, not through `SUDO_USER`.

**The user must be signed in.** The proxy services run in the user's login session, so the account and its home directory must exist and a session must be open.

**Nothing can ask for confirmation.** `valar` asks before it restarts a running app. Under MDM it cannot ask, so pass `--force` (see [Restarts](#restarts)).

## Choose a lane

The on-device proxy is optional. Without it, `valar <harness> on` uses the direct lane. The proxy lane adds [quota-first](/valarcode/claude-code#quota-first-use-your-own-subscription-first) and Remote Control. For [Cursor](/valarcode/cursor) on macOS, it keeps Cursor's own models working next to Valar's and makes Valar only strict. It needs two things on every Mac:

* **A root certificate your MDM trusts.** See [Set up the proxy from a root policy](#set-up-the-proxy-from-a-root-policy).
* **Each engineer signed in to Claude Code with their Claude account.** Without it, Claude Code stops at "Not logged in".

For the direct lane, skip step 4 below.

## Deploy

1. **Install the CLI** at a path the user can run, such as `/usr/local/bin/valar`. See [Install the CLI](/valarcode/setup#install-the-cli).

2. **Give each engineer a coding key.** Create keys in the dashboard or with [key automation](/valarcode/key-automation). Store each key as that user with `valar configure --api-key <key>`, or provide it through a protected `VALAR_API_KEY` environment variable. Keep keys out of policy arguments and logs.

3. **Upgrade existing installs, as the user:** `valar upgrade --force`. Finish this before setting up the proxy.

4. **Set up the proxy, from a root policy** (proxy lane only, see [below](#set-up-the-proxy-from-a-root-policy)).

5. **Turn on each harness, as the user:**

   ```bash theme={"system"}
   valar claude-desktop on --force
   valar claude on --force
   valar cursor on --force   # macOS and Linux; add --valar-only for Valar only
   ```

6. **Verify the proxy lane** with `valar <harness> status --verify` after the user sends a request through that harness. On the direct lane, use `valar <harness> status`.

7. **Keep it current.** Whenever your MDM installs a new `valar` binary, run `valar upgrade --force` as the user. Until it runs, most commands refuse (`V1A-1903`).

## Set up the proxy from a root policy

Under MDM, bring your organization's certificate. macOS trusts a new root only from an MDM profile or a person at the screen, so the certificate `valar proxy enable` creates on its own fails from a policy (`V1A-1113`). Before the policy runs:

1. **Deliver your root CA as an MDM configuration profile** with a Certificate payload. Until it arrives, `valar proxy enable` stops with `V1A-1106`.
2. **Put a leaf certificate for `api.anthropic.com` and its key on the Mac**, readable by root. See [Create an organization-managed certificate](/valarcode/proxy#create-an-organization-managed-certificate).

Then run:

```bash theme={"system"}
#!/bin/bash
set -euo pipefail

TARGET_USER="jdoe"
VALAR_BIN="/usr/local/bin/valar"

if [ "$(id -u)" -ne 0 ]; then
  echo "Run this policy as root." >&2
  exit 1
fi
if ! TARGET_UID="$(id -u "$TARGET_USER" 2>/dev/null)" || [ "$TARGET_UID" -eq 0 ]; then
  echo "Select an existing, non-root user." >&2
  exit 1
fi

SUDO_USER="$TARGET_USER" "$VALAR_BIN" proxy enable \
  --cert /absolute/path/leaf-bundle.pem --key /absolute/path/leaf.key
```

A root policy can read root-only certificate files; the installed copies are private to the user. Use absolute paths. If IT manages traffic steering, add `--ingress external`; if your network requires an outbound proxy, add `--upstream-proxy`. See [Corporate networks](/valarcode/proxy#corporate-networks).

Setting up the proxy does not turn on any harness. Running it again keeps each harness's on/off choice but restarts the proxy, interrupting requests in flight, so run it on first setup and after renewing the certificate. If you use Cursor, also run it once after upgrading to a release with Cursor support, so the certificate covers Cursor (reissue an organization-managed certificate with Cursor's names first).

## Restarts

Some changes apply only after a running app restarts. With a terminal, `valar` asks first. Under MDM it cannot ask, so pass `--force` to every `valar upgrade` and `valar <harness> on|off`. Without it, a command that needs a restart changes nothing and exits with an error (`1` for `on`/`off`, `20` for `upgrade`).

`--force` restarts what the change needs:

* **Claude Desktop** quits and reopens in the background.
* **Cursor** quits and reopens.
* **Claude Code** closes interactive sessions and restarts background agents. Users reopen conversations with `claude --resume`.

On `valar upgrade`, `--force` also accepts any breaking changes the upgrade lists.

Restarts interrupt work in progress, so schedule forced runs at login or outside working hours. `--force` does not bypass certificate, ownership, or network checks.

## Example: run as the signed-in user

If your MDM can run a script as the signed-in user, run the `valar` commands directly. Otherwise, switch to that user from a root script, as this macOS example does. Adapt it to your fleet, for example by listing only the harnesses your engineers use.

```bash theme={"system"}
#!/bin/bash
set -e

user=$(stat -f %Su /dev/console)
if [ "$user" = root ]; then
  echo "No user is signed in; retry later." >&2
  exit 1
fi
uid=$(id -u "$user")

as_user() {
  launchctl asuser "$uid" sudo -u "$user" -H /usr/local/bin/valar "$@"
}

as_user upgrade --force
as_user claude-desktop on --force
as_user claude on --force
```

## Windows

On Windows, no `valar` step needs administrator access, and every command runs as the signed-in user, including `valar proxy enable`. `valar` sets up the account that runs it, so a script that runs as SYSTEM does not set up the engineer's account. In Intune, set **Run this script using the logged on credentials** to **Yes**; with other tools, use their equivalent option.

Windows asks the user to confirm before a certificate is added to their own store, and an unattended script cannot answer. An unattended `valar proxy enable` that would create its own certificate therefore stops before changing anything (`V1A-1128`). Deploy an organization certificate instead:

1. **Trust your organization's root** on each device: an Intune trusted certificate profile or Group Policy that installs it in the computer's **Trusted Root Certification Authorities** store. See [Trust and distribute](/valarcode/proxy#trust-and-distribute).
2. **Deliver each device's leaf bundle and key** to a location only the signed-in user can read. Setup copies both into its own protected folder.
3. **Install the CLI.** The [installer](/valarcode/setup#install-the-cli) places it at `%USERPROFILE%\.local\bin\valar.exe`.
4. **Run the setup as the signed-in user:**

```powershell theme={"system"}
$ErrorActionPreference = "Stop"
$valar = Join-Path $env:USERPROFILE ".local\bin\valar.exe"

function Invoke-Valar {
  & $valar @args
  if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}

Invoke-Valar upgrade --force
Invoke-Valar proxy enable --cert C:\path\to\leaf-bundle.pem --key C:\path\to\leaf.key
Invoke-Valar claude-desktop on --force
Invoke-Valar claude on --force
```

Store the coding key first with `valar configure --api-key <key>` as the same user, or provide `VALAR_API_KEY` through a protected channel. Keep keys out of script arguments and logs.

If your organization applies one proxy setting to every user of the machine, `proxy enable` stops (`V1A-1125`): add `--ingress external` and deploy the Valar rule in your PAC. If your network requires an outbound proxy, add `--upstream-proxy`. See [Corporate networks](/valarcode/proxy#corporate-networks).

**Keep it current.** When your tool installs a new `valar.exe`, run `valar upgrade --force` and then `valar proxy restart` as the user. The restart moves the proxy services onto the new version.

**Verify** with `valar <harness> status --verify` after the user sends a request through that harness. To check the device without Valar, see [Deployment checks and diagnostics](/valarcode/proxy#deployment-checks-and-diagnostics).

## Update older policies

* **Selecting the user:** root policies that relied only on `HOME` must set `SUDO_USER` or run as the user.
* **Old command names:** `valar claude-desktop proxy` still works as an alias for `valar proxy`. On `proxy enable`, `--force`, `--no-restart`, and `--off` are accepted and ignored with a warning. Put `--force` on the harness command instead, and use the harness's `off` to stop routing.
