Keep your tools' code away from your keys
Under kindgi dev, your pack's tools run in a pack service on your machine,
as you. Much of that code is often written by a coding agent. kindgi dev
runs the pack service sandboxed, so the code reaches what it needs (the app,
the runtime that runs it, the network) and not the rest of what you can
reach. So does the indexer, which loads every tool, agent and flow module to
list them, and with them any code at a module's top level.
At start, kindgi dev says it's on:
✓ dev sandbox: macOS Seatbelt: your tools' code can't read your keys or files outside the app, write outside it, or reach Docker; it still has the network and the app's own fileskindgi doctor checks it too:
✓ Dev sandbox: kindgi dev runs your tools' code sandboxed (macOS Seatbelt): it can't read your keys or reach Docker.What it closes, and what it doesn't
Section titled “What it closes, and what it doesn't”| Closed to your tools' code | Still open |
|---|---|
Your home folder: SSH keys, cloud credentials (~/.aws, ~/.config/gcloud), registry tokens (~/.npmrc), other projects |
The app's own files, read and write: its code and its data |
Secrets in the app, wherever they are: .env*, Kindgi's .kindgi folder, .git, kindgi.env, pack.env, .kindgirc.json, .npmrc, .pypirc, .netrc |
The runtime that runs it and the app's dependencies, to read |
The Docker socket, and every other UNIX socket (ssh-agent, a local database's socket); on Linux, those under the home folder, /tmp, /var/tmp and /run (Docker's, ssh-agent's, a local database's): a socket elsewhere stays reachable |
The network: any API a tool calls |
| Other tools' temp files; on Linux, other processes too | Its own temp folder (TMPDIR) |
Writing anywhere outside the app: on macOS every other folder (/opt/homebrew, /Users/Shared, /Applications), where a program it replaced would run later outside the sandbox; on Linux the system is read-only |
What kindgi dev hands it: the app's own settings from its env files, and the secrets a tool declares (ctx.secrets) |
Writing Kindgi's configuration (kindgi.config.*, pyproject.toml): kindgi dev loads it, and it says how wide the sandbox is |
|
On macOS, the keychain, and LaunchServices and Apple Events (opening an app, or a file with one, outside the sandbox); on Linux, the terminal kindgi dev runs in (the code gets its own session) |
A process the code starts, such as a git or a curl, is inside the
sandbox too.
What it doesn't do:
- It doesn't stop the network. Code that can read a value can send it
anywhere. What the pack service is handed matters as much, which is why
Kindgi's own secrets and your model provider keys never reach its
environment (Keep local values in env files). On Linux
that includes abstract UNIX sockets (an X11 display's
@/tmp/.X11-unix/X0, some D-Bus buses), which share the network's namespace. - It doesn't protect the app's own files, or what runs them later. A tool
can read and change your app's code and data, as the coding agent can,
including files something outside the sandbox runs later: git hooks in the
tree (a
core.hooksPathsuch as.husky/),package.jsonscripts, aMakefile. Review what the agent writes before you run it outsidekindgi dev. - It covers
kindgi devonly. In a deployment, the pack's image is the boundary, and the pack service keeps only the names the pack declares (Declare the environment your code reads).
The runtime is opened to read wherever it is, and nothing else around it:
- Node.js, from nvm or Homebrew;
- a Python interpreter's own paths (a venv, a uv-managed Python under
~/.local/share/uv); - a JDK and every jar on the pack's classpath (
~/.m2/repository, coursier's cache).
A path that would open your whole home folder never is, and kindgi dev
says so.
Open a path or a socket a tool needs
Section titled “Open a path or a socket a tool needs”A tool that uses the AWS SDK's credential chain reads ~/.aws. One that
talks to a local Postgres over its socket connects to
/tmp/.s.PGSQL.5432 (over TCP, localhost:5432 needs nothing). Open what
it needs in the pack's config, rather than turning the sandbox off:
// in kindgi.config.tsdev: { sandbox: { allowRead: ['~/.aws'], allowUnixSockets: ['/tmp/.s.PGSQL.5432'], },},# in pyproject.toml[tool.kindgi.dev.sandbox]allowRead = ["~/.aws"]allowUnixSockets = ["/tmp/.s.PGSQL.5432"]In a Java or Scala pack it's "dev": { "sandbox": { … } } in
kindgi.config.json. A path is absolute, starts with ~/, or is relative to
the pack's root. kindgi dev names each one at every start, so an opening
an agent adds shows on screen as well as in the diff:
✓ dev sandbox: macOS Seatbelt: your tools' code can't read your keys or files outside the app, write outside it, or reach Docker; it still has the network and the app's own files also reads /Users/…/.aws (dev.sandbox.allowRead)The secret files listed above stay closed wherever they are, even inside a path you open.
Where it runs
Section titled “Where it runs”-
macOS: Seatbelt (
sandbox-exec), always there. Inside another sandbox that restricts anything (a coding agent's, say), macOS doesn't letkindgi devadd its own: run it in your own terminal. -
Linux: bubblewrap (
bwrap). Install it if your system doesn't have it:Terminal window sudo apt-get install bubblewrap # Debian, Ubuntusudo dnf install bubblewrap # FedoraUbuntu 23.10 and later restrict the user namespaces bwrap needs (Ubuntu's announcement). Allow it with an AppArmor profile for
/usr/bin/bwrap, then reload AppArmor:Terminal window printf 'profile bwrap /usr/bin/bwrap flags=(unconfined) {\n userns,\n}\n' | sudo tee /etc/apparmor.d/bwrapsudo systemctl reload apparmorOn Linux the secret files in the app are found each time the pack service starts. A
.envfile created whilekindgi devruns stays readable until the next start: a save restarts it. -
Windows: none
kindgi devcan use. Runkindgi devunder WSL, where it uses the Linux one. -
Inside a container (a dev container, CI): the container is the boundary, and bwrap can't run inside a default one.
Where it can't run, kindgi dev warns at start and runs your tools without
it:
⚠ Your tools run without the dev sandbox on this system: they can read your files and keys. Why: kindgi dev is already inside a sandbox (a coding agent’s?) that won’t let it add its own. Run kindgi dev in your own terminal. More: https://docs.kindgi.com/v0.1/guides/secrets/dev-sandbox/. To refuse to run without it: KINDGI_DEV_SANDBOX=required; to drop this warning: KINDGI_DEV_SANDBOX=off.That one is from a Mac, inside another sandbox; the Why: line names the
reason on each system.
With the sandbox on, kindgi dev starts only with one Kindgi configuration
in the app: the code it runs can't change the one in use, but could add
another by a name looked up first.
kindgi dev: more than one Kindgi configuration in /Users/…/acme-probe: kindgi.config.ts, kindgi.config.mts. With the dev sandbox on, kindgi dev starts with one only: the code it runs can't change it, but could add another by a name looked up first. Keep the one you use and remove the others.Require it, or turn it off
Section titled “Require it, or turn it off”KINDGI_DEV_SANDBOX sets it for a machine or a shell:
| Value | What kindgi dev does |
|---|---|
on (default) |
Runs the pack service sandboxed where it can; elsewhere, warns and runs it without. |
required |
Runs it sandboxed, or stops before anything starts. |
off |
Runs it without, and says so at every start. |
For one project, dev: { sandbox: false } in its config turns it off;
KINDGI_DEV_SANDBOX wins over it. Turned off, kindgi dev says so:
⚠ dev sandbox: off (KINDGI_DEV_SANDBOX=off): your tools' code can read your files and keys as you can