Running coding agents without exposing your API keys
Kiwi's credential model is built so that customer secrets are only ever in plaintext inside the one process that needs them — the daemon running the task — and never in the sandbox, never in the Control Plane's memory in BYOC, and never on disk unencrypted.
Two keypairs per daemon
On boot, a daemon generates two keypairs (pkg/crypto):
- X25519 — for credential sealing. Customer credentials are encrypted to the daemon's X25519 public key, so only that daemon can open them.
- Ed25519 — for heartbeat signing. The daemon signs its polls so the Control Plane can verify the request comes from the registered daemon.
How a credential travels
Customer credentials (an Anthropic/Codex/Gemini key, a git token) are stored by the Control Plane sealed to a specific daemon's X25519 public key — using a NaCl anonymous sealed box (an ephemeral sender keypair per seal, so there is no sender identity). At rest, that sealed blob is additionally encrypted by the configured key manager: a static key for dev/BYOC, or Cloud KMS envelope encryption for managed.
When a daemon leases work, it receives the sealed credentials in the poll response and opens them in memory with its X25519 private key. They are used to call the LLM provider and to open the PR — and are never written into the sandbox or persisted in plaintext.
BYOC vs managed — and the zero-knowledge caveat
The same sealing model runs in both deployment modes; what differs is who operates the machine that holds the private key.
| Managed | BYOC | |
|---|---|---|
| Who runs the daemon | Kiwi | You, in your own cloud |
| Where credentials are unsealed | Kiwi-operated host | Your VPC |
| Can the Control Plane operator decrypt? | Yes — Kiwi holds the private key | No — the key never leaves your cloud |
| Zero-knowledge? | No | Yes |
:::warning Managed is not zero-knowledge In BYOC, the daemon runs in your cloud and the Control Plane never sees plaintext credentials — that is a genuine zero-knowledge property. In managed mode, Kiwi operates the daemon and holds its private key, so Kiwi can decrypt. Do not treat managed mode as zero-knowledge. Zero-knowledge is a BYOC-only claim. :::
Defense in depth around the sandbox
The credential model is reinforced by the execution seam:
- The LLM Actor/Critic run in the daemon, so model-generated code never sees the LLM key.
- The test command runs in the sandbox with default-deny networking, so exfiltration has nowhere to go.
- Free-tier daemons each have their own keypair, so the per-org sealing boundary holds even when many daemons are packed onto a shared host.
Operational hardening
- In
productionmode,KIWI_ENCRYPTION_KEY,KIWI_SERVER_TOKEN, andKIWI_CORS_ALLOWED_ORIGINSmust be set explicitly. - For managed deployments, set
KIWI_KMS_KEYto use Cloud KMS envelope encryption instead of a static key. - Daemons register with single-use join tokens; after registration the persisted identity key is sufficient.