kosa8 docs

Guides / Securing an agent

Securing an agent

A sandbox stops an AI agent from touching your computer. It does not stop the agent from misusing the things you gave it on purpose: an API key, a network connection, a set of tools. This page is the map of what kosa8 puts between an agent and each of those, which threat each layer answers, and where each one stops.

Why a sandbox alone is not enough

A kosa8 sandbox is a virtual machine with its own kernel. An agent inside one cannot read your files or reach your processes. Suppose that wall is perfect. The agent can still go wrong in five ways, because none of them involve getting through the wall.

What a sealed virtual machine still lets through Inside a perfectly sealed virtual machine sit an agent and a real API key that anything in the machine can read. The key and any data can be sent to a host the sandbox is allowed to reach. The same address answers for other sites, which address rules cannot tell apart. A tool server sends new instructions back into the agent. A perfectly sealed VM ANTHROPIC_API_KEYthe real key, readable byanything running in here the agentdoes what the text it reads says key + any data an allowed hosthears anything, the key included same address, other siteaddress rules cannot tell them apart new instructions a tool servercan change what its tool says
Nothing here crosses the wall of the virtual machine. Every arrow uses something the agent was given.
  1. The key is in the sandbox, so whatever runs in the sandbox can read it.
  2. A host you allowed will accept any request the agent sends it, with the key or your files in it.
  3. One address often serves many sites. A rule about addresses admits all of them.
  4. A tool's description is text from a stranger that the model treats as instructions.

None of this is a flaw in the virtual machine. It is the difference between isolating a program and governing what it does with what it holds. The rest of this page is about the second.

The layers

kosa8 answers each of those with a separate control, and all of them except the first run on your side of the boundary (the guard and broker in the kosa8d service, the tool checks in the kosa8 mcp serve gateway), where nothing inside the sandbox can reach them. That placement is the point: a rule the agent could edit is a suggestion.

The layers an agent's action passes through An agent runs in a sandbox virtual machine, the first layer. Its action then passes, on your computer, the network guard and egress broker, the check that a tool's definition is pinned and its arguments fit the schema, the policy rules, and for some calls a person's approval. Every decision, allowed or refused, is written to the audit log. An action refused at any layer stops there. Sandbox — untrusted Your computer — where decisions are made 1 sandbox VMthe agent runs here, withits own kernel and the onefolder you chose 2 guard + brokerevery packet is checked; hostsare admitted by name; your keyis added out here, not in the VM 3 pinned toolsa tool's definition must matchwhat was approved; argumentsmust fit its schema 4 policy rulesallow, deny or ask, decided bywhat the call actually asks for 5 ask a personheld until someone at aterminal approves that one call 6 audit logevery decision above, allowed or refused, is appended to ahash-chained log on your side that the sandbox cannot reach refusedat any layer the action stopsthere, and the refusal is logged allowedit happens, and what wasallowed is logged too
Six layers. Only the first is inside the sandbox; the rest are out of the agent's reach.
  1. The agent runs in a virtual machine of its own. It sees one folder and no key.
  2. Anything it sends to the network passes the guard, then the broker, which admits hosts by name and adds your key on the way out.
  3. A tool is offered only while its definition is the one that was approved, and a call's arguments must fit the approved schema.
  4. Your organisation's signed rules decide the call by its arguments: allow, deny, or ask.
  5. A call a rule answers "ask" waits for a person. The approval covers exactly that call, once.
  6. Each decision is written to a log the agent cannot edit.
  7. A refusal at any layer ends the action there.
  8. An allowed action is recorded as well, so the log answers "what did it do", not only "what was stopped".
Not every action meets every layer

The picture shows the layers in the order an action could meet them. Which ones apply depends on the action. Network traffic from a sandbox meets layers 1 and 2. A tool call made through kosa8's MCP gateway meets layers 3, 4 and 5. (MCP, the Model Context Protocol, is how an AI client is given tools.) Both are recorded in layer 6.

