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

# Fleet rollout

> Push the endpoint agent to every employee laptop. Windows enrols silently with one fleet token; a Mac enrols when its user signs in.

This is how a company rolls Blindsight Endpoint out "like AD": one silent
push from the MDM, the directory auto-provisions every employee, and
every device binds to a real identity.

There are two independent axes; you almost always want both.

1. **Fleet software push.** IT deploys the agent to every machine
   with no per-user clicks. Windows: `.msi` via Intune, GPO, or SCCM,
   with one workspace‑wide enrollment token baked into the command;
   the agent self‑enrolls on first run. macOS: the `.dmg`, which
   carries no token; each Mac enrols when its user signs in.
2. **Directory sync + SSO.** Your IdP (Entra, Okta, Google) provisions
   every employee into the workspace (SCIM) and binds each device to
   the matching directory user on first sign‑in (OIDC).

On Windows these are decoupled on purpose. The silent installer runs
as SYSTEM and cannot know the human user, so identity is bound
**after** enrollment via the SSO device‑code flow, opened
automatically by the agent. On macOS the two happen together: the
sign-in that binds the identity is the one that enrols the device.
Either way, the employee signs in once.

See [Identity binding](https://docs.blindsight.io/endpoint/identity.md) for the directory and SSO side,
and [Installing the agent](https://docs.blindsight.io/endpoint/install.md) for what an install changes on
a single machine. This page is the IT‑side rollout.

## 1. Create the fleet enrollment token

**1. Open Endpoint → Devices**

**Endpoint → Devices → create token.** The copy-paste install command
with the token already baked in is on
**Endpoint → Configurations → Install**.

**2. Copy the token**

Shown when it is minted. Store it in your MDM secret vault. One
token covers the entire Windows fleet. Macs do not use it. An admin
who holds `endpoint.enrollment.reveal` can show it again later, so
an MDM job can reuse it without minting another.

**3. (Optional) Restrict the token**

Token settings let you cap the number of activations, set an
expiry, and limit it to a specific directory group.

## 2a. Windows push

Windows is the primary platform. The agent runs as a SYSTEM service
named `BlindsightDLP`.

```text theme={null}
msiexec /i Blindsight-<version>.msi /qn ^
  CLOUD_BASE=https://api.blindsight.example.com ^
  ENROLL_TOKEN=antde_xxxxxxxxxxxxxxxxxxxx
```

`CLOUD_BASE` and `ENROLL_TOKEN` are the **only two** properties the
package takes. Both are 64‑bit, per‑machine, x64 only.

Deploy via:

* **Intune** as a Win32 app. See [Deploying with Intune](#deploying-with-intune).
* **Group Policy** as a startup script. See [Deploying with Group Policy](#deploying-with-group-policy).
* **Configuration Manager (SCCM)** and other tools. See [Configuration Manager and other tools](#configuration-manager-and-other-tools).

The MSI writes `HKLM\SOFTWARE\Blindsight` (`CloudBaseURL`,
`EnrollmentToken`, `SSOLoginBase`), generates a **per-machine**
inspection root CA and adds it to the machine trust store (there is no
shared fleet key), and installs the SYSTEM service. The service self‑enrolls and runs the SSO
identity‑binding flow. An interactive install opens the dashboard
once; `/qn` stays silent.

> [!NOTE]
>
> Passing a property on the command line always wins. If you omit
> both, the installer keeps whatever the machine already has in
> `HKLM\SOFTWARE\Blindsight`, and only a genuinely fresh install
> falls back to the build's default. This is what makes an upgrade
> safe: a self-update runs `msiexec` with no properties and must not
> retarget a device that IT pointed somewhere specific.

> [!WARNING]
>
> A bare `msiexec /i Blindsight-<version>.msi /qn` does **not** enrol a device
> unless the build was created with a token baked in, or the machine
> already carries one. Pass `ENROLL_TOKEN` for a fleet push.

> [!WARNING]
>
> The per‑user `.exe` installer (Inno Setup) has been **withdrawn** and
> should not be used for new installs, fleet or otherwise. It installs
> into the user profile, which leaves the device token and the local
> policy owned by the person the agent is protecting, so the tamper
> resistance the MSI gets from LocalSystem does not apply. It is also a
> separate product identity, so `msiexec` cannot upgrade it in place.

On Windows 11 the stock vulnerable-driver blocklist refuses the
bundled capture driver and the agent falls back to its explicit-proxy
engine, which covers less. This is expected and needs no action from
you, but it does change coverage. See
[Windows 11 and the network driver](https://docs.blindsight.io/endpoint/install.md) for what is and is
not covered, and how the device reports it.

## Deploying with Intune

This is the configuration that enrolled a test fleet of Windows
machines cleanly and silently, with no sign-in and no reboot. The install
ran as SYSTEM and finished in under a minute. A machine that installed
during boot, before anyone signed in, enrolled about a minute later. It
was validated on Windows Server 2022 and Windows Server 2025.

### Create the app

The console walks through these same steps one at a time: open
**Endpoint → Configurations → Install**, choose **Windows**, then **Intune**.
It shows the install command with a **Generate token** button, so the
command you copy already holds a token.

**1. Package the MSI**

From **Endpoint → Configurations → Install**, download
`Blindsight-<version>.msi` (**Download MSI**) and the install kit
(**Download kit**). Put the MSI and the kit's `uninstall.ps1` in one
folder and package it with the Microsoft Win32 Content Prep Tool
(`IntuneWinAppUtil.exe`). Set the setup file to the MSI. Add it to
Intune as a **Windows app (Win32)**, with **Install behavior** set to
**System** and the architecture set to **x64**.

**2. Set the install command**

On the **Install** step, select **Generate token**. The console puts the
token into the command and shows it once, so copy the command before you
leave the page.

```text theme={null}
msiexec /i Blindsight-<version>.msi CLOUD_BASE="https://api.blindsight.example.com" ENROLL_TOKEN="antde_xxxxxxxxxxxxxxxxxxxx" /qn /norestart
```

This command was validated running as SYSTEM in a 32-bit process, which
is how Intune runs it.

**3. Set the detection rule**

Add a rule manually, with rule type **File**:

| Field | Value |
| - | - |
| Path | `C:\Program Files\Blindsight` |
| File or folder | `BlindsightAgent.exe` |
| Detection method | File or folder exists |
| Associated with a 32-bit app on 64-bit clients | No |

The agent updates itself and keeps this file, so the rule keeps working
after an update. Never detect on the ProductCode. An update installs a
new ProductCode, so a rule that pins it starts reporting "not detected"
within minutes of the first update, and Intune's built-in MSI rule pins
it. A custom script that looks up the UpgradeCode
`{1B8032BE-2978-4F43-802A-3A10B186515F}` through
`WindowsInstaller.Installer.RelatedProducts` also works. The kit's
`detect.ps1` is that script.

**4. Set the uninstall command**

The ProductCode changes with every version, so the uninstall command runs
the kit's script, which finds the installed product through the
UpgradeCode:

```text theme={null}
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\uninstall.ps1
```

`uninstall.ps1` has to be inside the `.intunewin` package. If you leave
it out, uninstalling from Intune fails. The script treats `1605` (the
product is already gone) as success. When uninstall codes are required on
the workspace, authorize the devices first or pass `-UninstallCode`. See
[Uninstalling the agent](https://docs.blindsight.io/endpoint/uninstall.md).

**5. Leave the return codes at their defaults**

`0` and `1707` are success, `3010` is a soft reboot, `1641` a hard
reboot, and `1618` retries. Expect `1603` for a downgrade, or when the
workspace requires an uninstall code and none was given. A re-run of a
failed install, with a corrected token or address, enrolls normally.

**6. Assign it to a device group**

Target **devices**, not users. The install needs no one signed in.
For a pilot, scope the assignment to one group and use a token
limited to the matching directory group. See the pilot workflow
below.

### Package the kit instead

If you prefer scripts to a bare MSI, package the whole kit folder with the
MSI and set the setup file to `install.ps1`. `install.ps1` carries the
token and exits with `msiexec`'s own exit code, so Intune reads the result
correctly.

| Field | Value |
| - | - |
| Install command | `powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\install.ps1` |
| Uninstall command | `powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\uninstall.ps1` |
| Detection | Custom script, upload `detect.ps1`, run as 32-bit process: No |

The kit's `README.txt` lists the same fields, and both are generated from
one place, so the console and the README always agree. The kit holds a live
enrollment token in `install.ps1` and `install.bat`, so treat the zip as a
secret.

### Updates

The agent keeps itself up to date, so leave **auto-update** on and detect
by the UpgradeCode or file version. If Intune must be the only thing that
changes the version, set the machine environment variable
`BLINDSIGHT_AUTO_UPDATE=0` before the install. The service reads it only
after a reboot.

An upgrade restarts the service, and during the restart the device is
not inspected for roughly 40 to 55 seconds, with the posture reading
`bypassed` until it restores. Schedule updates accordingly.

### Tokens

* Use a separate named kit, and therefore a separate token, for each wave
  of devices.
* Revoke an old token only after every device enrolled with it is stable.
* Do not turn on verbose Windows Installer logging (`/l*v`) on a
  production fleet. A verbose log records the install command line. If a
  token reaches a log, revoke it and mint another.

### Golden images

Always run **sysprep** on an image before you clone it. Two machines
cloned without it share one machine identity and merge into one device
row. The agents then swap the token between them every minute, the row's
hostname flips back and forth, the posture stays `bypassed`, and no error
is shown. Machines cloned with sysprep get their own identities and their
own rows. If you find a row like this, sysprep the image and revoke the
row.

### What shows up in the console

* **Identity is `pending` on every Windows device.** The service runs as
  SYSTEM, so it reports the machine account (`HOST$`) as the device's
  operating system user and never learns who signs in. The devices are
  fully protected while they are pending. To attribute traffic to a
  person, bind each device through
  [single sign-on](https://docs.blindsight.io/endpoint/identity.md), or
  an admin chooses **Confirm owner**. A confirmation is lost on a clean
  re-enrolment, so it has to be made again after a reinstall.
* **A device appears when it first enrolls.** There is no expected-versus-
  enrolled count. A machine that never enrolled is not in the console, so
  check Intune for its install status. `1603`, `1618`, `1605` and "not
  detected" are all visible only in Intune.
* **An offline machine installs and then enrolls.** The install returns
  `0` and the agent retries until it can reach the platform, typically
  within a few minutes of the network returning, including after a reboot
  while offline.
* **A bad token or address leaves no row.** The device log shows `401`, an
  unresolvable host, or a `405` for a wrong path. Rerun the install with
  the right values.
* **Seats.** At the seat limit, a new device gets `429` and no row. Free a
  seat by revoking a row in **Endpoint → Devices**.
* **A device that stops reporting** shows as offline after about five
  minutes, but its status stays `active` and its posture `protected`
  until you act. Nothing is raised for it.

### Retiring devices

Revoke the device row in **Endpoint → Devices**. That releases its seat
and ends its token. An uninstall pushed from Intune while the workspace's
uninstall mode is **off** removes the agent but leaves the row active and
the seat held, so revoke the row too. Under **enforce**, an authorized
or coded uninstall frees the seat and records the device as uninstalled.
See [Uninstall codes](https://docs.blindsight.io/endpoint/uninstall.md#uninstall-codes).

The uninstall mode takes about three minutes to apply after you change it,
and an uninstall attempted in that window can return `1603`. Retry it.

## Deploying with Group Policy

Use a computer startup script that runs the kit's `install.bat`. Startup
scripts run as SYSTEM before anyone signs in.

**1. Stage the files**

Put `install.bat` and `Blindsight-<version>.msi` together in a folder
every computer can read, for example the GPO's own **Startup** scripts
folder. `install.bat` holds the enrollment token, so keep that folder
readable by computers only.

**2. Add the startup script**

In Group Policy Management, open the GPO and go to **Computer
Configuration → Policies → Windows Settings → Scripts (Startup/Shutdown)
→ Startup**. Add `install.bat`.

**3. Skip devices that already have the agent**

Startup scripts run at every boot, and reinstalling the same version over
a running agent is not harmless. Add this as the first line of
`install.bat`:

```text theme={null}
if exist "%ProgramFiles%\Blindsight\BlindsightAgent.exe" exit /b 0
```

**4. Link the GPO**

Link it to the OU that holds the computers. They install at the next
restart, or run `gpupdate /force` and restart.

`install.bat` also suits fleets whose policy enforces the `AllSigned`
PowerShell execution policy, because it runs no unsigned script.

## Configuration Manager and other tools

For Configuration Manager (SCCM), create an application or package with
`install.bat` and the MSI as its content. Set the install command to
`install.bat`, run it as the system account whether or not a user is signed
in, and detect by the file `C:\Program Files\Blindsight\BlindsightAgent.exe`
existing. For an RMM tool or a one-off install, run the `msiexec` command
from **Endpoint → Configurations → Install → Command line** from an
elevated prompt, with the MSI in the same folder.

## 2b. macOS push

macOS ships as a **`.dmg`**, one per processor
(`Blindsight-Mac-<version>-arm64.dmg` for Apple silicon,
`Blindsight-Mac-<version>-x86_64.dmg` for Intel). Drag
`Blindsight Mac.app` into Applications. macOS 11.0 is the minimum.
There is no `.pkg`. The app is signed and notarized, so it opens
without a Gatekeeper prompt.

There is no token to distribute for a Mac. Push the disk image, or the
app from it, with Jamf, Kandji or Intune, or let employees take it from
the console's Downloads page. On first open the person signs in with
their work account, which enrols the device and binds their identity,
then approves the inspection certificate and the protection service
when macOS asks.

**Endpoint → Configurations → Install** offers a macOS install kit: a
README with the download links, checksums and steps for both builds on
your release channel. It holds no secret and can be shared freely.

For a single-tenant or self-hosted platform, push a configuration
profile in the `dev.blindsight` preferences domain so the app talks to
your platform rather than the Blindsight cloud:

| Key | Value |
| - | - |
| `CloudBaseURL` | `https://api.blindsight.example.com` |
| `SSOLoginBase` | `<CloudBaseURL>/api/auth/sso` |

A per-user profile is read before the device-wide one.

Interception on macOS uses an automatic proxy configuration (PAC) on
every network service plus a local inspection proxy, with the
inspection root CA in the login keychain and a root guardian daemon
that restores the configuration if it is disturbed. See
[What the install actually changes](https://docs.blindsight.io/endpoint/install.md) for the full list.

> [!NOTE]
>
> A macOS build older than 1.0.29 reports its bundle version as
> `0.1.0` to Finder and to inventory tools, whatever the agent
> actually is. Read the version from **Endpoint → Devices** instead,
> which is reported by the agent itself.

Linux is not supported.

## 2c. Keeping the fleet up to date

The agent self-updates by default: it checks a release manifest 60
seconds after start and then every 6 hours, verifies the download's
SHA-256 and size before installing it, and preserves device state
across the upgrade (enrollment, the CA, the pseudonymization vault, the
local event spool, sign-in and settings).

| Channel | What it is |
| - | - |
| `auto` | The default. Follows whatever platform the device is enrolled against. |
| `stable` | Promoted production builds. |
| `staging` | Internal and pre-release builds. `beta` is an alias for this. |

> [!WARNING]
>
> On a managed fleet, set `auto_update = false` (under `[update]` in
> the agent's config, or `BLINDSIGHT_AUTO_UPDATE=0`) and push builds
> through your MDM instead, so version rollout stays on your change
> calendar.

Never delete `%ProgramData%\Blindsight\pseudonym_vault.db` or
`vault.key`. They hold the only mapping from a surrogate back to what
the person actually wrote, and losing them is permanent and visible
to the user. A genuine uninstall wipes them; an upgrade does not. See
[Uninstalling the agent](https://docs.blindsight.io/endpoint/uninstall.md).

## 3. Verify rollout

Open **Endpoint → Devices** in the dashboard. Each machine appears
with an **Identity** column.

| Identity status | What it means |
| - | - |
| `bound` | The employee completed SSO. Traffic is attributed to a directory user. |
| `auto` | OS username matched a directory user via SCIM. Useful for non‑user devices. |
| `pending` | Agent enrolled, identity binding not yet completed. |

Tamper attempts (uninstall blocked by guardian, modified binary,
disabled proxy) surface as high‑severity audit events under
`POST /agent/tamper-events`.

## Managed devices in the desktop app

The desktop app treats a device you provisioned differently from one a
person set up themselves, so a person cannot undo what you chose.

* **Sign-in options are hidden.** On a managed device the sign-in screen
  has no **Advanced** link for the workspace address, App ID and token,
  and the device refuses a change to the workspace address. A Mac counts
  as managed when an MDM configuration profile is present. A Windows
  device counts when the installer or policy sets the platform address
  or an enrolment token.
* **Start at Login stays on.** Where the machine starts the app at every
  sign-in, the **Start at Login** item is not offered, and an earlier
  choice of off is recorded as on so the app does start. That is a
  macOS MDM profile, or the machine-wide startup entry the Windows
  installer writes.

## Out-of-repo signing

Certain steps **cannot** be done inside Blindsight's source tree.
They require external certificates and Apple / Microsoft developer
relationships.

| Step | Why it cannot be done here |
| - | - |
| Signed WFP kernel driver (optional, admin‑tamper hardening) | Needs EV cert + Microsoft attestation signing. |

Windows installers and binaries, and the macOS app and disk images, **are** signed in the shipped builds. The macOS builds are also notarized.

Talk to your account manager for the signed bundles tailored to your
organisation.

## SAML

SAML is schema‑ready in the backend but not enabled in this build.
OIDC covers Entra, Okta, Google, and Ping. Open a ticket if you have
a SAML‑only IdP.

## Common workflows

> **Pilot a small group before fleet rollout**
>
> 1. Create a token in **Endpoint → Devices** restricted to one
>    directory group (`engineering-pilot`).
> 2. Push the agent to that group via your MDM's smart‑group
>    scoping.
> 3. Watch verdicts and tamper events for a week.
> 4. Once you're happy, mint a new token without the group restriction
>    and promote to the whole fleet.

> **Rotate the enrollment token**
>
> 1. Mint a new token in **Endpoint → Devices**.
> 2. Update the MDM payload to embed the new token. Existing
>    devices are unaffected; rotation only matters for new
>    enrollments.
> 3. Revoke the previous token once your MDM has rolled the new
>    payload to every staging point.

> **Replace a lost laptop**
>
> 1. Revoke the device row in **Endpoint → Devices**.
> 2. Ship the replacement with the same MDM policy as the rest of
>    the fleet. The new device self‑enrolls and binds to the same
>    directory user.

> **Roll the agent back off a group**
>
> See [Uninstalling the agent](https://docs.blindsight.io/endpoint/uninstall.md), which covers the
> silent uninstall command, what it reverts, and what it destroys.

## See also

> **[Installing the agent](https://docs.blindsight.io/endpoint/install.md)**
>
> Single-machine install, what it changes, and how to verify it.

> **[Uninstalling the agent](https://docs.blindsight.io/endpoint/uninstall.md)**
>
> Silent removal, the macOS teardown, and retiring the device row.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.