Skip to content

Safety, and what vekna does not sandbox

Vekna does not sandbox agents. The agent edits your repository and runs your commands — that is the job, and a sandbox around it would defeat the point.

Where the boundaries are Vekna does not sandbox agents: the agent acts freely inside a cast, a failure stops at the cast process, vekna offers a tool gate, read-only tool lists, decide and step budgets, and the real boundaries are scoped credentials and a fence around vekna itself. Where the boundaries are Vekna does not sandbox agents. The agent edits your repository and runs your commands — that is the job. What it buys is containment of failure, and a few stated places where you get to say no. the host · or a fence you put round all of vekna one cast process · ordinary Python, a working dir The agent, inside a step acts permissively — no sandbox, by design edits your repository the checkout the cast runs in runs your commands through shell and its own tools reaches what its token reaches GitHub, APIs — as far as the credential lets it A sandbox around it would defeat the point. Where a boundary is wanted, it lives outside the cast: in the token, or in the fence. Where you get to say no vekna's own, small and stated Tool gate gate_tools=["Bash"] asks you before the agent runs a named tool Read-only agent dontAsk + allowed_tools off the list, denied — bar vekna's own ask tool decide never answers for you decide(…) no default, no timeout Step budget max_steps a ritual that loops forever stops Scope the credentials, not the process a boundary that is yours to draw, and the one worth having one token per ritual fine-grained, least privilege triage ✓ read pull requests ✓ comment on them not granted ✗ push to main ✗ read every repo in the org Failure stops at the process blast radius: one cast ✗ this cast dies a broken ritual, a misbehaving SDK kills its own process ✓ the daemon carries on its row says how the cast ended ✓ every other cast carries on each is a process of its own Fence the whole thing if a cast must not reach the host devcontainer · VM · what you already use vekna daemon and its casts Run vekna inside it, rather than expecting vekna to grow a fence inwards. a cast containerises like any Python process None of these is a sandbox. They are places where you get to say no.

What the process split does buy is containment of failure: a broken ritual or a misbehaving SDK kills one cast process and nothing else.

Where a boundary is genuinely wanted, two things work, and neither is vekna's to build.

Scope the credentials, not the process

A ritual that triages pull requests needs a token that can read pull requests and comment on them — not one that can push to main or read every repository in the organisation.

Fine-grained tokens, one per ritual, least privilege. The example rituals each state the exact permission set they need, because a recommendation nobody can act on is not a recommendation.

Fence the whole thing if you want a fence

If a cast must not reach the host, run vekna inside the container — devcontainer, VM, whatever the project already uses — rather than expecting vekna to grow one inwards. A cast process is an ordinary Python process with a working directory, and it containerises like anything else.

What vekna does own

Small, and stated:

  • The coding medium's tool gate. CodingOpts(gate_tools=[...]) asks you before the agent runs a named tool, and permission_mode="dontAsk" with an allowed_tools list denies everything outside it without stopping to ask. That is how you get a genuinely read-only agent — the list doing the work, not the mode: dontAsk denies what is not on it and grants what is, so one write-capable tool in there is a write-capable agent.
  • A decide never defaults and never times out. Nothing in a cast answers a question on your behalf.
  • Step budgets. max_steps bounds the trampoline, so a ritual that loops forever stops rather than running until you notice.

None of these is a sandbox. They are places where you get to say no.