kosa8 / Guides

Guide

How do I give an AI agent API keys without exposing them?

Updated 2026-10-31

Do not put the key in the agent's environment at all. Give the agent a placeholder and an API address that points at a proxy outside its sandbox; the proxy checks each request, swaps the placeholder for the real key, and forwards it only to the one API that key belongs to. In kosa8 this is the egress broker: the key stays in the host service's memory and never enters the VM.

01Steps

These steps use kosa8 agent run, which builds an agent's sandbox from a kit: an image, a command, the hosts it may reach and its credentials.

  1. Keep the key in your own shell. Set the key on your computer the way the tool normally expects it, for example ANTHROPIC_API_KEY. kosa8 agent run reads it there and sends it to the kosa8d service over a socket only you can open.

  2. Check which kits broker their keys. The KEYS column of kosa8 agent kits says where each kit's credentials go: brokered means the key stays on your computer and the sandbox holds a placeholder; passed in means the real key is in the sandbox's environment.

  3. Dry-run the kit. A dry run prints the plan and starts nothing. Look for the brokering line; a line that begins kosa8: passing means that kit puts a real key in the sandbox.

    terminal
    kosa8 agent run --dry-run claude
    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)
  4. Run the agent. -w names the one folder the agent may see. The sandbox and its broker are removed when the agent exits, and the key is dropped from memory.

  5. Broker your own tool's key. Any HTTP API whose client lets you set a base URL can be brokered. Describe the credential in a kit file: the upstream it may go to, the host environment variable that holds it, the header, and the methods and path prefixes it may be used on.

    weather.yaml
    # weather.yaml
    name: weather
    description: A shell that can call a weather API without holding its key
    image: alpine:latest
    command: [sh]
    egress_allow:
      - docs.example.com
    credentials:
      - name: weather
        upstream: https://api.example.com
        secret: WEATHER_API_KEY
        header: Authorization
        scheme: "Bearer "
        methods: [GET]
        paths: [/v1/forecast]
        env:
          WEATHER_API_URL: "{{url}}"
          WEATHER_API_KEY: "{{placeholder}}"

02Why is an API key in an environment variable unsafe for an AI agent?

Anything in the agent's environment can be read by the agent, by every package it installs and by every script it runs. A prompt injection hidden in a web page, issue or file can tell the agent to print or send the key; a compromised dependency can read it at install time; and keys end up in logs, shell history and crash output. Once copied out, the key works from anywhere until you revoke it.

Prompt injection is first on the OWASP Top 10 for LLM applications, and it is hard to rule out because the agent must read untrusted text to do its job. The reliable fix is that there is nothing worth stealing inside the sandbox.

03How does an injecting egress proxy keep the key out of the sandbox?

The sandbox is given a random placeholder and the proxy's address in place of the real key and API address. Its request leaves through one open port to the broker on your computer, which checks the method, the path and the placeholder, writes the real key into the header, and forwards the request over verified TLS to the one upstream the key belongs to. Redirects are not followed.

In kosa8 the broker is a small HTTP proxy inside the kosa8d service, one per sandbox, and it is the only way out a brokered sandbox has. The API's host is not on the sandbox's allow-list, so the agent cannot open its own connection to the API, with or without a key. Every request, allowed or refused, is written to the audit log with host, method, path and status, never the key or the query string. The real key is not in the sandbox, its record on disk, a snapshot or the audit log.

04What can an attacker do with a stolen placeholder?

Very little. Sent straight to the API it is not a key. Sent to another sandbox's broker it does not match that sandbox's own placeholder and is refused with 403. After the sandbox stops, the broker and the key it held are gone.

The placeholder is recognisable on purpose: kosa8-placeholder- followed by 32 random hexadecimal characters, fresh for each sandbox, so one found in a log is obviously not a real key.

05What does key brokering not protect against?

The placeholder is still a capability: inside the sandbox, any request the route's methods and paths allow is made with the real key while the sandbox runs. Narrow the route and scope the key itself at the provider. Bodies are not inspected, and a tool that cannot change its base URL cannot be brokered.

The Copilot CLI is one such tool, so kosa8's copilot kit still passes GITHUB_TOKEN in and says so on every run; give it the narrowest token that works. A brokered sandbox that is restarted, restored or forked comes back with its network closed and no broker, because carrying the key across would mean storing it.

06Other options

Other approaches reduce the damage a leaked key can do, or keep the key away from the agent in a different way. They combine well with each other.

  • Scoped, short-lived keys. Create a separate key for the agent with the smallest permissions and a spending limit at the provider, and rotate it often. This helps whatever else you use.
  • A model gateway you run. An LLM proxy such as LiteLLM can issue its own virtual keys with budgets, so the agent never holds the provider key. The virtual key still sits in the agent's environment and works from anywhere that can reach the proxy.
  • A secrets manager. HashiCorp Vault can issue dynamic, short-lived credentials. This shortens a leaked secret's life, but if it is injected as an environment variable the agent can still read it.
  • Other sandboxes with network controls. Docker, Claude Code's built-in /sandbox, full VMs in UTM or Lima, and hosted sandboxes such as E2B, Daytona and Modal can all limit what an agent reaches. Check each one's documentation for how it handles credentials.

07Sources