sandbox VMA virtual machine per agent, with its own kernel, disk and private network. The agent sees the folder you named and nothing else on your computer. Start with Your first sandbox; the picture of what runs where is in How kosa8 works.
network guardEvery packet the virtual machine sends is read on your computer before anything forwards it. A sandbox can be given no network, or a list of hosts. See Network rules.
egress brokerThe one door a brokered sandbox's traffic leaves through. It admits hosts by name and port, and it holds your API key so the sandbox does not: the agent gets a placeholder, and the real key is added on your side. See Keep API keys out of the sandbox.
pinned toolsThe gateway records a digest of each tool's definition the first time it sees a server. A tool whose definition later changes, and a tool that newly appears, is withheld until a person accepts it. Arguments and results are checked against the pinned schemas. See Tool servers.
policy rulesRules in your organisation's signed MCP policy decide a call by what it asks for, not only by the tool's name: "issues go in acme/* repositories", "merging needs a person". Deny beats ask beats allow. See Tool rules.
ask a personA call a rule answers "ask" is refused with an id. kosa8 mcp asks shows it; kosa8 mcp approve ID approves exactly that call, for one use, for ten minutes. See Tool rules.
agent identityEach agent can be given a name, a scope and a token the service verifies. Policy is then decided in that agent's scope, and its log entries carry its name. See Agent identity.
pinned packagesA kit (the recipe an agent sandbox is built from) pins what it installs to an exact version and the SHA-512 of that version's tarball, and a kit file can be signed. See Kits.
audit logA hash-chained record of every action: brokered requests allowed and refused, commands run, tool decisions. kosa8 audit verify proves nobody edited it. See The audit log.

Threats and what answers them

Read the last column before the first two. "Partly" is the honest answer more often than "yes".

ThreatWhat answers itHow far
Prompt injection
sends your data out
The sandbox starts with no network, or a short list of named hosts. Everything else is refused on your computer and logged. See Network rules. partly The agent can still send anything it can read to a host you allowed. Request bodies are not inspected. Allow few hosts, and none that accept uploads.
Stolen API key The egress broker keeps the key on your computer. The sandbox holds a placeholder that is worthless anywhere else. See Keep API keys out of the sandbox. yes for the brokered kits: the key cannot be read from inside. partly for spending: while the sandbox runs, the placeholder buys whatever the route allows. The copilot kit still passes its token in.
Tool poisoning,
or a "rug pull"
Tool definitions are pinned by digest. A changed or new definition is withheld until a person reviews it with kosa8 mcp pins diff. See Tool servers. partly The first definition a server gives is taken on trust, unless your organisation's policy lists the pins. Text a tool returns is checked for shape, not for hidden instructions.
Over-broad tool use Argument rules: a call is allowed, denied or held for a person by what its arguments say. They apply to kosa8's own tools too. See Tool rules. yes for what you wrote a rule for. A rule you did not write protects nothing; kosa8 does not guess which calls are dangerous.
Malicious package
in the agent's install
Built-in kits install one pinned version, checked against its SHA-512 before anything runs. A kit whose setup downloads anything else is refused unless you pass --allow-unpinned. See Kits. partly The pin covers the package's own tarball. Its dependencies are resolved by npm at install time, and images are still named by tag.
An agent pretending
to be another
An identity the service verifies: a token minted with kosa8 agent token create. A bad, expired or revoked token is refused, not served anonymously. See Agent identity. partly Tokens are bearer tokens: whoever holds one is that agent. A process running as you on your computer can still call the service as a person.
"What did it do?" The audit log records brokered requests (host, port, method, path, status), every command with the SHA-256 of its exact arguments, and tool decisions. See The audit log. partly Never bodies, never query strings, never the environment. Inside an encrypted tunnel only the host, port and byte counts are known. Entries are rate-limited, with a count of any held back.

Get the essentials in five minutes

Three things are worth seeing with your own eyes: the key is not in the sandbox, a request that should be refused is refused, and both facts are written down.

Run a brokered kit

With your key in your shell's environment as usual, start a built-in kit. Flags go before the kit name.

