How this started
A few hours ago I scrolled past Cursor's own post. It said they're introducing the Cursor SDK so you can build agents with the same runtime, harness, and models that power Cursor - CI/CD, end-to-end automations, agents embedded in products. The post also named several companies as examples.
My brain did the thing every tired developer does: same runtime -> I'll read the code -> I'll see how sandboxing works.
Official announcement: Cursor on LinkedIn
Spoiler: the SDK is on npm. What ships isn't human-readable application source laid out for audit - it's compiled bundles (still plain text on disk, not intended for line-by-line inspection of logic).
What I expected vs what I got
| Expectation | Reality |
|---|---|
| Clone-adjacent transparency |
@cursor/sdk is compiled bundles (dist/cjs, dist/esm), not a source tree you can grep like your own repo - not intended for line-by-line inspection (nothing stops you opening the file; it's not the packaging intent) |
| "I'll verify security in the agent loop" | You verify your process boundary (user, container, network). The types hint at local.sandboxOptions.enabled - a boolean, not a full FS ACL |
| Open license vibes |
LICENSE.md is short and proprietary (Anysphere, tied to Terms of Service) |
No pitchforks - just alignment: proprietary code on my laptop is a contract, not a community repo. I'm fine with that when I choose it. I had simply mixed up "SDK on npm" with "something I can read like first-party source."
What actually sits in node_modules/@cursor
I pinned what I saw from @cursor/sdk@1.0.9 (public beta in package.json).
@cursor/sdk
-
Name / version:
@cursor/sdk1.0.9 - Description: TypeScript SDK for Cursor agents (public beta).
-
Entry:
main->./dist/cjs/index.js, ESM ->./dist/esm/index.js, types indist -
Exports:
"."and"./agent"both resolve to the same built entrypoints (soimport '@cursor/sdk/agent'isn't a second codebase - it's the same bundle, different export path) -
Runtime deps (what npm actually installs for consumers):
@bufbuild/protobuf,@connectrpc/connect,@connectrpc/connect-node,@statsig/js-client,sqlite3,zod -
Optional dependencies: platform packages that pull native-ish payloads -
@cursor/sdk-darwin-arm64,@cursor/sdk-darwin-x64,@cursor/sdk-linux-arm64,@cursor/sdk-linux-x64,@cursor/sdk-win32-x64(same version pin)
On disk it's still Connect RPC + protobuf + sqlite + zod + Statsig on paper - plus a large bundled index.js for each of CJS and ESM (~5 MB each in 1.0.9). Good for shipping; not packaged for comfortable line-by-line review of behavior (the bundle is readable; ergonomics aren't those of a source drop).
Connect RPC (Buf). Dependencies like @connectrpc/connect, @connectrpc/connect-node, and @bufbuild/protobuf point at Protobuf over HTTP - the stack Buf popularised as "typed RPC without reinventing REST." That doesn't reveal application logic, but it's a stack choice: typical patterns are generated contracts and fewer stringly-typed boundaries than ad hoc JSON.
Statsig. The tree includes @statsig/js-client (Statsig's own product category is feature flags and related tooling). I'm not going to guess what it does in this SDK at runtime; it's listed here so you can check Cursor's docs and your own network traces if that matters for your policy. More on treating unknown egress below.
@cursor/sdk-darwin-x64
Separate tiny package, same version 1.0.9:
- Description: Ripgrep binary for darwin-x64, bundled for @cursor/sdk.
-
Constraints:
os: ["darwin"],cpu: ["x64"] -
Ships:
bin/**/*(pluspackage.json/README)
So one "platform" slice is literally ripgrep for macOS x64 - a native binary inside npm. On Linux x64 the optional package is @cursor/sdk-linux-x64 with bin/rg - same pattern. That's normal for tooling; it's also another reminder that trust isn't abstract: you're executing vendor-supplied code and vendor-supplied binaries.
License (the one file I didn't need a source map for)
From LICENSE.md in the package:
© Anysphere Inc. All rights reserved. Use is subject to Cursor's Terms of Service.
Short. Clear. Not OSI-approved openness.
Security: still not "in the box"
The SDK types expose things like local.cwd (workspace) and local.sandboxOptions.enabled - useful switches, not a full policy engine. There is no fine-grained filesystem ACL in the public types (no per-path allow/deny lists, no separate read/write policies per tree). So enabled helps but is not enough without everything below.
Privacy, telemetry, and dependencies
If @statsig/js-client (or any other listed dependency) is a concern for air-gapped use, strict CI determinism, or third-party analytics policies, the practical step is the same as for any SDK: Cursor's docs / ToS, and validate egress in your environment (proxy, firewall logs, packet capture if your policy allows).
Egress allowlisting applies both to RPC/API/model traffic you already expect and to anything else the process might open - without assuming good or bad intent; just know what leaves the box.
Checklist: safe local use of @cursor/sdk
Treat the SDK as the driver; security comes from the OS, container, network, permissions, and your own guardrails (audit, approvals, limits).
Recommended baseline (any OS)
- Run the agent in an isolated environment (container, VM, or dedicated user).
- Use a dedicated workspace per task (
cwd), not your home directory or multi-project trees with secrets. - Set
local.sandboxOptions.enabled: truefor local agents. - Restrict outbound network (allowlist only what you need).
- Require human approval for risky actions (
delete, bulk writes, destructiveshell). - Log and audit prompts, tool calls, shell commands, and file changes.
- Apply timeouts and step/output limits to stop runaway runs.
- Pin dependencies, use lockfiles, and avoid arbitrary installs at runtime.
Filesystem
- One workspace directory per job; avoid pointing
cwdat trees that hold SSH keys, cloud creds, or personal data. - Prefer read-only mounts for source and a writable scratch for artifacts only.
- Run as a non-root / non-admin user dedicated to the agent.
- Block access to typical secret locations unless strictly required:
~/.ssh;~/.aws,~/.config/gcloud, similar cloud CLI dirs; password managers, browser profiles, credential stores.
Secrets and tokens
- Prefer short-lived credentials.
- Redact secrets in logs and artifacts.
- Avoid baking long-lived tokens into env unless necessary; rotate regularly.
Tools and automation risk
shell is usually the highest risk; write / delete are next. Apply least privilege: disable or gate tools you do not need, and require confirmation for destructive operations.
Network
- Use an egress allowlist (only package registries and APIs you actually use).
- Block access to internal RFC1918 ranges and cloud metadata endpoints unless required.
Audit and observability
Log at minimum: who / when / what prompt / which tools / which commands / what changed / outcome. Essential for incident review.
Supply chain
- Commit lockfiles; pin critical versions.
- Scan dependencies for known issues.
- Do not allow unrestricted
npm install/ package pulls inside the agent runtime without review.
Pre-flight
- [ ] Isolated runtime (user, container, or VM).
- [ ] Narrow
cwdto a dedicated workspace. - [ ] Sandbox on:
local.sandboxOptions.enabledfor local agent options, orsandboxOptionsoncreateLocalExecutor(same boolean - pick the API you use). - [ ] Network restricted (allowlist).
- [ ] Secrets not exposed on the agent's filesystem or env.
- [ ] Dangerous tools gated or approved manually.
- [ ] Logging and audit enabled.
- [ ] Timeouts and step/output limits set.
Linux (short)
- Dedicated system user, no sudo; per-run directory (e.g.
/srv/agent-runs/<id>), minimal home for that user. - Prefer containers: read-only root, single writable mount for work;
--cap-drop=ALL,no-new-privileges, resource limits. - Egress: nftables/iptables or Kubernetes/CNI policies.
- Optional hardening: systemd (
NoNewPrivileges,ProtectSystem,ProtectHome), cgroups / ulimits, seccomp / AppArmor / SELinux where available.
macOS (short)
- Separate local user for the agent (not administrator); dedicated folder for work - do not reuse your personal home for untrusted automation.
- No Linux-style containers by default - user separation + strict permissions; consider VM or Linux VM (Lima, Colima, UTM) for stronger boundaries.
- TCC: avoid Full Disk Access unless required; don't grant broad disk access unnecessarily; keep Keychain / iCloud Drive off reachable paths unless intentional.
- Application firewall plus egress allowlist; block localhost/internal services if not needed.
- Same SDK settings: tight
local.cwd,local.sandboxOptions.enabled: true, with OS isolation as the real barrier.
That checklist is operations: isolation, egress, logs. API details: Cursor TypeScript SDK docs.
Admissibility (next section) sits on top of that - who may propose which actions before anything runs.
The missing layer: admissibility
This part is my framing, not something missing from a README by mistake.
The Cursor SDK gives you:
- a runtime
- tools (read, write, shell)
- an agent loop
What you still have to supply, in any serious deployment, is:
a definition of what is allowed to happen - or accept that only culture and prompts stand between intent and execution.
One common mental model is:
Agent -> executes actions -> system changes
A stricter pattern many teams want is:
Agent -> proposes actions -> policy validates -> executor applies
The difference:
- one style leans on trusting the agent within a sandbox flag
- another splits policy (what may exist) from execution (what actually runs), so disallowed actions are unrepresentable or rejected before an executor touches disk or shell
That admissibility layer - policies that decide whether a proposed action may exist at all - is where I spend time in design reviews, regardless of whether the SDK bundle is open source.
Closing
The LinkedIn post describes same product surface, packaged for automation. I had conflated that with shipping source I could audit line-by-line like my own repo; npm install showed published packages and a license, not a navigable source tree.
If you're embedding this on a machine that also holds sensitive data - treat it like any other proprietary runtime: isolate, limit, log, and read the license.
If readable sources or a published threat model for local execution appear later, I'll read them with interest.
The SDK is easy to ship and wire up; safety still rides on your threat model, isolation, egress, logging, and any admissibility rules outside what one npm package implies. That isn't replaced by prompts or local.sandboxOptions.enabled alone.
How do you run proprietary agents in CI - sandbox flags only, or gVisor/Firecracker (or similar) around the process?
Top comments (0)