Dev.to Security πŸ” Cybersecurity πŸ‘ 0 πŸ“– 5 min read

GitHub Next's Ace runs agents with your privileges: 7 facts from its trust model, and 6 checks before you share a channel

GitHub Next released Ace this week, an open-source collaborative coding environment where people and agents work together in channels that run on your own machines. It is MIT-licensed, it has shipped 98 releases since th

GitHub Next released Ace this week, an open-source collaborative coding environment where people and agents work together in channels that run on your own machines. It is MIT-licensed, it has shipped 98 releases since the repository appeared on October 2, and the README opens with a warning box instead of a feature list. That warning is the most honest paragraph I have read in an agent tool this year, so I worked through the README, the start, usage and command docs, and the architecture file to pin down what the trust model actually says before anyone starts a channel on a shared tailnet.

What Ace is, and what you are running

A host process runs on your machine, from source with Bun 1.4 or later, or as the Mac app (Apple silicon, macOS 15 or later). Channels live under $ACE_HOME on that machine, default ~/.local/state/ace. Each channel is a chat with an agent in it, plus lanes, isolated worktrees the agent starts for parallel work. You need Tailscale running before anything else, and an Anthropic or OpenAI key in Settings β†’ Providers. From a checkout:

bun install
bun ace new --project ~/code/my-repo
bun ace ask <channel> "what does this repo do?"

Even solo, a Mac without Tailscale cannot create a channel, because every channel belongs to a tailnet. Models are written provider/id, for example --model anthropic/claude-opus-5-5, so pin an exact id rather than a family name, the same lesson as when model names stopped meaning one thing.

Agents run with your privileges

The warning, verbatim: "Ace runs agents with the privileges of the user running the host. They can execute arbitrary shell commands and read, change, or delete files beyond the project directory." There is no sandbox layer between the agent and your user account, and the next sentence closes the loophole you were hoping for: "Channels and lanes are not security sandboxes." A channel is closer to handing a teammate an SSH session on your machine than to opening a shared document.

Lanes isolate work from work, not from you

Each piece of work gets a lane, a copy-on-write worktree, so a new lane starts with its dependencies already in place and parallel agents never share a checkout. That is real isolation for concurrent work: two agents in one repo will not clobber each other's files. It is not a security boundary. The lane's agent still runs as your user and reaches anything your user can reach. Coordinating parallel agents has its own failure modes, Antigravity's /run-workflow built a whole mechanism around them, but the isolation layer here is the worktree, nothing more.

Your tailnet is the entire access control

The README again: "Your tailnet is your team and the sole authority for team membership and collaboration access. Ace has no separate accounts, invitations, or team access controls." Everyone on the tailnet who runs Ace is on your team, with nothing to join. Adding a person means adding them to the tailnet in the Tailscale admin console. The host names each caller with tailscale whois, so the whole access question reduces to one line: who is on your tailnet, and would you give each of them a shell on this machine?

GitHub logins sit on top of that, not instead of it. Ace names people by their GitHub login, resolved with gh api user, and a GitHub-backed project is visible to logins that can read the repository. Local folder projects stay visible only on your own host unless someone shares them, and existing projects became private on upgrade. A share grants the team, or one person, every channel in a project.

The two switches that stay off

Two capabilities start off on every new channel, and both are the ones that let other people spend your privileges:

  • Agent access: whether teammates can ask your channel's agent, the one that runs commands as you. Off by default, and turning it on asks first, with the reason stated in the dialog: agents run on your machine with your permissions.
  • Desktop tools: whether the channel's agents can operate this Mac's apps. Also off by default.

The CLI forms are explicit, which makes them easy to script and easy to audit:

ace agents fix-login off   # teammates can read along, not drive the agent
ace desktop fix-login off  # agents cannot touch the Mac's apps
ace project access         # who can see this project, and why

Two control planes, one host

The host listens on 127.0.0.1:4140. On loopback, the WebSocket at /ws needs the owner token from $ACE_HOME/host.token, sent as a Bearer header. On the tailnet there is no token: Tailscale identifies callers, and the sensitive routes, settings, keys, projects and terminals, are refused there. The same gateway is reachable two ways with two rule sets, and the dangerous operations only work from the machine itself. A host that should never join the team fabric can run ace serve --loopback and stay off the tailnet and the directory entirely.

Everything lands on your disk

Channels live under $ACE_HOME/channels/<id>/, each holding channel.json and channel.sqlite. channel.json records the tailnet, by MagicDNS suffix, the channel was created on, and the host serves only channels of the tailnet it found at startup; channels from another tailnet stay on disk, hidden. Your provider key sits in the app's settings on that machine. The architecture file also states the deployment model outright: Ace is open source, teams clone and fork it, and "Ace will not operate a hosted service." There is a Beta cloud-compute option that moves an idle channel to a hosted workspace; the agent commits and pushes every lane first, and the channel cannot move back.

Six checks before you share a channel

  1. Treat every channel as a shell for whoever can reach it. The default-off switches help, but tailnet membership is the real decision.
  2. Keep Ace on a tailnet you control, not the company-wide one that still has ex-employees' devices or shared machines on it.
  3. Leave agent access and desktop tools off until a task needs them, then turn them off again. One command each, no settings hunt.
  4. Rotate the provider key if a host ever sat on a tailnet you do not fully control. The key lives in Settings β†’ Providers on that machine.
  5. Before moving a channel to cloud compute, review what is in the worktrees. Every lane gets committed and pushed, and the move is one-way.
  6. Read the trust model section of the architecture file yourself. It is short, and the README calls it binding.

Most agent tools blur the boundary until an incident clarifies it. Ace does the opposite: one wall, named in the first screen of the README, with the two expensive switches off by default. That is the same instinct behind reviewing agent permissions as config instead of ambient magic, whether it is the open security questions around MCP's newer primitives or the allow rules in a coding agent's settings file.

πŸ“° Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.