Skip to content
Docs

Endpoint Enrollment Guide

Bring every employee’s and guest’s AI usage under governance — with the lightest touch that meets your policy. Dream big, build fast.

Audience: the customer’s IT / network / security team. This guide explains how devices reach AgentWatch, how they enroll, how they’re attributed to a person, and the three deployment models — with an honest split of what AgentWatch provides vs what you configure on your network.


Axis What it means How AgentWatch does it
Access letting a device onto the network / to the internet gated on enrollment (the device trusts our CA so traffic can be governed), released by your NAC/gateway
Attribution knowing which person the traffic belongs to a separate signal: Connect client X-Zscaler-User, a LAN‑IP→user map, the observed LLM‑account email, or a portal‑verified email

Content inspection (DLP/redaction) is a third, optional layer — it needs the CA installed on the endpoint. You can run visibility-only (destinations + volume, no content) with zero content inspection.


2. Enrollment portal (what AgentWatch ships)

Section titled “2. Enrollment portal (what AgentWatch ships)”

A tenant‑branded captive/enrollment portal at https://<gateway>/portal:

  • Identity modes (per tenant): sso (your IdP), otp (emailed one‑time code — proves mailbox control), domain (allow‑listed email, no code), none (any input, monitoring‑only). Configure under Admin → Enrollment Portal (/portal-admin.html).
  • Multi‑domain allowedDomains (e.g. example.com example2.com) — employees + contractors, no pre‑known email list required.
  • Per‑OS: macOS/Windows/Linux → Connect client or profile; iOS/Android → profile only.
  • Enrolled devices skip the portal. Branding (logo/colors/copy) is tenant‑configurable.

Access is gated on enrollment, not the email — so a name/OTP/SSO is about attribution strength, not letting them online.


3. How a device reaches the portal on join — the three models

Section titled “3. How a device reaches the portal on join — the three models”

Model B — DNS trigger (lightest; one setting) ✅ turnkey

Section titled “Model B — DNS trigger (lightest; one setting) ✅ turnkey”

Point your DHCP/router DNS at the AgentWatch resolver and enable captive steering:

AGENTWATCH_DNS_CAPTIVE=1 # folds the OS captive-probe hosts into the steer set

The resolver answers the OS probe hosts (captive.apple.com, connectivitycheck.gstatic.com, www.msftconnecttest.com, …) with the gateway IP; the gateway 302s the probe path (/generate_204, /hotspot-detect.html, /connecttest.txt) to /portal, so the device auto-pops “Sign in to network.”

  • Hosted resolver: https://dns.interplay.iterate.ai/dns-query (DoH) — or run the dns-server container on‑prem.
  • What you configure: one DNS setting (DHCP option 6). Also push a Chrome/Edge Secure DNS off policy so browsers don’t bypass system DNS.
  • Limit: DNS nudges enrollment; it cannot hard‑block un‑enrolled devices. Use for monitoring‑first rollouts.

Model A — Captive portal via your Wi‑Fi/NAC (block‑until‑enrolled) — integration

Section titled “Model A — Captive portal via your Wi‑Fi/NAC (block‑until‑enrolled) — integration”

Your controller (Meraki / Aruba / UniFi / Cisco ISE / ClearPass / pfSense) runs the walled garden and points its external captive portal at https://<gateway>/portal. On enrollment the portal calls your controller back to admit the device.

  • What AgentWatch provides: the portal + an admit webhook (admitWebhookUrl, HMAC‑signed, CoA‑shaped) — see §5.
  • What you configure: the SSID’s external‑portal URL, the walled‑garden allowlist (AgentWatch host + your IdP), and the admit callback (RADIUS CoA or the controller’s API).

Model C — Inline gateway (full control) — deployment topology

Section titled “Model C — Inline gateway (full control) — deployment topology”

Route AI traffic through an AgentWatch gateway container. You do NOT change your L3 default gateway — AgentWatch is an application‑layer proxy, not a router. See §6.


