Skip to main content

A barebone sandbox for agentic coding based on UNIX user

Project description

A⁴U²: AI Agent As Another Unix User (aka agent-as-unix-user)

A barebone sandbox for agentic coding based on UNIX users.

TL;DR:

uv tool install agent-as-unix-user  # Install this cli
au new  # Create a new UNIX user for your IA agent
au mount add --rw ~/example # Expose `~/example` in `/home/agent/example`
                            # with read&write access
au run --env FOO=bar claude  # Run claude (with an environ variable) as the agent UNIX user,
                             # with only access to `/home/agent`

UNIX has been designed from the ground to allow multiple users to securely share a single machine (remember the time when a terminal was a physical thing that was used to connect to a mainframe ? Yeah, me neither).

So instead of containers or VMs, agent-as-unix-user is a simple wrapper around standard UNIX commands to easily:

  • Creates a dedicated UNIX user
  • Give access to certain folders in read-only or read&write mode
  • Undo all of this if needed ;-)
  • Run commands as the UNIX user

With your IA agent running as a dedicate user, protection becomes trivial:

This gives you filesystem-level isolation with minimal overhead: the agent runs on the same host, but under a separate UID with controlled access.

Installation

Only Linux is supported for now (MacOS might be possible though, so PR welcome \o/).

pipx install agent-as-unix-user
# or with uv
uv tool install agent-as-unix-user

[!NOTE] agent-as-unix-user has the following requirements:

  • Linux with ACL support
  • A C compiler (for the setuid entrypoint)
  • sudo access (for user/group creation and setuid setup)

Recipes

The great thing about this approach is its simplicity and it compatibility with the UNIX ecosystem.

Example 1: limit CPU & RAM

Limit the agent to use at most 16Go of RAM and one-and-half cores on your machine.

systemctl set-property user-$(id -u agent).slice CPUQuota=150% MemoryMax=16G

Example 2: filter network traffic

Run an HTTP proxy locally with your filtering rules, then configure iptables:

# Redirect HTTP and HTTPS traffic from UNIX user `agent` to
# port 3128 (default port for Squid HTTP proxy)
iptables -t nat -A OUTPUT -m owner --uid-owner agent -p tcp --dport 80  -j REDIRECT --to-port 3128
iptables -t nat -A OUTPUT -m owner --uid-owner agent -p tcp --dport 443 -j REDIRECT --to-port 3128

# Allow DNS
iptables -A OUTPUT -m owner --uid-owner agent -p udp --dport 53 -j ACCEPT

# Block everything else for that user
iptables -A OUTPUT -m owner --uid-owner agent -j DROP

How it works

When you create an agent, agent-as-unix-user will:

  1. Create a UNIX user (e.g. agent) and a group (su-as-agent)
  2. Add your user to the group so you can interact with the agent's files
  3. Configure the agent's home directory with setgid + ACL defaults so files created by either user remain editable by both
  4. Compile and install a small setuid C binary (/home/agent/su_as_agent) to execute command as the agent.

Note agent-as-unix-user is designed to be as transparent as possible by only using UNIX commands and displaying them as they are run:

$ uv run au new -a agent2
Create agent agent2 in /home/agent2 and configure group 'su-as-agent2'? [y/N]: y
$ sudo groupadd su-as-agent2
[sudo] password for touilleMan:
$ sudo useradd --shell /usr/bin/bash --no-user-group --create-home --home-dir /home/agent2 --gid su-as-agent2 agent2
$ sudo usermod --append --groups su-as-agent2 touilleMan
$ sudo chgrp su-as-agent2 /home/agent2
$ sudo chmod 2770 /home/agent2
$ sudo setfacl --modify default:group:su-as-agent2:rwx /home/agent2
$ sg su-as-agent2 -c 'tee /home/agent2/README.md'
$ sg su-as-agent2 -c 'mkdir -p /home/agent2/.config/agent-as-unix-user/su_as_agent-src'
$ sg su-as-agent2 -c 'tee /home/agent2/.config/agent-as-unix-user/su_as_agent-src/main.c'
$ sg su-as-agent2 -c 'tee /home/agent2/.config/agent-as-unix-user/su_as_agent-src/Makefile'
$ sg su-as-agent2 -c 'make -C /home/agent2/.config/agent-as-unix-user/su_as_agent-src'
make: Entering directory '/home/agent2/.config/agent-as-unix-user/su_as_agent-src'
cc -O2 -Wall -Wextra -Werror -DTARGET_UID=1003 -DTARGET_GID=1003 -o su_as_agent main.c
make: Leaving directory '/home/agent2/.config/agent-as-unix-user/su_as_agent-src'
$ sg su-as-agent2 -c 'mv --force /home/agent2/.config/agent-as-unix-user/su_as_agent-src/su_as_agent /home/agent2/su_as_agent'
$ sudo chown root:su-as-agent2 /home/agent2/su_as_agent
$ sudo chmod 4750 /home/agent2/su_as_agent
Created agent agent2

