Endpoint Agent · Step 4 of 7

Validate the Installation

Confirm two things: the agent installed correctly, and it is actively intercepting traffic. Each platform has five sequential checks — a failed check halts progression until you resolve it.

Console-side validation — the fastest check

If the agent successfully phoned home, the device shows up in the Quilr Console within seconds. Open Settings → Endpoint in your tenant Console and switch to the Deployment Status tab. Type the device’s hostname or the user’s email in the search box.

ColumnHealthy valueIf it’s wrong …
DeviceHostname matches the machine you installed on, with a UUID belowMissing → agent never reached discover.quilrai.dev. Check the Step 6 allow-list & AV exclusion.
Email AddressThe signed-in user’s emailEmpty → email-discovery hasn’t resolved a persona; sign the user into the Quilr Console once.
Full NameResolved from the IdPEmpty → same as Email; persona unresolved.
OSDetected platform (e.g. Windows 11 Pro / Mac OS X:26_5_1)Wrong build → the agent reported a different OS than expected; usually just stale telemetry, rerun after a reboot.
StatusEnabledDisabled → the agent service is stopped. Restart it (Windows: Start-Service QuilrAIAgent, macOS: sudo launchctl kickstart system/ai.quilr.sentinel).
VersionMatches “Latest Endpoint Version” banner top-rightStale → redeploy or wait for the next auto-update.
Installed OnToday’s dateOlder → the new install didn’t register a new device row; reinstall didn’t replace the prior install.
Last Seen“a few minutes ago” / “just now”> 1 hour → agent process stopped or device offline. Tail agent.log for the last heartbeat error.
Quilr Console - Settings - Endpoint - Deployment Status tab. Three devices listed: GURMUKH-LAPTOP (Windows 11) and Gurmukhnishans-MacBook.local (Mac OS X:26_5_1) registered to gsingh@quilr.ai with status Enabled and version 1.0.48, and Gurmukh-Windows-Laptop with version 1.0.0, all showing 'Enabled' status with Last Seen times '10 hours ago', '1 day ago', '3 weeks ago'.
Console — Settings → Endpoint → Deployment Status. The test device shows up with Status = Enabled, current version, and a fresh Last Seen.
If the row looks like the screenshot above The agent is already on the backplane — the five on-device checks below are useful for understanding how it’s intercepting, but the install itself is confirmed. If the row is missing or yellow / red, run the checks and Step 6 to find the broken link.
🧭
Run checks in order Don’t skip ahead. If Check 3 (CA chain) fails, the functional test cannot pass — fix the earlier check first.

Run all commands in Terminal with sudo rights.

1

Binaries installed

bash
ls -ld /Applications/QuilrAIProxy.app && \
ls -ld "/Library/Application Support/QuilrAI" && \
defaults read /Applications/QuilrAIProxy.app/Contents/Info.plist CFBundleShortVersionString
Expected: both directories exist; a version string prints (e.g. 2026.05.08).

If this check fails — inspect the pkg install log:

LogPath
Quilr installer trace/Library/Application Support/Sentinel/logs/sentinel-endpoint.log
macOS installer subsystem/var/log/install.log (filter with grep -i quilr)
bash · sudo
sudo tail -n 200 /Library/Application\ Support/Sentinel/logs/sentinel-endpoint.log 2>/dev/null
sudo grep -i 'quilr\|sentinel' /var/log/install.log | tail -n 100

Most pkg failures are codesign / notarization mismatches or insufficient disk space.

2

Daemons running

bash · sudo
pgrep -lf 'quilrai|quilrai-proxy'
sudo launchctl print system/ai.quilr.sentinel       | grep -E 'state =|last exit'
sudo launchctl print system/ai.quilr.quilrai-proxy  | grep -E 'state =|last exit'
Expected: at least two PIDs; state = running on both daemons; last exit code = 0.
3

CA chain in System keychain

bash
COUNT=$(security find-certificate -a /Library/Keychains/System.keychain | grep -ci quilr)
echo "Quilr certs in System keychain: $COUNT (expect: 2)"
Expected: exactly 2 (root + intermediate).
4

Network Extension activated

bash
systemextensionsctl list | grep -i quilr
Expected: a line containing [activated enabled] — not waiting or absent.
5