Managed employee device Guest / BYOD
Method Connect thick client via MDM (Jamf/Intune/JumpCloud) mobileconfig (CA + DoH) — light consent
Consent the MDM’s (silent to user) user approves a profile (a few taps)
API key the employee’s own key, issued at enrollment (org enrollment token in the MDM profile) none needed — org by gateway egress IP
Identity MDM per‑user email, else the signed‑in OS user + your email domain, or a sign‑in approval (§7e) OTP‑verified portal email + observed LLM‑account email
Removable by user? No (MDM‑locked) Yes (their device — you cannot lock a personal device)
Off‑network coverage yes, by design only while the profile persists (they can remove it)

Guidance: default guests to mobileconfig (keyless, removable, network‑scoped). Reserve the Connect thick client for managed devices. If a guest opts into Connect, the portal issues a per‑device, revocable key after OTP — never the shared org key.


5. Admit webhook (Model A) — sample payload + NAC recipes

Section titled “5. Admit webhook (Model A) — sample payload + NAC recipes”

On enrollment, AgentWatch POSTs to your configured admitWebhookUrl:

POST https://your-nac-bridge.example/agentwatch/admit
Content-Type: application/json
X-AgentWatch-Signature: sha256=<hmac-sha256(body, admitWebhookSecret)>
{ "event": "device.admit", "org": "example", "deviceKey": "<hash>",
"framedIp": "10.20.30.40", "action": "coa-reauthorize", "at": 1699999999999 }

Verify the HMAC, then move the device to “authorized.” Sample bridge → RADIUS CoA (FreeRADIUS radclient):

Terminal window
# /agentwatch/admit receiver (pseudo): verify HMAC, then:
echo "Framed-IP-Address=$framedIp,Acct-Session-Id=$sid" \
| radclient -x <nas-ip>:3799 coa "$COA_SECRET"

Controller API alternatives: Meraki POST /networks/{id}/clients/{mac}/policy (allowed); Aruba ClearPass POST /api/session/{id}/disconnect + re‑auth; UniFi cmd/stamgr authorize-guest; Cisco ISE CoA via pxGrid. Set admitWebhookUrl + admitWebhookSecret in Admin → Enrollment Portal.


6. Inline gateway (Model C) — Docker, with/without HAProxy

Section titled “6. Inline gateway (Model C) — Docker, with/without HAProxy”

You keep your existing router/default gateway. AI traffic is steered to AgentWatch (via DNS §3‑B, a PAC/system‑proxy, or the Connect client); AgentWatch inspects and forwards to the real AI service (transparent relay — it never blackholes, and non‑AI traffic isn’t sent to it at all). “Inline” = in the HTTP path, not the L3 path.

  • With an HAProxy frontend (recommended): HAProxy terminates TLS on :443 and routes by SNI to the AgentWatch container. Ships as dns-server/haproxy-mitm.cfg.example. Good for SNI‑passthrough (metadata only, no CA) and full MITM (with CA).
  • Without HAProxy: the AgentWatch container listens on :443 directly (single‑host). Simpler; fewer moving parts.
  • What happens to their existing gateway: unchanged — it remains the L3 default route. AgentWatch is upstream of the AI destinations only, and egresses to those destinations itself. Metadata‑only mode needs no CA; content inspection needs the CA (MDM/portal).
# minimal inline (no HAProxy): AgentWatch on 443. Steered AI traffic is relayed
# to the real upstream automatically (transparent relay); non-AI traffic is never
# routed here. Content inspection turns on once the CA is trusted on endpoints.
services:
agentwatch:
image: iterateai/agentwatch:latest
ports: ["443:8787"]

7. Bulk MDM rollout — zero‑touch for the whole fleet

Section titled “7. Bulk MDM rollout — zero‑touch for the whole fleet”

Two artifacts, from two different admin pages, both pushed via your MDM (JumpCloud / Intune / Jamf). Employees never configure anything and never see a prompt.

