Root on the VM is not a boundary
The agent runs as themurmur user with passwordless sudo: root on its own VM.
That’s deliberate. The VM is ephemeral, single-tenant, and holds nothing the agent
can’t already read: its own unsealed developer profile and its own identity token.
An in-VM privilege wall would fence nothing, so Murmur doesn’t pretend it’s one.
All real isolation is enforced server-side: the API authenticates every call with
the agent’s identity token, the Temporal proxy admits only the VM’s own task queue,
and per-tenant KMS keys never touch the VM. What root buys you is self-provisioning:
an agent that needs a system package installs it at runtime (sudo apt-get install,
or npx playwright install --with-deps chromium on an image with Node.js) instead
of stranding on a missing dependency.
The honest cost is defense-in-depth on the murmur-vm supervisor: a root agent
could tamper with it and misreport its own lifecycle events. Those events carry
only the VM’s own identity. They can’t cross a tenant or touch another agent, and
durable state is re-derived from GitHub, not from what the VM says about itself. If
your policy requires a non-root agent anyway, remove /etc/sudoers.d/murmur in
your own recipe bake.
Leg 1: Secret access
You choose which credentials an agent receives and which identities its requests use. What you control:- Scope secrets to where they’re needed. A workspace
delivers a tenant secret to its agent VMs by declaring it in
runtime_secret_mounts, so that list is what the workspace puts on its VMs. A service profile delivers its own credentials separately, and a mount governs neither those nor a developer’s own profile credentials. Pass one-off credentials as spawn-time secrets (murmur spawn -e) that live only for that single agent. - Run agents under a configured identity. A service profile supplies bot credentials. Grant its authority through tenant-bindings and grants on the target workspace. Its own Access Grants control who can assume it; runtime extension determines which of its grants reach a running agent.
- Confine an agent’s GitHub reach to the repositories it works in. Spawn with
--restrict-repository-access(or declare it on a flight) and the agent’s GitHub access is limited to the repositories that spawn involves, and the VM holds no GitHub token at all, so there is nothing on the machine for a prompt injection to use directly. See Repository confinement. - Secret values are write-only. The API never returns a stored secret value -
murmur secret lsshows names, kinds, and short hints only, and a value can’t be read back once set. RBAC governs who can manage secrets (secret.create,secret.edit,secret.delete) through roles and bindings; which of them a workspace delivers to its agents is set by itsruntime_secret_mounts, above.
- End-to-end encryption to the specific VM. Credentials are encrypted at rest under your tenant’s KMS key, re-sealed with NaCl box to the target VM’s ephemeral key, decrypted only in memory, and destroyed with the VM. See Encryption.
- Per-tenant isolation. Each tenant has its own KMS key, and AAD binding makes a secret encrypted for one tenant (or developer) impossible to decrypt for another.
-
Secret scrubbing on the way out. As a backstop,
murmur-vmredacts any session-event field or task response that exactly equals an unsealed profile secret, replacing it with[REDACTED]before it leaves the VM, so an agent that is tricked into echoing a credential can’t ship it back through the control plane.
Leg 2: Trusted input
A coding agent has to read untrusted content. That’s the job, so you can’t stop injected content from reaching it. What you can control is who is allowed to steer the agent: whose instructions it will act on. Murmur gives you two layers of this.Who in your org can drive an agent (RBAC)
Steering a running agent (queueing follow-ups, updating its task list, killing it) requires theagent.edit permission; acting as an agent requires
agent.assume. You grant these through roles, groups, and
tenant-bindings, and you can scope them with name
patterns so a developer drives only their own agents. An org member without
agent.edit on an agent cannot send it instructions.
Which external identities can steer an agent (steering policies)
The riskier input path is events from outside your org: a PR comment, a review, or an issue/PR that opens and triggers a Flight. Murmur gates these with steering policies, so a stranger commenting on a public PR can’t drive your agent. A steering policy sets a minimum tier of trust for the event’s author, plus optional allowlists of specific usernames:
You attach a policy in two places, and the narrower of the two always wins:
- Per repo: set a steering policy on a repo’s config to
govern events coming from that repo. If you set nothing, Murmur auto-selects by
repo visibility: public repos default to
COLLABORATORS, private repos toOPEN(every commenter is already org-vetted). - Per service profile: set a policy on a service profile to gate every agent that runs under it, regardless of which repo the event came from. A locked-down profile can’t be loosened by a permissive repo.
dependabot[bot], without
opening the tier for everyone.
Enforcement is fail-closed and auditable: an event whose author fails the
effective policy is recorded on the agent’s timeline as BLOCKED and is never
delivered. No follow-up, no checklist task, no wake, no Flight spawn. The agent’s
own owner can always steer their own agent.
Leg 3: Egress control
Egress control restricts where an agent VM can send traffic. It is the highest-leverage leg, because it’s the one you can cut on a coding agent without taking away its job. In Murmur, egress control is a feature of customer placements. When you run agents in a customer placement, each VM boots in your own GCP project or AWS account, on your subnet, so the network the VM lives in is yours, and you apply whatever native egress controls your cloud provides. There’s nothing Murmur-specific to learn:- VPC firewall rules / security groups that default-deny outbound and allow only the destinations you choose
- A forced egress proxy, NAT gateway, or VPN
- DNS-resolution allowlists and SNI/Host filtering at a managed firewall
- Cloud-native network policy, flow logs, and your own incident response