Full Disk Access granted via MDM

bash · sudo
sudo sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" \
"select client, allowed, auth_reason from access \
where service='kTCCServiceSystemPolicyAllFiles' and client like '%quilr%';"
Expected: at least one row with allowed=1 and auth_reason=4 (MDM grant).

Run all commands in PowerShell as Administrator.

1

MSI installed

PowerShell
Get-ChildItem `
  HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*, `
  HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
Get-ItemProperty | Where-Object DisplayName -like '*Quilr*' |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate

Get-Item "$env:ProgramFiles\QuilrAI" | Select-Object FullName, LastWriteTime
Expected: Quilr Endpoint Agent listed with a version and Publisher = Quilr AI; the install folder exists.

If this check fails — inspect the MSI install log:

When the MSI was run byLog path
Signed-in user (interactive install)C:\Users\<USER>\AppData\Local\Temp\sentinel-msi-install.log
SYSTEM (MDM-pushed — Intune Win32 / ManageEngine / GPO)C:\Windows\Temp\sentinel-msi-install.log

Probe both locations from a shell and tail whichever exists:

PowerShell
foreach ($p in @(
  "$env:TEMP\sentinel-msi-install.log",
  "C:\Windows\Temp\sentinel-msi-install.log",
  "C:\Users\$env:USERNAME\AppData\Local\Temp\sentinel-msi-install.log"
)) {
  if (Test-Path $p) { "==> $p"; Get-Content $p -Tail 200; break }
}

For the rollback equivalent, replace sentinel-msi-install.log with sentinel-msi-uninstall.log.

2

Windows service running

PowerShell
Get-Service | Where-Object { $_.Name -match 'quilrai|quilr' } |
Select-Object Name, Status, StartType
Expected: Status = Running and StartType = Automatic.
3

WinDivert driver registered

PowerShell (admin)
sc query WinDivert
Expected: SERVICE_NAME: WinDivert · STATE : 4  RUNNING. "The specified service does not exist as an installed service" = MSI did not register the driver — see Step 6 § Known issues.
4

CA chain in Local Machine trust store

PowerShell
certutil -store Root | Select-String -Pattern 'Quilr' -SimpleMatch
certutil -store CA   | Select-String -Pattern 'Quilr' -SimpleMatch
Expected: Quilr root in the Root store and Quilr intermediate in the CA (Intermediate) store.

Critical log locations (Windows)

If any of the four checks above fails, the relevant log is here. Tail the matching file and search for ERROR / FATAL / the MSI return code first.

ComponentPathPurpose
Agent runtime (all services)%PROGRAMDATA%\quilrai\logs\Root directory for every sentinel-service trace (proxy, templating engine, broker)
Proxy daemon (runtime)%PROGRAMDATA%\quilrai\logs\proxy.log.YYYY-MM-DDDLP engine, TLS interception, flow.matched events — daily-rotating
Templating engine (runtime)%PROGRAMDATA%\quilrai\logs\templating-engine.log.YYYY-MM-DDDLP alert popups — daily-rotating
IPC broker (runtime)%PROGRAMDATA%\quilrai\logs\agent.stderr.log  (also agent.stdout.log)Lifecycle, init, heartbeat, inter-process broker traffic
MSI install — interactive (signed-in user)%TEMP%\sentinel-msi-install.logMSI verbose trace when the user double-clicked / msiexec'd
MSI install — SYSTEM (MDM-pushed)C:\Windows\Temp\sentinel-msi-install.logSame trace when Intune Win32 / ManageEngine / GPO ran the MSI as LocalSystem
MSI uninstall / rollback%TEMP%\sentinel-msi-uninstall.log  or  C:\Windows\Temp\sentinel-msi-uninstall.logRollback / uninstall verbose trace
Intune Management Extension%PROGRAMDATA%\Microsoft\IntuneManagementExtension\Logs\IntuneManagementExtension.logWin32 download · hash check · install orchestration (Intune-only)
Windows Event Log — SystemGet-WinEvent -LogName System | ? { $_.ProviderName -match 'WinDivert' } | Select -First 50WinDivert kernel-driver load / registration failures (elevated)
Windows Event Log — ApplicationGet-WinEvent -LogName Application | ? { $_.ProviderName -match 'Quilr' } | Select -First 50User-mode service crashes · uncaught exceptions surfaced to WER