Artifact Downloaded from Purpose
.mobileconfig (root CA + DoH) Admin → DNS Redirector → Download .mobileconfig Trusts the AgentWatch root CA and points device DNS at your resolver. Governs browser AI traffic; enables content inspection on the steered AI domains. This is the only artifact iOS/Android need.
Connect installer (.dmg / .msi / .bin) Admin → Agent Fleet → Download The thick MITM client for macOS / Windows / Linux desktops — full traffic capture beyond the browser.
  1. Push the .mobileconfig FIRST — to ALL devices. Admin → DNS Redirector → Download .mobileconfig. It carries the root CA + DoH/DNS steering (the server domain is taken from your browser’s address bar). Pushing it first means CA trust + DNS steering are already in place when the thick client lands — and it alone brings browser AI traffic under governance everywhere, including mobile.

  2. Then download the per‑OS Connect installer from Agent Fleet and push per‑OS to the matching desktop groups — .dmg → macOS, .msi → Windows, .bin/.deb → Linux. One installer per OS group.

  3. The thick client auto‑configures on install. It reads its MDM‑pushed managed config from the OS policy store your MDM writes — the same keys on every OS:

    OS Where Connect reads it Who can write it
    macOS managed‑preferences payload ai.iterate.agentwatch-connect → /Library/Managed Preferences/ai.iterate.agentwatch-connect.plist the MDM only
    Windows HKLM\SOFTWARE\Policies\AgentWatch\Connect (REG_SZ values) administrators / SYSTEM
    Linux /etc/agentwatch/connect.json root — the file is ignored unless it is owned by root and not group/world‑writable
    Key Value
    ServerURL your AgentWatch address, e.g. https://agentwatch.acme.com
    EnrollmentToken Agent Fleet → Agent Connect Settings → Enrollment Token (log in as the tenant’s admin)
    Email the MDM’s per‑user variable (Intune {{mail}} / Jamf $EMAIL) — optional, see §7e
    EmailDomain optional: acme.com, used when Email is not available

    With the managed config present + the CA already trusted (step 1), the client auto‑enables interception on install — silent, installed as a login/service agent, no reboot (it starts on install or next login), no “unknown author” prompt. Older devices configured under HKLM\SOFTWARE\Policies\Iterate\AgentWatchConnect or /etc/agentwatch-connect/managed.json keep working; new rollouts should use the paths above.

Phones/tablets can’t run the Connect app — for them the DNS Redirector .mobileconfig alone (or the Android managed‑config equivalent) is enough. It steers DNS + trusts the CA, so you get browser AI traffic governed (domain/URL metadata; content for the AI domains steered to the gateway). Native apps on mobile aren’t intercepted — expected for the profile‑only path.

7c. What the Connect tray shows: managed vs. manual

Section titled “7c. What the Connect tray shows: managed vs. manual”
  • Installed via MDM (managed): the tray is locked to a minimal view — Requests Proxied, Uptime, the version number, and “🔒 Managed by your organization.” The Edit button, Server / User / Hosts Redirect rows, Show details, Enable Interception, and Check for Updates are all hidden — the config is enforced by your MDM and interception auto‑starts.
  • Installed manually (an employee ran the installer themselves): the tray shows the full interactive view — Edit config, Enable/Disable interception, Show details, Check for Updates — exactly as today.

7d. Rotating the fleet key (e.g. suspected compromise)

Section titled “7d. Rotating the fleet key (e.g. suspected compromise)”

The apiKey lives in the thick client’s MDM managed config (§7a step 3), not in the .mobileconfig. To rotate: renew the org gateway key in AgentWatch (Admin → API Key Management → renew, which invalidates the old key) → update the apiKey value in your MDM’s managed‑config payload → re‑push it. The policy store updates silently and the client picks up the new key on its next config read — no employee action. (For a smaller blast radius, issue per‑device keys so a compromise is one device, not the fleet.)

7e. How each computer is tied to ONE employee

Section titled “7e. How each computer is tied to ONE employee”

