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:
- runtime / execution environment: where and how agents are launched; servers, permissions, management;
- workflow: how agents are used. Not the topic today.
Maturity levels for team agent runtimes
Before a team runtime appears, there are usually two personal modes:
- Level 0A, personal local mode: agents run on a laptop in a local terminal;
-
Level 0B, personal server mode: durable sessions run on remote dev servers with tmux/zellij,
/agent-view, Agent Deck, or similar tools.
After that, the runtime becomes a team concern:
- Level 1, small team runtime: OS-level permission separation, centralized management of agents across servers, controlled attach, basic audit;
- Level 2, mature team runtime: stronger isolation in containers/VMs, K8s, reproducible environments, resource limits, controlled mounts and network boundaries;
- Level 3, enterprise runtime: custom models/private cloud, PII/PD/DLP, policies, compliance, observability, integrations.
This article is about the jump from personal modes, 0A-0B, to level 1.
Disclaimer
- I want this article to be useful to a broad audience, so I won't go deep into containers and enterprise levels 2-3.
- The approach described here doesn't replace sandboxes, containers, VMs, DLP, or corporate policies. The goal is to give a team the most basic hygiene for working with agent sessions.
- This is about working with agents, not about defending against a malicious developer who has server access. That's why I use
NOPASSWD: ALLin the examples, but I flag every one of them with a note.
TL;DR for a small team
The minimal working model:
- agents live on dev servers, not laptops;
- tmux keeps long-running sessions alive;
- Eternal Terminal gives you a connection that survives drops;
- each person has their own Linux user and runs agents under a separate Linux user;
- agent permissions are trimmed to the bare minimum;
- on top of tmux you build a session manager that lets leads see different people's sessions across different servers and attach to them;
- control over who can see and connect to whose sessions should be flexible and obvious, with no shared keys and no root handed out;
- events are logged and available for audit.
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.
What this setup handles vs. what it doesn't
| 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 |
Why not just start with Docker/Kubernetes?
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.
1. Servers
Option A. A separate dev server per developer
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:
- 4-7 agent sessions running at once per developer is normal, not an exception;
- the sessions alone can eat 12-16 GB of RAM and 6-10 vCPUs;
- heavy builds, tests, and watchers devour the rest;
- many concurrent consumers means a fight over resources;
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.
Option B. A shared dev server for several people
An option for the start of a project, for training, or for light load. Use it only if the basics are in place:
- at least two Linux users per person: one for the person, one for their agents;
- agent-user permissions restricted at the ACL level;
- auditd, journald, Monit, or equivalents;
- better to set resource limits via systemd per agent user, so one person's heavy sessions don't starve everyone else's machine;
- if you use several accounts for the same agent, you should at least give each one a different outbound IP.
I won't go deeper into this scenario, since I don't treat it as the main one here.
2. Connecting to servers
2.1. Keys
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:
# /etc/ssh/sshd_config
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.
2.2. 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.
3. Runtime: tmux as the base
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.
4. Identity and permissions
The basic scheme:
- each person has their own Linux login user: the human user;
- agents are authenticated and run under a separate agent user;
- tmux sessions live in the agent user's sockets;
- processes, tokens, configs, and permissions don't get mixed together;
- a lead's or senior's access to someone else's sessions is granted through explicit sudo rules for the agent user, not the human user;
- leads reach sessions on other servers with their own SSH key; sudo rights are granted on each server independently, but the configuration is rolled out centrally through whatever tooling the team uses: Ansible, Terraform, OpenTofu, etc.
4.1. Human user and agent user
It's important not to mix the two roles:
- human user: the person who connected to the server and manages sessions;
- agent user: the user the agent actually runs as: its tmux session, processes, tokens, and access.
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
# Give the trusted user wes the right to act as 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.
4.2. Guest access to sessions
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.
# Let lead Marcus see and attach to his own sessions, plus Wes's and Nadia's
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:
- the agent doesn't get the same access the human has: shell command history, SSH keys, personal tokens, stray aliases, access to other projects and the home directory, and so on;
- the agent's blast radius is limited by the agent user's permissions, not the developer's;
- resource and permission limits can be tuned without touching the people;
- the agent's outbound routing and network access are easier to keep separate from the user's, which helps when something's blocked in your region;
- the agent's environment is reproducible: it doesn't pick up a random alias or rc file from the developer's personal shell;
- a lead or senior gets access to people's sessions without taking on their identity;
- in the logs, the agent's actions are separated from the human's.
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.
5. The management layer: a tmux session manager
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.
5.1. Ready-made tools
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.
5.2. Team scenarios
For team scenarios, what matters isn't pretty session lists. It's the constraints:
- launching agents as different users, from the right accounts, with limited permissions;
- different visibility into others' sessions for different team members;
- being able to see and attach to the right sessions, yours and others', running across different servers, while respecting permissions;
- keeping server load under control;
- no need to hand everyone excessive access or shared keys;
- logging and audit.
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.
5.3. What the session manager should have
In my view, these columns in the UI / TUI are probably enough:
- Server
- Project / Worktree
- Agent
- Launched by / agent user
- Activity status: active / idle for X
- Resources: CPU / RAM
- Actions: attach / kill
5.4. How do you see sessions on other servers?
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 connects from his laptop to his own server
marcus-laptop: et dev-marcus
# Marcus can reach Wes's server
marcus@dev-marcus: et dev-wes
# Marcus can see Wes's AI sessions
marcus@dev-wes: sudo -iu wes-agent tmux ls
# Marcus can attach to the session he wants
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.
6. What it looks like in practice
For a regular developer
- The developer logs into the server:
et dev-wes
- Opens the session manager:
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.
For a lead
When a lead or senior opens the session manager, they see:
- their own sessions on this server, just like a regular developer;
- colleagues' sessions whose agent users they have passwordless sudo over;
- their own and others' sessions on the servers listed in the config, where they have SSH key access;
- and they can close stale sessions, not just their own, but other people's too.
Onboarding newcomers and helping colleagues
- A newcomer opens an agent.
- The lead or senior gets on a call with them, no video, no screen sharing.
- They attach to the same session and work in it alongside the newcomer, demonstrating best practices and helping put them into use.
- A colleague asks: "show me how to use the architecture-review plugin."
- The lead opens the session and shows both "how to" and "how not to."
7. On the "mature" and enterprise levels
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:
- which image/template is used;
- which runtime user commands run as;
- which commands require explicit confirmation;
- which directories are mounted inside;
- where the agent can go over the network;
- what CPU/RAM/disk limits are set;
- how long a session can live without activity;
- which logs and artifacts are kept;
- what gets deleted when it's done.
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.
8. What's next
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:
- new processes and team rules built around agents;
- requirements for architecture and code that are an order of magnitude stricter than before agents;
- shared and specialized rule sets for agents: skills/plugins/hooks;
- custom MCPs for integrating with internal systems and documentation;
- a new git flow built for agents;
- automated review of commits and PRs by agents as part of CI;
- security and measures to protect sensitive data;
- full environment isolation for working in sensitive infrastructure;
- audit, logs, monitoring;
- SSO/RBAC, observability;
- a full rethink of how you build products and manage requirements, if you want to accelerate more than just development.
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.


Top comments (0)