Templating-engine / broker filenames mirror the macOS layout; if a file is missing on a given build, confirm the exact name with Quilr support before escalating.

Install folder layout (Windows)

Reference tree of what a healthy install puts on disk. Use to spot missing binaries (failed MSI custom action) or rogue extras (tampering).

%ProgramFiles%\QuilrAI\ — install root

tree /F
C:.
│   bootstrap.exe
│   cert.pem
│   dlp_content_extractor.json
│   email-discovery.exe
│   h2_disable_hosts.txt
│   ipc-light-broker.exe
│   key.pem
│   quilrai-diagnostics.exe
│   quilrai-endpoint.exe
│   quilrai-monitor-v2.exe
│   quilrai-proxy.exe
│   quilrai.exe
│   root.pem
│   template-engine.exe
│   templating-engine.exe
│   WinDivert.dll
│   WinDivert.lib
│   WinDivert64.sys
│
├───configs
│       oauth_config.json
│       redirector_config.toml
│
├───hooks
│   │   quilrai-claude-hook-client.exe
│   │   quilrai-codex-hook-client.exe
│   │   quilrai-copilotcli-hook-client.exe
│   │   quilrai-hook-client.exe
│   │
│   └───scripts
│       │   claude_code.lua
│       │   codex.lua
│       │   copilot.lua
│       │   cursor.lua
│       │   kiro.lua
│       │   lmstudio.lua
│       │   manifest.json
│       │   nemoclaw.lua
│       │   ollama.lua
│       │
│       └───lib
│               frontmatter.lua
│               mcp.lua
│               path.lua
│               risk.lua
│
├───icons
│       icon.ico
│       icon.png
│
├───installer
│       brand.json
│       certs-bundle.zip
│       install-launcher.exe
│       quilrai-tray.exe
│       uninstall-launcher.exe
│       update-launcher.exe
│       vc_redist.x64.exe
│
└───templates
    │   alert.html
    │   block.html
    │   index.html
    │   notification.html
    │   prompt.html
    │
    └───app-discovery
            alert.html
            block.html
            notification.html

Reproduce with: tree /F /A "%ProgramFiles%\QuilrAI"

%HOMEPATH%\.quilrai\ — per-user hooks · scripts · state

tree /F
C:.
│   quilrai-claude-hook-client.exe
│   quilrai-codex-hook-client.exe
│   quilrai-copilotcli-hook-client.exe
│   quilrai-hook-client.exe
│
├───logs
│       monitor.log.2026-06-14
│
├───scripts
│   │   claude_code.lua
│   │   codex.lua
│   │   copilot.lua
│   │   cursor.lua
│   │   kiro.lua
│   │   lmstudio.lua
│   │   manifest.json
│   │   nemoclaw.lua
│   │   ollama.lua
│   │
│   └───lib
│           frontmatter.lua
│           mcp.lua
│           path.lua
│           risk.lua
│
└───v2
        snapshot.json
        tenant-policy.json

Reproduce with: tree /F /A "%HOMEPATH%\.quilrai" · monitor.log.YYYY-MM-DD is the per-user agent-monitor trace (daily-rotating). The v2\ folder caches the tenant policy snapshot.

Functional test — claude.ai interception

This proves the agent is actively decrypting and matching AI traffic in real time.

bash · sudo
sudo log stream --predicate 'subsystem == "ai.quilr.endpoint"' --info \
| grep -iE 'matched|intercepted|claude'

Then open https://claude.ai in Safari or Firefox and send a prompt.

Expected: a flow.matched … claude.ai line appears within ~2 seconds; no certificate warning; Claude responds normally.
PowerShell
Get-Content "$env:PROGRAMDATA\quilrai\logs\proxy.log.*" -Tail 0 -Wait |
Select-String -Pattern 'matched|claude' -SimpleMatch

Open https://claude.ai in Firefox and send a prompt.

Expected: a matched … claude.ai line in the log within ~2 seconds.

Certificate-chain verification

Confirm the TLS issuer is rewritten to Quilr’s CA — the definitive proof of interception.