The enrollment token is the same for the whole organization — it proves a computer belongs to your tenant, not which person uses it. Connect works out the person in this order, identically on macOS, Windows and Linux:

  1. Email from the MDM, when the MDM substituted a real address. A value still reading $EMAIL or {{mail}} is ignored, never sent.
  2. The signed‑in user’s directory identity — on a domain‑ or Entra‑joined Windows PC, the user’s UPN (jdoe@acme.com).
  3. <login name>@<EmailDomain> — only if you set EmailDomain. Connect never guesses a domain.
  4. A sign‑in approval when none of the above gives a provisioned employee, or when your organization requires it (below).

In every case the email must belong to an employee who already exists in AgentWatch (SCIM, CSV import or Employee Management → Add); an unknown email is refused and the computer falls back to step 4. The computer always receives that employee’s own key, so everything it sends is attributed to them.

Sign‑in approval. The computer shows a short code (KQ7M‑3XTP) in the Connect tray and opens a page in the default browser. The employee signs in with your normal sign‑in — SSO, LDAP or password, whatever your workspace uses — checks that the code and computer name match, and clicks Approve. The computer is enrolled as whoever signed in, so the identity no longer depends on anything the computer says about itself. If the approval page is opened from a different network than the computer, the employee must type the code rather than click a link, so a forwarded link cannot enroll someone else’s machine. On a Linux server with no display, the link and code are printed in the log (or run agentwatch-connect enroll --server <url> --token <token> in a terminal) and can be approved from any device.

Require it for everyone: Agent Fleet → Agent Connect Settings → Require sign‑in to approve each computer. With it on, the token plus a self‑reported email is no longer accepted — every computer is approved by a sign‑in, once. It is off by default, so turning it on is a decision rather than an upgrade surprise. Existing enrolled computers are unaffected. Every enrollment, by either path, is recorded in Settings → Audit Logs as agent.device_enrolled (and agent.device_enroll_denied when someone clicks This wasn’t me).

JumpCloud, per OS:

OS How to push the managed config
macOS Device Management → MDM → Custom Configuration Profile: upload the .mobileconfig from DNS Redirector → Download .mobileconfig (it already carries ServerURL + EnrollmentToken), or your own profile with payload type ai.iterate.agentwatch-connect.
Windows Policy Management → Windows → Custom Registry Keys: HKEY_LOCAL_MACHINE\SOFTWARE\Policies\AgentWatch\Connect, String values ServerURL, EnrollmentToken, and EmailDomain (or Email).
Linux Commands (runs as root): write /etc/agentwatch/connect.json with {"ServerURL": "…", "EnrollmentToken": "…", "EmailDomain": "acme.com"}, then chmod 644 it.

Whether JumpCloud substitutes a per‑user variable into a custom profile or a registry value depends on your JumpCloud configuration — verify on one device. If it does not, leave Email out: with EmailDomain set, Connect uses the signed‑in user’s login name, and anything that does not match an employee goes to sign‑in approval.

Symptom Cause Fix
Tray says Not Configured no managed config at the path above, or (Linux) the file is not root‑owned check the path for your OS; sudo chown root:root /etc/agentwatch/connect.json && sudo chmod 644 …
Tray says Waiting for approval Connect needs a sign‑in (no usable email, the email is not an employee, or sign‑in is required) the employee signs in on the page that opened; Open sign‑in page in the tray reopens it
Approval page: set up for a different organization the computer’s token belongs to another tenant than the signed‑in account push the token of the employee’s own tenant
Approval page: no AgentWatch gateway access the signed‑in account is not an employee (e.g. an admin login with no gateway key) add them in Employee Management
identity_not_provisioned in the Connect log the email is not an employee provision them, or let sign‑in approval resolve it

  • Without the CA (visibility‑only): destinations (which AI service, via DNS/SNI), volume, timing — per‑person once an identity signal is attached. No prompt/response content.
  • With the CA (content governance): full prompts/responses, DLP redaction/blocking, per‑message audit.

Run visibility‑first, then enable content inspection (DLP) when ready — all per‑tenant policy, flipped without redeploy.


© Iterate.ai · AgentWatch · Dream big, build fast.