To run a command as an agent, au run my_command will itself uses /home/agent/su_as_agent that:

  • Scrubs your environ variables (only LANG and TERM are kept).
  • Drops all the groups inherited from the original user.
  • Sets UID and GID to become the agent user.

Usage

Create a new agent

au new                    # creates an agent named "agent" (default)
au new --agent agentA     # custom agent name
au new --yes              # skip confirmation prompt

Requires root/sudo. Creates the UNIX user, group, home directory (with setgid + ACL), compiles the setuid entrypoint, and updates the config file.

Run a command as the agent

au run echo hello                    # run as default agent "agent"
au run --agent agentA -- code        # run as a specific agent
au run --env API_KEY=xxx -- cmd      # pass environment variables

Before executing, au run verifies the entrypoint binary hasn't been modified by comparing its SHA-256 hash against the stored fingerprint. Environment is scrubbed by default — only LANG and TERM are kept, plus any variables passed explicitly via --env.

Show agent info & health

au info                   # info for default agent "agent"
au info --agent agentA    # info for a specific agent

Displays the agent's home directory, group, entrypoint path, ACL external accesses, and runs a healthcheck that verifies:

  • UNIX user and group exist
  • Home directory exists with setgid bit
  • Default ACLs are configured
  • Entrypoint exists and is executable
  • Current user is a member of the agent's group
  • ACL tooling is available on the system

List agents

au list

Lists all agents present in the configuration file.

Delete an agent

au delete                        # delete default agent "agent"
au delete --agent agentA         # delete a specific agent
au delete --delete-home          # also remove the home directory
au delete --yes                  # skip confirmation prompt

Requires root/sudo. Removes the UNIX user, group, and optionally the home directory. Resilient to partial state — if some resources are already gone, it skips them and continues.

Global options

--config, -C PATH    Config file (default: ~/.config/agent-as-unix-user.toml)
--version            Show version
-h, --help           Show help

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agent_as_unix_user-2.1.0.tar.gz (17.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agent_as_unix_user-2.1.0-py3-none-any.whl (24.2 kB view details)

Uploaded Python 3

File details

Details for the file agent_as_unix_user-2.1.0.tar.gz.

File metadata

  • Download URL: agent_as_unix_user-2.1.0.tar.gz
  • Upload date:
  • Size: 17.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for agent_as_unix_user-2.1.0.tar.gz
Algorithm Hash digest
SHA256 8fd564bcd9d163f5d6692f2b67fcef0897a14bc4508d54817c270064fa58da01
MD5 e9733d970731d9369841466927fa358f
BLAKE2b-256 1eee1ff62e73b6fa6bdf5a515e2909d6cc6e11fe7c033c230953a2ee2a5d5d5c

See more details on using hashes here.

Provenance

The following attestation bundles were made for agent_as_unix_user-2.1.0.tar.gz:

Publisher: ci-cd.yml on touilleMan/agent-as-unix-user

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file agent_as_unix_user-2.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for agent_as_unix_user-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d9f530d5d07521d68b6c42f806019c422052bd01a9f416c64931896bba54743b
MD5 14085c7335a5276b3dc9058839b4a32c
BLAKE2b-256 7635986bb184f4b1dbaa4109ee3a6707eb56ef8e5b7096dc80d134eab3380f6a

See more details on using hashes here.

Provenance

The following attestation bundles were made for agent_as_unix_user-2.1.0-py3-none-any.whl:

Publisher: ci-cd.yml on touilleMan/agent-as-unix-user

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page