bash
openssl s_client -connect claude.ai:443 -servername claude.ai </dev/null 2>/dev/null \
| openssl x509 -noout -issuer
PowerShell 7+
$tcp = New-Object Net.Sockets.TcpClient('claude.ai', 443)
$ssl = New-Object Net.Security.SslStream($tcp.GetStream())
$ssl.AuthenticateAsClient('claude.ai')
$ssl.RemoteCertificate.Issuer
🔎
How to read the result If the issuer shows a real CA (WE1, Let’s Encrypt, DigiCert, Cloudflare), traffic is reaching the origin un-intercepted — and if it shows your SWG, that host needs to be on the SWG’s SSL-bypass list. When the Quilr agent is working, a browser padlock → certificate details will show Issued By: Quilr CA.

Browser padlock check

  • Chrome / Edge: padlock → Connection is secureCertificate is valid → Details
  • Safari: padlock → Show Certificate
  • Firefox: padlock → arrow → More informationView Certificate

Leaf certificate Issued By = Quilr CA confirms active interception. If it shows Anthropic’s real CA, the agent is not intercepting that browser’s flow.

Desktop-app DLP test — verify the agent intercepts native AI apps

The proxy + WinDivert / Network Extension stack should intercept TLS traffic from both browsers and native desktop AI apps (Claude Desktop, ChatGPT Desktop, Cursor, GitHub Copilot, …). This test confirms the desktop side with a synthetic-PII payload and the Quilr Security Alert popup.

1 — Confirm Guardrails are ON for the target apps

Open Settings → Endpoint → Detection configurations in the Quilr Console. The header should read “X/X active” (all detection configs enabled). For every app row you intend to test, confirm each category (Chat / File Upload / Codex / …) shows the green GUARDRAILS ON pill.

Quilr Console - Settings - Endpoint - Detection configurations tab. Header reads '27/27 active' next to a search box. Endpoint Applications section lists 12 apps including ChatGPT (4 types configured, NO DESKTOP APP MONITORING, BROWSER MONITORING AVAILABLE, 4/4 ACTIVE; categories Chat, File Upload, Chat (Anonymous), Codex; Chat row shows GUARDRAILS ON, 7 MONITOR / 11 NOT MONITORED, BROWSERS 13/13), Claude (3 types configured, DESKTOP APP MONITORED, BROWSER MONITORING AVAILABLE, 3/3 ACTIVE; categories Chat, Claude Code Desktop, File Upload Desktop; Chat shows GUARDRAILS ON / 7 JUSTIFY), Cursor (2 types, Chat + File Upload, GUARDRAILS ON / 7 MONITOR), GitHub Copilot (1 type configured). Each app row has 'Guardrails' and 'Monitored Browsers' buttons on the right.
Console — Settings → Endpoint → Detection configurations. The endpoint agent intercepts only when Guardrails are ON for that app + category.
Wait ~90 seconds after toggling Detection-config changes propagate to the agent on the next policy sync. Wait at least 90 seconds after enabling a Guardrail before testing — otherwise the agent will still pass the prompt through.
Pill / columnWhat it means for this test
DESKTOP APP MONITOREDThe agent will hook the native app’s TLS traffic. Required for desktop-app testing — if absent, the agent only sees browser traffic.
BROWSER MONITORING AVAILABLEThe Browser Extension can monitor this app in a browser tab. Not required for the desktop-app test.
GUARDRAILS ON (green)DLP runs against this category. GUARDRAILS OFF → agent sees the traffic but never raises a popup.
X/X ACTIVEEvery detection type is enabled. 2/4 active → only 2 of 4 categories on; check which is off.

2 — Submit synthetic PII through a native AI app

Pick any app that shows DESKTOP APP MONITORED + GUARDRAILS ON in step 1 (Claude Desktop is the easiest). Launch it on the pilot device, paste the same synthetic-PII block used on the Browser Extension side, and submit:

