When a team starts coding with AI agents, the bottleneck moves fast. Getting agents to run is the easy part.
Running agents under control is the hard part: knowing which server an agent sits on, what it's allowed to touch, who can watch a session, and who can drop into a teammate's session to help.
This is a hands-on blueprint for exactly that: the jump from agents scattered across people's laptops to a managed, multi-developer runtime, built with nothing fancier than SSH, tmux, sudo, and infrastructure-as-code.
Plenty of ready-made tools already cover the solo case. Agent Deck, AoE, Vibe Kanban, and the like spin up parallel agent sessions, sort them by project, and show status. Vendors are moving the same way too: Claude Code now has /agent-view.
But those answer how one person runs a lot of agents, not how a team runs them safely.
Concretely, a team needs to know where and how sessions get launched, what permissions agents run with, who can see them, who can attach to them, and how to give leads and seniors access to juniors' sessions for mentoring. It also needs a standardized execution environment and a way to scale the whole thing through infrastructure-as-code.
Today I'll walk through how to build a basic agent runtime for teams of two or more:
Before a team runtime appears, there are usually two personal modes:
/agent-view
, Agent Deck, or similar tools.After that, the runtime becomes a team concern:
This article is about the jump from personal modes, 0A-0B, to level 1.
NOPASSWD: ALL
in the examples, but I flag every one of them with a note.The minimal working model:
This isn't enterprise grade. Where there's sensitive infrastructure and/or data, I run agents in rootless containers at the very least. But for now, this is just the minimal working setup.
| Handles | Doesn't handle |
|---|---|
| scaling to teams of 2-15+ developers | quality of requirements and architecture |
| agent durability | team processes |
| separating human and agent permissions | code quality, tests, CI |
| basic attribution of actions | protection against agent mistakes |
| basic limits on agent permissions | full permission isolation |
| session visibility for leads | compliance with AI vendor rules |
| a controlled way to attach to newcomers' agent sessions for mentoring | protection of sensitive data |
| enterprise policies |
For teams moving to agent-driven development, the first pain point isn't the sandbox. It's session chaos: it's unclear where and how to launch agents, how to keep tabs on them, how to manage them. Without a session-management layer, moving the chaos inside containers won't save you.
Agents in containers aren't free. A lot of details show up that someone has to keep an eye on: UID mapping, network namespaces, egress proxy, DNS, API endpoints, services, duplicated authentication, image maintenance. All of it is solvable, but it's not a team's first step into an agent runtime.
If you need agents to actually work, not just to "try them out," the default is a separate dev server, or an equivalently isolated environment, per developer.
Why:
load:
dev/stage environments, external integrations, and services need clear isolation of permissions and environment;
accounts, subscriptions, rate limits, and outbound IP behavior are easier to attribute and control.
An option for the start of a project, for training, or for light load. Use it only if the basics are in place:
I won't go deeper into this scenario, since I don't treat it as the main one here.
Developer Wes generates an SSH key on his laptop:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
He copies the public part of the key to his server, dev-wes
:
ssh-copy-id -i ~/.ssh/id_ed25519.pub wes@1.2.3.4
He sets up an alias in ~/.ssh/config
:
Host dev-wes
HostName 1.2.3.4
User wes
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
After that, connecting is just:
ssh dev-wes
When you have a lot of servers, it helps to add autocompletion and an fzf menu over ~/.ssh/config
so you don't have to keep aliases in your head.
On the servers, disable password login and root login. Keys only:
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
If the team has no corporate VPN and connects to servers directly, the private keys on personal laptops must be protected with 2FA, in software or hardware: at minimum the Secure Enclave on macOS, or Windows Hello / TPM on Windows.
et
instead of ssh
Plain SSH drops when the network blips, when the laptop goes to sleep, and so on. When you've always got a pile of tabs open across different servers, projects, and agents, reconnecting is a pain.
So I don't connect like this:
ssh dev-wes
I connect like this:
et dev-wes
Eternal Terminal, or et
, restores the connection after drops, including long ones. Switch VPNs and your sessions are still alive; open the laptop after changing location, or the next morning, and everything keeps running.
The more popular mosh isn't a great fit for agents yet: it "draws" the screen itself and "predicts" your input instead of behaving like plain SSH. That makes scrolling, full-screen mode, and terminal integrations work worse. Eternal Terminal is closer to a regular SSH/PTY session, so agents are happier inside it.
Running agent sessions remotely in tmux is already better than running them locally: the session lives on the server, doesn't depend on the laptop, and runs in a standardized environment.
et dev-wes
tmux new -s claude
claude
But hand-managed tmux turns into chaos fast. A couple of days in, you open the session list and see something like this:
tmux ls
claude: 1 windows (created Mon May 4 09:12:43 2026)
test: 1 windows (created Mon May 4 14:55:01 2026) (attached)
new: 2 windows (created Tue May 5 10:03:18 2026)
new2: 1 windows (created Tue May 5 18:41:02 2026)
prod-bug-final: 1 windows (created Wed May 6 23:17:55 2026)
fix-temp: 1 windows (created Thu May 7 08:22:11 2026)
No idea which project, whose process, which agent, what's active, what's stuck, what's safe to kill, and so on.
So you need a session manager on top of tmux.
But first, permissions.
The basic scheme:
It's important not to mix the two roles:
If you run the agent as the same human user, the agent gets the same permissions, especially in permissive mode: --dangerously-skip-permissions
, yolo. In that case the blast radius is limited only by the human user's permissions.
In a sane setup these are different users: the human user manages the session, and the agent runs as an agent user with limited permissions.
sudo useradd -m -s /bin/bash wes
sudo useradd -m -s /bin/bash wes-agent
echo "wes ALL=(wes-agent) NOPASSWD: ALL" | \
sudo tee "/etc/sudoers.d/wes-agent"
sudo chmod 440 "/etc/sudoers.d/wes-agent"
sudo visudo -c -f "/etc/sudoers.d/wes-agent" # syntax check
Just to be clear: I'm constraining the agent, not trying to defend against Wes himself. That's why I'm using NOPASSWD: ALL
here. Wes can run any command as his own agent user, but not as root, and not as other users.
So Wes won't launch the agent with a plain claude
. It'll be more like this:
sudo -u wes-agent tmux new -s billing-api-claude
claude
Except it'll be a single keypress in a wrapper over tmux: the session manager, more on that in the next section.
If you want the agent to push to Git on its own, set up a separate SSH key or a fine-grained PAT inside wes-agent
, with minimal permissions for just the repos it needs. Don't forward the ssh-agent with ForwardAgent yes
or ssh -A
into the agent user, or wes-agent
could end up with privileges it shouldn't have.
A team lead should see all of the team's agent sessions and be able to attach to them; a senior should see the sessions of the juniors they mentor; everyone else sees only their own.
The simplest way to manage this is the same OS-level sudo privileges.
echo "marcus ALL=(marcus-agent,wes-agent,nadia-agent) NOPASSWD: ALL" | \
sudo tee "/etc/sudoers.d/marcus-lead"
sudo chmod 440 "/etc/sudoers.d/marcus-lead"
sudo visudo -c -f "/etc/sudoers.d/marcus-lead" # syntax check
Again, NOPASSWD: ALL
here. This is the trusted-lead/senior model. This access is equivalent to full access to the employee's agent user, not just tmux attach
.
You end up with this:
wes
└─ sudo → wes-agent → only their own sessions
nadia
└─ sudo → nadia-agent → only their own sessions
marcus (lead)
├─ sudo → marcus-agent → his own sessions
├─ sudo → wes-agent → Wes's sessions
└─ sudo → nadia-agent → Nadia's sessions
The lead gets sudo rights over wes-agent
, not over wes
himself. He can attach to Wes's session, kill it, inspect the agent's processes, but he doesn't become Wes. Wes's SSH keys, his secrets and credentials, his personal .gitconfig
: all of that stays with Wes.
In process logs and Git commits, the lead's actions stay the lead's actions.
This isn't about defending against an evil lead. He's trusted. It's about cleaner attribution and not doing something under someone else's name by mistake.
The point isn't to build a "real sandbox." It's this:
An even better practice is to isolate the work in rootless Docker/Podman or a VM. But for a quick start, for small teams and dev servers with no sensitive data, limiting agent permissions at the OS level can be enough.
This is nowhere near enterprise-grade security. But it's a lot better than one shared user. Any dev server quickly becomes a place with access to repos, personal data, secrets, internal APIs, and tokens.
tmux doesn't know the context of agent sessions: which project, who owns it, which agent, and so on. And when there are many dev servers, it does nothing to pull all their sessions onto one screen.
So you need a thin layer over tmux that adds all this semantics.
For solo development there are already plenty of good tools: Agent Deck, AoE, Vibe Kanban, CCManager, and others. Most of them support different agents. Agent Deck and AoE can run sessions in Docker. Agent Deck can work with your own sessions on other remote servers.
The AI vendors themselves are also building tools to manage sessions from a single window. Claude Code recently got /agent-view, though multi-agent support and several personal subscriptions in one window are unlikely to land.
That helps the solo workflow, but it does not solve the team runtime problem by itself.
For team scenarios, what matters isn't pretty session lists. It's the constraints:
The question isn't "how does one person launch 30 agents."
It's: how do you give a team a manageable runtime?
In my own setup, I use a small Python + Textual TUI wrapper over tmux called uxon. Treat it as one reference implementation of the pattern, not as the point of the article. For more complex scenarios such as containers or enterprise environments, it's always custom.
You can use it as a starting point, or build your own tmux-based session manager with Claude in an evening or two, as long as you understand the requirements it has to meet.
In my view, these columns in the UI / TUI are probably enough:
On every server lead Marcus needs to reach, you create a separate Linux user marcus
and grant it sudo rights over the relevant agent users:
| Server | Linux user | Sudo access to agent user |
|---|---|---|
Marcus's server, dev-marcus |
||
marcus |
||
marcus-agent |
||
Wes's server, dev-wes |
||
marcus |
||
wes-agent |
||
Nadia's server, dev-nadia |
||
marcus |
||
nadia-agent |
The local marcus
gets SSH access to the remote marcus
users by key:
marcus-laptop: et dev-marcus
marcus@dev-marcus: et dev-wes
marcus@dev-wes: sudo -iu wes-agent tmux ls
marcus@dev-wes: sudo -iu wes-agent tmux attach -t backend-debug
The session manager should do this work in the background so that, in the TUI, Marcus sees both local and remote sessions, including other people's, running under other agent users such as wes-agent
and nadia-agent
, that the marcus
user has sudo access to on the remote servers.
Marcus doesn't get some "magic" blanket access to every agent on every machine. On each server, access is defined with ordinary OS tools: you created the marcus
user, dropped in his SSH key, and granted specific sudo rights over the relevant agent users. It's rolled out like any infrastructure-as-code: through Ansible, Terraform/OpenTofu, or whatever stack you've settled on.
In this scheme, to revoke Marcus's access to Wes's sessions, you edit sudoers on Wes's server, and nowhere else.
It sounds primitive, but it's precisely the absence of a central point that answers most of the "how do you administer all this centrally" questions. Config rollout is centralized through Ansible/Terraform. Authority is validated locally on each server by plain sudo. The session manager on top is just a client that connects by key and asks each host what's available to it.
et dev-wes
uxon
Or your own wrapper.
Sees their sessions, which folders they're running in, their status, and the server load.
Attaches to the one they need, or creates a new one and gets to work.
Closes stale sessions with a single keypress.
When a lead or senior opens the session manager, they see:
At the "mature" level, agent visibility and the absence of server chaos aren't the main problem anymore. The goal is to make the agent's execution environment genuinely constrained and reproducible.
| Approach | What it does | When to choose it | Downsides |
|---|---|---|---|
| Separate OS-level users | Isolates process permissions, files, tokens, partly resources | Basic team runtime, fast start, no sensitive data or risks | Weak network and dependency isolation; boundaries sit at the OS-kernel level |
| Dev container | Provides a reproducible environment: image, tools, dependencies, settings | When people and agents need the same dev environment | It's about reproducibility; protection depends on configuration |
| Rootless Docker/Podman | Isolates the filesystem, processes, dependencies, some host permissions | When you need isolation for yolo mode but without enterprise security | The container shares the kernel with the host; mounted paths, secrets, network, and capabilities are critical |
| VM | Isolates at the hypervisor level, separate OS kernel | Sensitive infrastructure, long-lived sandboxes | Heavier in resources, startup, and maintenance |
| microVM / Kata / Firecracker | Almost like a VM | Sensitive infrastructure, many short-lived sandboxes | Harder to debug, orchestrate, and fit into the dev process |
| Ready-made sandbox platform | Depends on the platform | When you need a production-grade sandbox without building your own | Vendor lock-in, cost, and open questions on data, compliance, and customization |
Containers aren't a "mature" or enterprise level by themselves. If you've forwarded SSH keys, credentials, the Docker socket, the whole home directory, and unrestricted network into the container, that's not isolation. It's the old risks in new packaging.
The point is that agent sessions run not in a shared shell on the server, but in a predefined environment with clear boundaries:
It's better to give the agent more freedom inside a constrained runtime than to run it with limited permissions in the shared environment of a dev server.
At the enterprise level, on top of all this you may see custom agents on custom models, centralized policies and audit, sensitive-data controls, DLP, observability, quotas, SIEM/SOC, SDLC, and so on.
The approach above solves the most basic team problem: it makes working with agents more transparent, manageable, and scalable.
It doesn't make developers better, code higher-quality, the product more valuable, or the team automatically AI-native or agent-first.
You'll also need, or may need:
If the topic's interesting, I can devote the next part to level 2: how to run agent sessions in rootless Docker/Podman and what details to plan for. Or I could cover how to reshape team processes so that working with agents actually fits into them.
For now: I hope this was useful. If you set this up for your own team, I'd love to hear what you changed in the comments.