$ kosa8 agent run -w ~/code/api claude
kosa8: kit claude (node:22-alpine)
kosa8: workspace /Users/you/code/api -> /work (nothing else on the host is visible)
kosa8: network closed except through the egress broker: registry.npmjs.org, statsig.anthropic.com
kosa8: brokering ANTHROPIC_API_KEY -> api.anthropic.com (the sandbox holds a placeholder, never the key)
kosa8: sandbox claude-44059 ready in 653ms
kosa8: pulling node:22-alpine
kosa8: running kit setup, then: claude

Those lines are the contract for this run: which folder is visible, which hosts are reachable, and where the key is. To read them without starting anything, add --dry-run.

See that the key is not inside

Ask the agent to print its environment. Where the key used to be there is a placeholder, and the API's address has been replaced by an address on the sandbox's own private network. This is from a test kit with one brokered credential named echo:

ECHO_KEY=kosa8-placeholder-1803c857986afe6bc9f59600e4d6f6f8
ECHO_URL=http://192.168.127.254:57504/echo
HTTPS_PROXY=http://192.168.127.254:57504

In the claude kit the same two values arrive as ANTHROPIC_API_KEY and ANTHROPIC_BASE_URL. A request sent to that address with the placeholder reaches the real API with the real key, which was added on your computer. The same placeholder sent anywhere else is a random string.

See a refused request in the audit log

From inside that test sandbox, a request to a host that was not listed came back HTTP/1.1 403 Forbidden, and a connection that tried to go around the broker altogether got Connection refused. On your side, both are in the log:

$ kosa8 audit ls --json
# the action and detail of three of the entries
sandbox.egress.allow {"kind":"route","host":"httpbin.org","port":443,"method":"GET","path":"/headers","route":"echo","status":200,"bytes_in":225}
sandbox.egress.deny  {"kind":"http","host":"neverssl.com","port":80,"method":"GET","path":"/","reason":"host not in allow-list"}
sandbox.egress.deny  {"kind":"connect","host":"evil.example","port":443,"reason":"host not in allow-list"}
$ kosa8 audit verify
audit chain intact: 17 entries verified

The first line is the allowed request. It names the route and the path, and it does not contain the key. kosa8 audit verify walks the chain and tells you whether any entry was altered or removed.

For an organisation

Every layer above works on one person's computer with no setup. An organisation can go further and make them mandatory with a signed policy that a developer's machine enforces and cannot weaken:

See Governance and the Policy reference.

What kosa8 does not protect against

A control believed to do more than it does is worse than none. These are the edges, stated plainly.

What this does not do

  • The placeholder is a spendable capability. The agent cannot read your key, and it can still use it: any request the route's methods and paths admit is made with the real credential, for as long as the sandbox runs. The broker cannot tell a good request from a bad one. Narrow the route, and scope the key itself at the provider.
  • An encrypted tunnel is opaque. For HTTPS to an allowed host the broker sees a name and a port, then TLS it does not open. There is no method or path filtering inside it, no request log beyond byte counts, and no check that the name inside the tunnel is the name that was asked for. An allowed host that accepts uploads is a way out for data.
  • Nothing reads content. Request and response bodies are not inspected in either direction. A tool's result is checked against its declared shape, not searched for instructions. Prompt injection hidden in well-formed text reaches the model.
  • A process running as you on your computer is out of scope. The service's socket is yours. A program running under your account can call it as a person, read ~/.kosa8, and approve a held call. The terminal check on kosa8 mcp approve stops an agent approving its own call through a pipe, and nothing more determined. Keep agents in sandboxes; that is what the sandbox is for.
  • First-use pinning trusts the first definition. If a tool server is hostile the first time it is started, its definitions are pinned as they are. Pins listed in your organisation's signed policy remove that gap; local pinning alone does not.
  • Not every agent can be brokered. Brokering needs a command-line tool that accepts a base URL. The Copilot CLI does not, so that kit passes GITHUB_TOKEN into the sandbox, and kosa8 agent run says so every time.
  • A sandbox you create by hand is open by default. kosa8 sandbox create with no network flag has an unrestricted network unless your organisation sets default_egress. Only sandboxes an agent creates, and brokered kits, are closed by default.

Where to go next