For the complete documentation index, see llms.txt. This page is also available as Markdown.

Agentic AI Policy Workload Reduction

Keeper Endpoint Privilege Manager (EPM) is billed by the number of workloads evaluated per endpoint. Every process launch, file access, elevation request, and background check that reaches the agent counts as a workload, so an endpoint running unusually noisy applications will consume disproportionately more workloads than one running the same policies against well-behaved software.

The most effective way to reduce workload consumption without weakening policy coverage is to quiet the applications themselves. Many common developer, productivity, and background tools poll the filesystem, refresh caches, or run periodic housekeeping far more aggressively than they need to; adjusting each application's own settings to reduce that unnecessary activity cuts workloads at the source, before they ever reach EPM for evaluation.

The recommendation below identifies a specific application with known noisy defaults and shows how to centrally deploy the settings changes that reduce its workload footprint across a managed fleet.


Recommendation: Deploy Cursor Polling Settings via a JobUpdate Policy (macOS)

Symptom

macOS endpoints running the Cursor IDE (and, by extension, VS Code, which shares Cursor's Git and search machinery) produce a continuous stream of git and rg (ripgrep) process launches even when the user is idle. On a host running the EPM System Extension, every one of these process spawns is intercepted for policy evaluation, which:

  • Drives up workload counts per endpoint (and therefore billed usage).

  • Adds sustained CPU and disk load on the endpoint.

  • Floods the audit and policy pipeline with low-value process-exec events.

  • Under load, can contribute to KEEPER_POLICY_EXEC_TIMEOUT fail-open behavior.

Why It Happens

Cursor's defaults are optimized for interactive responsiveness in small repos, not for quiet operation on managed endpoints. Out of the box, Cursor:

  • Runs Git auto-fetch and auto-refresh on a short interval (roughly once per second by default).

  • Auto-detects repositories and recursively scans the workspace for .git directories.

  • Uses ripgrep for global search and Quick Open, walking the entire workspace unless directories are excluded.

  • Watches the entire workspace via filesystem watchers, including node_modules, build output directories, and .git internals.

Each git/rg invocation is a distinct process launch that the EPM System Extension must evaluate against policy. In large repositories or monorepos this activity is effectively continuous.

Fix: Push Quiet Settings to Every User via a JobUpdate Policy

Rather than asking every developer to hand-edit their own settings.json, deploy a single JobUpdate policy that installs a scheduled job on managed macOS endpoints. The job runs as the EPM service (root), enumerates every user home under /Users, and writes the recommended settings into each user's ~/Library/Application Support/Cursor/User/settings.json.

The settings the job applies are:

json

Effect on workload volume:

  • Git: no auto-fetch, no auto-refresh, no auto repository detection, and repository scan depth is 0 — no recursive workspace scanning. This eliminates the steady one-per-second git invocation baseline.

  • Search (ripgrep): honors .gitignore files at every level, does not follow symlinks, and skips node_modules, dist, build, and .git. Global search and Quick Open no longer traverse these heavy directories.

  • File watcher: excludes the same directories from the workspace watcher, preventing constant re-indexing when build tools or git write into them.

Policy JSON

Paste this into the Admin Console. The outer fields scope and trigger the installation; the inner Extension.JobJson is the job definition. The ConfigurationPolicyProcessor reads Extension.JobJson and saves it through the blessed SaveJobToDiskAndLkg path, which updates both disk and the Last Known Good copy — so the LKG watcher will not revert it.

json

Key fields to review before deploying:

  • PolicyType: "JobUpdate" — marks this as a job-installation policy. The ConfigurationPolicyProcessor reads Extension and installs the job.

  • Extension.Action: "Add" — installs or updates the job ("Add" upserts; use "Remove" to uninstall).

  • Extension.JobId — must match JobJson.id (configure-cursor-polling).

  • Status — set to "enforce" to activate; "monitor" only logs.

  • MachineCheck — replace O_w7iACgy53mAwPlniSz4w with your target machine id(s), or use ["*"] to apply to all machines.

  • schedule.intervalMinutes: 30 — production value. Test policies may use 1 for fast verification; revert to 30 (or higher) before rolling out broadly.

  • Trigger — the job runs on both the PolicyPreprocessingCompleted custom event and the schedule interval, so newly-installed endpoints get their first apply as soon as policy preprocessing completes.

Do not deploy by editing /Library/Keeper/sbin/Jobs/configure-cursor-polling.json directly. The ConfigurationLkgReconciliation filesystem watcher reverts manual edits (JOB_WATCHER_RESTORE). The Admin Console's JobUpdate policy is the only supported path.

User Coverage: Local, AD Mobile, and Network Homes

The /Users/*/ glob covers every home directory mounted under /Users, which on macOS includes:

  • Local users — e.g. /Users/test, /Users/jsmith.

  • Active Directory mobile accounts — the AD plug-in creates mobile account homes under /Users/<aduser>. These are local cached homes, so writes are fast and reliable.

  • Network home directories — NFS/AFP homes mounted under /Users/<networkuser> are matched by the glob; writes traverse the network to the home server.

The Shared directory is intentionally skipped. Because the job runs as root, file permissions on user homes do not block writes for any user type. Homes mounted outside /Users (e.g. /Volumes/homes/<user>) are not covered by the default glob — extend the glob if your environment uses non-standard home roots.

Escaping Pitfall

The task inlines a bash script via /bin/bash -c "<script>". The Application Support path contains a space, which must survive three layers of parsing: JSON, .NET's Process.Start argument tokenizer, and bash. The correct JSON uses two backslashes for each Application Support occurrence:

  • Application\\ Support (2 backslashes in JSON) → 1 backslash in the args string → bash treats the space as escaped → one word → works.

  • Application\\\\ Support (4 backslashes) → 2 backslashes in the args string → bash interprets \\ as an escaped backslash, leaving the space unescaped → word-split → the echo > redirect targets a directory → Is a directory → exit 1.

Both occurrences (the mkdir path and the echo > redirect path) must use two backslashes.

Verification

  • A successful run leaves a fresh ~/Library/Application Support/Cursor/User/settings.json (root-owned, ~477 bytes) in every non-Shared user home. TASK_COMPLETE and JOB_EXECUTION_COMPLETE for a success are logged at Debug/Info and are filtered out when system.logging.level is Warning.

  • A failed run produces [WRN] [JobExecutor] [JOB_STOPPED] ... Task 'run-config' failed and [WRN] [JobService] [JOB_EXECUTION_COMPLETE] ... Success: False at Warning level — these are visible by default.

  • To see the explicit ExitCode=0 line, temporarily set system.logging.level to Debug in /Library/Keeper/sbin/appsettings.json and restart the agent (keepersudo launchctl kickstart -k system/com.keeper.endpoint-privilege-manager.launcher), then revert to Warning after verifying.

Caveats

  • Overwrites settings.json entirely. The task uses echo > settings.json, which replaces the whole file. Any user customizations in Cursor settings are lost on each run. A merge-based approach (read existing JSON, merge the polling keys, write back) would preserve user customizations and is a planned enhancement.

  • Idempotency. The job is idempotent for the polling settings (re-writing the same JSON), but destructive to any other keys the user has set (see above).

  • Network home performance. Writes to NFS/AFP homes traverse the network; on slow links the task may approach the 60-second timeout. Consider narrowing the glob to exclude slow or unreachable network home roots if timeouts occur.

  • Non-/Users home roots. Not covered by default; extend the glob (e.g. /Users/*/ /Volumes/homes/*/) if your environment uses custom home paths.

Last updated

Was this helpful?