synthetic PII — test only
First and Last Name    SSN            Date of Birth
Robert Aragon          489-36-8350    6/7/1981
Ashley Borden          514-14-8905    7/8/1981
Thomas Conley          690-05-5315    8/9/1981
Susan Davis            421-37-1396    9/10/1981
Christopher Diaz       458-02-6124    1/10/1975
Rick Edwards           612-20-6833    2/11/1975
Victor Faulkner        300-62-3266    3/12/1975
Lisa Garrison          660-03-8360    4/13/1975
Marjorie Green         213-46-8915    5/14/1975
Mark Hall              449-48-3135    6/14/1975
James Heard            559-81-1301    7/16/1975
Albert Iorio           322-84-2281    8/17/1975
Charles Jackson        646-44-9061    9/18/1975
Teresa Kaminski        465-73-5022    10/19/1975
Tim Lowe               044-34-6954    1/20/1991
Monte Mceachern        477-12-8344    2/21/1991

(Same publicly-circulated synthetic-PII test list from BE Step 4 Test 3; do not use real personal data.)

3 — What you should see

Expected: a native OS window titled “Quilr | Security Alert” appears before the prompt leaves the app, with title “Potentially Sensitive Data Detected.”, the PERSONALLY IDENTIFIABLE INFORMATION (PII) tag, the matched rows underlined in red, and a Reason for bypassing dropdown the user must pick before they can click Continue with Original. The popup is rendered by the templating-engine subprocess (see Step 6 critical-logs · templating-engine.log).
Quilr Endpoint Agent native popup. Window title 'Quilr | Security Alert' (blue chrome). Body title 'Potentially Sensitive Data Detected.' in yellow, subtitle 'Please review content before submitting to external website.', tag 'PERSONALLY IDENTIFIABLE INFORMATION (PII)', 'Highlight Sensitive Data' button, the synthetic-PII payload table (Robert Aragon, Ashley Borden, Thomas Conley, ...) with the SSN columns and dates underlined in red. A 'Reason for bypassing:' dropdown labelled 'Select a justification...' sits below. Footer reads 'Stay safe, Quilr it!' and a green-outlined 'Continue with Original' button is in the bottom-right.
What a successful EA desktop-app block looks like — native OS window, PII tag, red-underlined matches, and a mandatory Reason for bypassing dropdown before the user can override.
📝
Bypass requires a justification The EA popup’s Continue with Original is gated behind a non-optional dropdown. The justification value is captured in the finding under bypass_reason — useful for audit. The BE popup is more lenient (free-form override); EA is stricter by design because the OS-level interception is harder to bypass than a browser tab.

4 — Confirm a Finding was generated in the Console

Open Findings, switch to the Endpoint Agent Findings tab, and filter by the test user. A new finding should land within ~2 seconds with:

FieldHealthy valueIf it’s wrong …
Sourceendpoint agent (not browser extension)Wrong source → the BE caught it first; close the AI site in the browser and retry on the desktop app.
AppThe native app you used (e.g. Claude Desktop, Cursor, GitHub Copilot)Listed as unknown → the app isn’t in Detection configurations, or DESKTOP APP MONITORED is off.
EventPrompt (or File Upload if the app supports attaching files)Different event → the agent classified it as a different category.
bypass_reasonEmpty if the user closed the popup; the justification string if they clicked Continue with Original
Device NameThe pilot device hostname (matches the row in Deployment Status)Different hostname → a different device fired this; isolate.
If the popup didn’t fireWhere to look
Console shows DESKTOP APP MONITORED on this app but GUARDRAILS are offToggle on, wait 90 s, retry.
Console shows NO DESKTOP APP MONITORING for this appPick a different app from the list (the screenshot in step 1 shows which qualify), or have Quilr support enable desktop-app monitoring for the requested app.
Popup appears in a browser but not in the desktop appThe Browser Extension intercepted first. Close the AI site in every browser tab during the desktop-app test, OR uninstall the BE to isolate the EA path.
No popup anywhere; agent logs show TLS handshake failed against the AI hostThe Quilr CA isn’t trusted by the desktop app’s embedded TLS stack (some Electron apps ship their own root store). See Step 6 § TLS handshake failure.
Popup fires but no Finding in ConsoleTail proxy.log for Forward failed — the local intercept worked but the upload to the backplane choked. See Step 6 § Forward failed.
Exit criteria for Step 4 All five platform checks green · functional matched … claude.ai event observed · padlock shows the Quilr CA. The device is fully protected. For fleet rollout, continue to Step 5.