Skip to content

feat(env): optional passwordless sudo for the sandbox agent - #208

Merged
Kavya Sree Kaitepalli (KavyaSree2610) merged 1 commit into
mainfrom
bala/root-access
Nov 2, 2026
Merged

Kavya Sree Kaitepalli (KavyaSree2610) merged 1 commit into
mainfrom
bala/root-access

Conversation

@0xba1a

@0xba1a Bala (0xba1a) commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

Summary

Add an opt-in sudo_access flag that gives the sandbox's agent account passwordless sudo. Some tools, such as mock, need root for part of their work.

The agent keeps running as the host user's uid. It only becomes root for commands it explicitly runs with sudo. So files it writes in a READ_WRITE mount stay owned by the host user, with no ownership fix-up needed. The default is False, which keeps today's behaviour.

Changes

  • shell_server/prepare.sh: with AGENT_SUDO=1 it:
    • installs sudo if it's missing;
    • adds a NOPASSWD sudoers entry for the agent (/etc/sudoers.d/microbots-agent, mode 0440);
    • makes /etc/shadow owner-readable. Some images, such as Azure Linux, ship it with mode 0000, which sudo's PAM account check can't read inside a container.
  • LocalDockerEnvironment(sudo_access=...):
    • passes AGENT_SUDO to prepare.sh;
    • starts the container without no-new-privileges, because sudo and setuid helpers (for example mock's consolehelper launcher) need it. Without sudo_access the flag stays on, as before;
    • fails fast if sudo -n true doesn't work in the agent's shell;
    • allows a READ_ONLY mount but logs a warning (see Security).
  • Ownership: the shell server always drops to agent. Files the agent writes through sudo stay root-owned; nothing is chowned when the environment stops.
  • Bots: MicroBot, ReadingBot, WritingBot, LogAnalysisBot, BrowsingBot, AgentBoss and CopilotBot accept sudo_access for the environment they create. A provided environment must already have been created with sudo_access=True, otherwise they raise ValueError.
  • Docs: a "Sudo access" section on the Sandbox Images page and in the CopilotBot parameter table.

Why sudo instead of a root shell

An earlier version of this PR ran the whole agent shell as root, and then had to chown every root-created file back to the host user. With sudo:

  • the agent's commands run as the host user by default;
  • tools built for this model work as designed. azldev expects to run as a normal user in the mock group, and mock escalates through its own setuid launcher.

A follow-up PR adds mock.yaml, which adds the agent to the mock group, and azldev.yaml. With them, azldev comp render succeeds on the stock Azure Linux image as the agent, without sudo, and leaves no root-owned files in the repository.

Security

With sudo_access=True the sandbox becomes a guardrail rather than an isolation boundary.

  • Through sudo, the agent has root with the container's SYS_ADMIN capability and AppArmor unconfined, so it can mount filesystems and reach host-wide kernel interfaces.
  • A misbehaving or prompt-injected agent could therefore remount a READ_ONLY mount as writable, or gain root on the host.
  • Turning off no-new-privileges also makes setuid binaries in the image usable.

The runtime warnings and the docs say this plainly. Enable it only for trusted tasks and trusted repositories, skills and instructions.

Testing

  • Unit:

    • Environment: container security options with and without sudo, AGENT_SUDO passed to prepare.sh, the sudo -n true check (success, and failure stopping the container), the READ_ONLY warning, and no chown on stop.
    • prepare.sh: the sudo setup only happens when requested.
    • Bots: sudo_access forwarding and the provided-environment check for MicroBot, all subclasses and CopilotBot.
    • Results: 760 passed. The failures in test_microbot.py::TestMicrobotUnit and test_memory_tool_integration.py also occur on main and come from my local environment.
  • Integration: new test/environment/local_docker/test_sudo_access.py, run on both stock images (DEBIAN_IMAGE, AZURELINUX_IMAGE):

    • with sudo_access=True, the agent runs as the host uid, sudo -n id -u returns 0, and a file it writes in a READ_WRITE mount is owned by the host user;
    • without it, sudo is unavailable.

    CI's integration selection, run locally: 25 passed, with no new failures compared to main.

Upcoming PRs in this stack

  1. refactor(env): run stock MCR images, prepare the sandbox on the fly #202 (merged): stock MCR images prepared on the fly.
  2. feat(tools): distro-aware tool commands #205 (merged): distro-aware tool commands.
  3. feat(env): Azure Linux 3 sandbox image #207 (merged): Azure Linux 3 sandbox and image on the bots.
  4. This PR: optional passwordless sudo for the sandbox agent.
  5. rpm / mock / azldev tool definitions.
  6. CopilotBot session_options and skill tracking, so it can use a repository's agent skills.

Base automatically changed from bala/azurelinux-image to main October 29, 2026 08:53
@codecov-commenter

Codecov Comments Bot (codecov-commenter) commented Oct 29, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.22%. Comparing base (f926f86) to head (c2f0033).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #208      +/-   ##
==========================================
+ Coverage   77.07%   77.22%   +0.15%     
==========================================
  Files          47       47              
  Lines        3197     3219      +22     
==========================================
+ Hits         2464     2486      +22     
  Misses        733      733              
Flag Coverage Δ
ghcp 31.87% <47.82%> (+0.09%) ⬆️
integration 42.49% <65.21%> (+0.17%) ⬆️
ollama_local 34.54% <47.82%> (+0.07%) ⬆️
slow-browser 18.35% <4.34%> (-0.10%) ⬇️
slow-other 38.64% <47.82%> (+0.20%) ⬆️
unit 74.83% <100.00%> (+0.39%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/microbots/MicroBot.py 100.00% <100.00%> (ø)
src/microbots/bot/AgentBoss.py 100.00% <ø> (ø)
src/microbots/bot/BrowsingBot.py 100.00% <ø> (ø)
src/microbots/bot/CopilotBot.py 100.00% <100.00%> (ø)
src/microbots/bot/LogAnalysisBot.py 100.00% <ø> (ø)
src/microbots/bot/ReadingBot.py 100.00% <ø> (ø)
src/microbots/bot/WritingBot.py 100.00% <ø> (ø)
...environment/local_docker/LocalDockerEnvironment.py 88.44% <100.00%> (+0.64%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@0xba1a Bala (0xba1a) changed the title feat(env): optional root access for the sandbox shell feat(env): optional passwordless sudo for the sandbox agent Oct 29, 2026
Some tools (e.g. mock) need root for part of their work. Add an opt-in
`sudo_access` flag that gives the sandbox's `agent` account - which
already has the host user's uid - passwordless sudo, instead of running
the whole shell as root.

- prepare.sh: with AGENT_SUDO=1, installs sudo if missing and adds a
  NOPASSWD sudoers entry for the agent. Some images (e.g. Azure Linux)
  ship /etc/shadow with mode 0000, which sudo's PAM account check cannot
  read in a container, so it is made owner-readable.
- LocalDockerEnvironment(sudo_access=...): passes AGENT_SUDO to
  prepare.sh, starts the container without no-new-privileges (sudo and
  setuid helpers such as mock's launcher need it), and fails fast if
  `sudo -n true` does not work. A READ_ONLY mount is allowed but logs a
  warning, since with sudo the agent could remount it writable.
- The shell still runs as the host uid, so files the agent writes stay
  owned by the host user; files written through sudo stay root-owned
  (no ownership fix-up on stop).
- MicroBot, ReadingBot, WritingBot, LogAnalysisBot, BrowsingBot,
  AgentBoss and CopilotBot accept sudo_access; a provided environment
  must already have sudo access.
- Docs: "Sudo access" section.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
environment: Optional[any] = None,
additional_tools: Optional[list[ToolAbstract]] = None,
image: Optional[str] = None,
sudo_access: bool = False,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might give sudo access all the sub-agents that AgentBoss creates

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is expected. We don't have fine-grained control over the sub-agents as of now. We'll address this later along with improving overall AgentBoss experience.

)
```

- The agent's commands still run as your uid unless it explicitly uses `sudo`, so files it writes in a `READ_WRITE` mount stay owned by you. Files it writes through `sudo` are owned by root and are left that way.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if the agent opens its own bash session using sudo bash and run the comamnds?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is true. When the Agent is given sudo access, all sorts of privileged things are possible. So, we included multiple warnings in this flow. The documentation assumes that the agent will be co-operative.

If the model becomes rogue, we don't have any real guardrail against it. This is applicable for all the privileged agents. Thus, the developer should be cautious before enabling this and the system where this agent runs shouldn't be critical for production operations.

@KavyaSree2610
Kavya Sree Kaitepalli (KavyaSree2610) merged commit a2f7e2e into main Nov 2, 2026
10 checks passed
@0xba1a
Bala (0xba1a) deleted the bala/root-access branch November 2, 2026 06:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants