Endpoint Enrollment
Governing shadow AI needs the endpoint agent on the device. This page is the operational half of shadow AI discovery: how devices are enrolled, attributed to a person, and kept working.
What gets installed?
Section titled “What gets installed?”A lightweight system service — AgentWatch Connect — shipped as signed installers for macOS, Windows and Linux. On the device it identifies traffic bound for known public AI services, stamps the corporate user identity, and forwards it to your gateway so the activity is attributed, audited and policy-checked.
It is designed to be unremarkable in operation: it runs as a managed service, survives reboots, and fails open — if the gateway is unreachable, the user’s traffic still works rather than the device losing AI access.
How does a device get enrolled?
Section titled “How does a device get enrolled?”Four routes, in decreasing order of user involvement:
| Route | How it works |
|---|---|
| Zero-touch MDM | The installer reads a managed preferences profile pushed by your MDM and enrolls itself with no user interaction — either a direct API key or a per-organization enrollment token |
| Self-service portal | A tenant-branded enrollment page where an employee signs in, downloads the right installer, and is enrolled against their own identity |
| Enrollment token | A per-organization, rate-limited token that mints a real gateway key for the device on first contact |
| Manual | An administrator supplies the key directly, for lab and pilot devices |
Enrollment is organization-scoped: a token can only ever enroll a device into the organization that issued it.
How is activity attributed to a person?
Section titled “How is activity attributed to a person?”The agent stamps the corporate identity on every forwarded request, which is the same mechanism delegated identity uses on the API path. Where a device carries no identity — a DNS-steered deployment, or a shared kiosk — attribution falls back to the organization by egress IP, which is honest about being organization-level rather than inventing a user.
Consumer accounts are a real limitation worth stating plainly: activity from a personal address that does not exist in your directory cannot be mapped to an employee by email. It is still visible, still policy-checked, and still attributed to the device and organization.
Why does the agent install a certificate?
Section titled “Why does the agent install a certificate?”Because content inspection requires it. Public AI services are reached over TLS, so applying DLP to what an employee pastes into a chatbot means terminating that TLS on the device. The agent installs a local trust anchor to do so, distro-aware across the platforms it supports.
Without that trust step you still get discovery — which services are being used, by whom, how often — but not content inspection. Some organizations deliberately stop at discovery; both are supported, and the console is explicit about which one a device is providing.
Can traffic be steered without an agent?
Section titled “Can traffic be steered without an agent?”Yes, two ways, with a trade-off:
- DNS steering — a DNS redirector resolves known AI domains to your gateway. No software on the device, but attribution is organization-level and content inspection still requires the certificate to be trusted on endpoints. Managed DoH profiles are supported for macOS and iOS.
- Existing proxy or CASB — AgentWatch accepts the identity headers that Zscaler, Forcepoint and Netskope already stamp, so an organization with a corporate proxy can route AI traffic through the gateway with no endpoint change at all.
How do I install the agent?
Section titled “How do I install the agent?”Linux (servers and VMs) — a one-liner that downloads the matching binary from your AgentWatch server, installs the machine-wide systemd service and configures credentials. It is idempotent, so re-running it upgrades in place. Supported: Ubuntu/Debian and RHEL/CentOS/Rocky/Alma/Fedora, x86_64 and aarch64. Needs AgentWatch 2.0.360 or later on the server.
Run it as a normal user with sudo rights (not in a root shell), so the service
runs as that user:
export AGENTWATCH_SERVER_URL="https://<your-agentwatch-host>"export AGENTWATCH_EMAIL="john.doe@acme.com" # the employee this machine belongs toexport AGENTWATCH_API_KEY="ak_…" # that employee's gateway keycurl -fsSL "$AGENTWATCH_SERVER_URL/agent/install.sh" | sudo -E shKeep the -E: it is what passes the three variables through sudo. If your
sudo policy does not allow -E, pass them to sudo directly instead:
curl -fsSL "$AGENTWATCH_SERVER_URL/agent/install.sh" | \ sudo AGENTWATCH_SERVER_URL="$AGENTWATCH_SERVER_URL" AGENTWATCH_EMAIL="$AGENTWATCH_EMAIL" \ AGENTWATCH_API_KEY="$AGENTWATCH_API_KEY" shThe installer ends with Installed. and the commands below. Confirm the service
is running and the machine is intercepting:
systemctl is-active agentwatch-connect # activeagentwatch-connect status # shows your server and emailgetent hosts api.openai.com # 127.0.0.1 — routed through ConnectWithin about 30 seconds the machine appears under Agent Fleet in the console with Proxy running, CA trusted and Hosts active. Send any request from the machine (for example with the OpenAI SDK) and it shows up in Usage Insights under that employee.
| Symptom | Cause | Fix |
|---|---|---|
Error: Node.js is required, or an agent.js that fails with an ELF / Exec format error |
the server is older than 2.0.360 and serves a legacy installer | upgrade the AgentWatch server, then re-run the one-liner |
AGENTWATCH_SERVER_URL, AGENTWATCH_EMAIL and AGENTWATCH_API_KEY must all be set |
sudo without -E dropped the exported variables |
keep sudo -E, or use the second form above |
the download is not a Linux binary |
AGENTWATCH_SERVER_URL points at something other than the AgentWatch server (a login page, a proxy) |
use the console’s address, starting https:// |
service activating / journal shows no config found |
Connect 1.0.145 or earlier, installed with sudo | upgrade the server (it serves the fixed client) and re-run the one-liner |
a request returns 401 Authentication required from AgentWatch |
server older than 2.0.360 | upgrade the AgentWatch server |
No systemd on this machine |
a container or minimal image | start it in the foreground: sudo agentwatch-connect run |
unable to get local issuer certificate, and the computer never appears in Agent Fleet (any OS) |
a TLS-inspecting gateway (Cisco SWG, Zscaler, Netskope…) re-signs the connection with a root Connect did not trust | Connect 1.0.147 or later trusts the operating system’s roots automatically; or exempt your AgentWatch address from TLS inspection on the gateway |
Windows notes. Administrator approval is needed once, when Setup runs:
it installs the Connect certificate for the whole computer and registers a
service that starts at boot. From Connect 1.0.147 Setup does this even before
anyone has entered a server or key, so afterwards an employee without admin
rights can configure Connect and switch interception on and off with no further
prompt. On an install from before 1.0.147 the first Enable Interception still
asks once; IT can do the same from an administrator PowerShell:
& 'C:\Program Files\AgentWatch Connect\agentwatch-connect.exe' install — or push
the installer and managed configuration through your MDM, which needs no prompt
at all. If antivirus blocks the bundled browser-compatibility component, allow
C:\Program Files\AgentWatch Connect\curl-impersonate\curl-impersonate.exe; the
Connect log names the reason when it cannot start.
Managed computers. When Connect is configured by your MDM (any OS), the app hides the off switch and, from Connect 1.0.147, Connect itself refuses to turn interception off — a request from the app, a script or another program on the computer gets 403, managed by your organization. To stop interception, remove the managed configuration or uninstall Connect with administrator rights.
macOS and Windows — download the signed installer from the enrollment portal (below) or from your MDM distribution point and run it. Both register a managed system service that starts at boot.
Kubernetes and containers — the agent also runs as a sidecar or per-node DaemonSet, exposing explicit opt-in proxy endpoints rather than intercepting traffic. A DaemonSet manifest, a sidecar-injection example and a Helm chart ship with the agent.
How do I enroll a fleet without touching each device?
Section titled “How do I enroll a fleet without touching each device?”Zero-touch via MDM. Push a managed preferences profile containing either a direct API key or a per-organization enrollment token. The agent reads it on first start and enrolls itself with no user interaction. Because the profile is read by path rather than by merged domain, a DLP policy on the device cannot suppress it.
Deploying with an MDM. Step-by-step rollouts — silent install commands, the exact managed-configuration keys per OS, what employees see, verification, upgrades and pausing — are in Deploying Connect with JumpCloud (Windows, macOS and Linux) and Deploying Connect with Microsoft Intune (Windows and macOS).
Self-service portal. Turn on the tenant-branded enrollment portal (Settings → Enrollment Portal), then send employees the link. They sign in, download the right installer for their platform, and are enrolled against their own identity — no administrator involvement per device.
Enrollment token. For scripted builds, issue a per-organization token and pass it to the installer; the device exchanges it for a real gateway key on first contact. The token is organization-scoped and rate-limited, so it can only ever enroll devices into the organization that issued it.
How does a computer know which employee it belongs to?
Section titled “How does a computer know which employee it belongs to?”The enrollment token is shared by the whole organization, so it identifies the tenant, not the person. Connect resolves the person the same way on macOS, Windows and Linux, and always ends up holding that employee’s own gateway key:
| Order | Source | Notes |
|---|---|---|
| 1 | Email in the managed config |
only a real address — an unsubstituted $EMAIL / {{mail}} is ignored |
| 2 | the signed-in Windows user’s UPN | domain- or Entra-joined PCs only |
| 3 | <login name>@<EmailDomain> |
only when you set EmailDomain; no domain is ever guessed |
| 4 | sign-in approval | the employee signs in once in the browser and approves the code shown on the computer |
The managed config lives in the same place every MDM can write, and nowhere a user can:
| OS | Location |
|---|---|
| macOS | managed preferences ai.iterate.agentwatch-connect |
| Windows | HKLM\SOFTWARE\Policies\AgentWatch\Connect |
| Linux | /etc/agentwatch/connect.json — must be owned by root and not group/world-writable, otherwise it is ignored |
With Agent Fleet → Agent Connect Settings → Require sign-in to approve each
computer turned on, steps 1–3 are no longer accepted on their own and every
computer is approved by whoever signs in — the identity then never depends on
what the computer reports. An approval opened from a different network than the
computer must type the code rather than click a link. Every enrollment is in
Settings → Audit Logs as agent.device_enrolled.
Per-OS JumpCloud recipes and a troubleshooting table are in the Endpoint Enrollment Guide.
How do I verify a device is actually being governed?
Section titled “How do I verify a device is actually being governed?”Enrollment alone is not inspection. On the device:
agentwatch-connect status # service, enrollment, and interception stateThen open a public AI assistant in a browser on that device and send a harmless message. Within a few seconds it should appear in Usage Insights attributed to that employee. If the device shows as enrolled but nothing arrives:
| Symptom | Cause | Fix |
|---|---|---|
| Enrolled, no traffic captured | Interception not enabled, or the certificate is not trusted | Re-run the installer; on Windows confirm the elevation prompt was accepted |
| Traffic captured, no user | The identity is empty or unknown to this organization | Set AGENTWATCH_EMAIL to a provisioned employee, or enable Auto Create Users |
| Browser shows a certificate warning | The local trust anchor was not installed | Re-run the installer as administrator / with sudo |
| Activity attributed to the organization, not a person | Device has no identity (DNS-steered or shared) | Install the agent, or map the LAN IP to a user |
How do I uninstall Connect?
Section titled “How do I uninstall Connect?”Uninstalling removes everything Connect put on the computer and restores direct access to the AI services: the service, the hosts-file redirection, the Connect certificate (system store, browser certificate databases, macOS keychains), the browser DNS-over-HTTPS policies it set, any DNS or proxy auto-config change, its helper scripts and the CA environment variables in shell profiles. It is non-interactive (an MDM can run it), and safe to run twice. It needs administrator rights.
| Computer | Installed by a person | Installed by an MDM |
|---|---|---|
| Windows | Settings → Apps → Installed apps → AgentWatch Connect → Uninstall | Intune: assign the app as Uninstall (command "C:\Program Files\AgentWatch Connect\unins000.exe" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART). JumpCloud: run the same command as a Windows Command |
| macOS | sudo "/Applications/AgentWatch Connect.app/Contents/Resources/uninstall.sh" |
Run that path as a root script from the MDM (Jamf policy, JumpCloud Command, Intune shell script) |
| Linux (.deb) | sudo apt remove agentwatch-connect |
the same, from the MDM’s command runner |
| Linux (.bin or one-liner) | sudo agentwatch-connect uninstall |
the same, as root |
Since Connect 1.0.150 the Windows uninstaller runs agentwatch-connect uninstall first. Before that it removed the service and the files but left
the hosts-file entries and the certificate behind, so ChatGPT, Claude and
other redirected sites stopped loading after Connect was removed. On a
computer uninstalled with an older version, run this once from an
Administrator PowerShell to clean up (or reinstall 1.0.150 and uninstall it):
# remove the AgentWatch block from the hosts file and the Connect certificate$h = "$env:SystemRoot\System32\drivers\etc\hosts"$t = Get-Content $h -Raw$t = [regex]::Replace($t, '(?s)\r?\n?# >>> AgentWatch Connect - DO NOT EDIT BELOW.*?# <<< AgentWatch Connect - DO NOT EDIT ABOVE\r?\n?', "`r`n")Set-Content -Path $h -Value $t.TrimEnd() -Encoding ASCIIcertutil -delstore Root "AgentWatch Connect CA"ipconfig /flushdnsWhat is left on purpose. The uninstall output lists these:
- MDM-owned settings —
HKLM\SOFTWARE\Policies\AgentWatch\Connect(and the legacyHKLM\SOFTWARE\Policies\Iterate\AgentWatchConnect) on Windows, the configuration profile and/Library/Managed Preferences/ai.iterate.agentwatch-connect.pliston macOS,/etc/agentwatch/connect.jsonon Linux. The MDM put them there; remove them in the MDM (unassign the policy or profile). While they remain, a reinstall enrolls by itself again. - Each person’s own settings —
~/.agentwatch-connect(Windows%USERPROFILE%\.agentwatch-connect) and the key stored in their keychain, so a reinstall keeps the server, email and key.
Removing personal settings too (--purge). Add --purge to remove them for
every user on the computer:
sudo agentwatch-connect uninstall --purge # Linux (.bin / one-liner)sudo apt purge agentwatch-connect # Linux (.deb)sudo "/Applications/AgentWatch Connect.app/Contents/Resources/uninstall.sh" --purge # macOSOn Windows, run "C:\Program Files\AgentWatch Connect\agentwatch-connect.exe" uninstall --purge
from an Administrator prompt, then uninstall from Settings (or unins000.exe).
Check it worked.
# macOS / Linux - nothing should printgrep -i "AgentWatch Connect" /etc/hosts# Linuxls /etc/ssl/certs | grep -i agentwatch; systemctl status agentwatch-connect # "could not be found"# macOSsecurity find-certificate -c "AgentWatch Connect CA" /Library/Keychains/System.keychain # "could not be found"# Windows - both should find nothingSelect-String -Path "$env:SystemRoot\System32\drivers\etc\hosts" -Pattern "AgentWatch Connect"certutil -store Root "AgentWatch Connect CA"| Symptom after uninstalling | Cause | Fix |
|---|---|---|
| ChatGPT / Claude do not load on Windows | Uninstalled with Connect older than 1.0.150: the hosts entries were left | Run the PowerShell cleanup above |
| A browser still warns about the certificate, or still goes to 127.0.0.1 | The browser cached the old DNS or certificate state | Quit and reopen the browser |
| Connect comes back after uninstalling | The MDM assignment is still Required | Unassign it, or assign Uninstall, in the MDM |
apt remove left ~/.agentwatch-connect |
Personal settings are kept on purpose | sudo apt purge agentwatch-connect |
Enrollment can also be revoked centrally from the fleet view, which stops attribution immediately without touching the device — useful when a laptop is lost before it can be wiped.
What does the fleet view show?
Section titled “What does the fleet view show?”Enrolled devices with their platform, agent version, last contact, enrollment method, and whether interception and certificate trust are active — so a device that is enrolled but not actually inspecting is distinguishable from one that is. Version drift across the fleet is visible, and the agent can be updated centrally.
Sources and references
Section titled “Sources and references”- What the captured activity looks like: Shadow AI discovery.
- Identity on the API path: Delegated identity and Auto Create Users.
- Provisioning the people these devices belong to: Single sign-on and directory sync.
- Policy applied to captured content: Data protection and guardrails.