Skip to content

Security model

  • Hypervisor isolation. Every tenant is a Firecracker microVM. Sessions can install anything, run anything, break anything — and reach only their own machine.
  • Billing resolution is explicit. Whose Claude account pays for a turn: the person’s own connection, else their tenant’s, else the workspace’s org-wide API key — never a deployment-wide anything. Subscription sign-ins are one person each; anything shared runs on commercial API keys.
  • A rule you set is never silently dropped. guardrails, no-tools, protected-branches and max-turns are enforced by the Claude agent itself; Codex, Gemini and Copilot are separate programs that accept none of them. So Sparkyard refuses to move a thread — or a default — to an agent that cannot enforce a rule your workspace has set, and names the agents a new rule excludes at the moment you set it. max-turns only warns: it caps cost rather than access. The rest refuse, because a promise made to your own security review is not answered by a warning in a thread.
  • Conversations stay in Slack, with one exception. The database holds identifiers, settings and ledgers — not what was said. The exception exists because agents can hand work to each other: a rolling transcript of a thread’s last dozen turns, truncated, so an agent joining halfway is not answering about work it cannot see. Written only for threads with agent turns, read only once more than one agent has answered, deleted with the thread.
  • A database console is not a shared link. /sparkyard db publishes a SQL console on an owner-locked URL: it needs a session minted for one named person, so knowing the address is not enough. It is deliberately not an ordinary preview, which would default to public — a bearer URL onto a query console would be worse than exposing the database’s port, since the port at least has the database’s own password in front of it. The console is read-only, and that password is typed into the browser rather than held here.
  • Credentials live in a vault. Values are AES-256-GCM sealed into rows bound to their tenant; exactly one process can decrypt. Nothing is ever pasted into a channel: Claude connects by sign-in ceremony, GitHub by device flow, everything else through private forms.
  • Tokens expire. GitHub access is minted per boot (installation tokens, 1 hour) or per person (user tokens, 8 hours, silently refreshed) — a disk snapshot of VM memory stops mattering shortly after it is written.
  • Per-tenant everything. No deployment-level default can shape a tenant: identities, owners, installations and settings are explicit rows, so one customer’s configuration cannot leak into another’s.
  • Webhooks are signed, not secret. A desk can be woken by a CI failure (CI desk) — the only path where a request from the internet reaches an agent with credentials and no person in between. The hook id is public by design; the per-hook secret is what authenticates, checked with HMAC-SHA256 over the raw bytes before anything is read, written or spent. Replays are stopped separately, by the provider’s delivery id, because a signature with no timestamp in it cannot tell fresh from recorded. An autonomous desk still runs inside the same microVM under the same egress rules: autonomy widens what can start a turn, never what a turn may reach.
  • A desk’s job description grants it nothing. A desk type is the text the desk is given about itself, and that is all it is. Permissions come from what an admin switched on — a new desk can file issues and nothing else; adding a CI webhook adds read access to Actions; turning repair on adds the ability to push, and turning it off takes it back. Calling a desk review or oncall does not widen a single token.
  • One deployment, no middlemen. The machines run on infrastructure the operator controls — code, credentials and inference traffic touch that deployment and the providers it talks to (GitHub, Anthropic, Slack), with no additional cloud in the middle.