Skip to content

Podman based sandboxing solution for m series macs

License

Notifications You must be signed in to change notification settings

jikkuatwork/testman

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Testman

Ephemeral container sandboxes for running AI coding assistants safely.

cd sandboxes/agentman
./run.zsh --workspace ~/code/myproject --public

Why

AI coding assistants execute code, install packages, and access your filesystem. Running them with unrestricted access creates exposure—to your SSH keys, cloud credentials, and other projects.

Testman provides ephemeral, isolated containers where AI tools operate with access limited to a single project directory. Each session starts fresh. Syscall-level auditing captures everything the agent does.

Designed to work with kodemachine for defense in depth: VM isolation at the host level, container isolation at the project level.

Architecture

┌─────────────────────────────────────────────────────────────┐
│ Host / VM                                                   │
│                                                             │
│   testman/sandboxes/agentman/run.zsh                        │
│         │                                                   │
│         ▼                                                   │
│   ┌─────────────────────────────────────────────────────┐   │
│   │ Ephemeral Container (podman --rm)                   │   │
│   │   - AI assistants execute here                      │   │
│   │   - Filesystem: ~/workspace (mounted project dir)   │   │
│   │   - Syscall auditing via strace                     │   │
│   │   - Destroyed on exit                               │   │
│   └─────────────────────────────────────────────────────┘   │
│                                                             │
│   ~/.testman/containers/<project>/                          │
│     config/  → persists AI conversation history             │
│     logs/    → syscall and filesystem audit logs            │
└─────────────────────────────────────────────────────────────┘

Quick Start

1. Build Base Image

cd sandboxes/base

# Public image (privacy-safe, no personal config)
./build.zsh --public

# Private image (requires TESTMAN_SSH_KEY and TESTMAN_DOTFILES env vars)
./build.zsh --private

2. Run AI Assistant

cd sandboxes/agentman

# Basic usage
./run.zsh --workspace ~/code/myproject --public

# With syscall auditing
./run.zsh --workspace ~/code/myproject --public --audit

# With port mapping for dev servers
./run.zsh --workspace ~/code/myproject --public --map-ports 3000,8080

3. Inside Container

# AI assistants available (installed at runtime)
claude      # Claude Code
gemini      # Google Gemini CLI
aider       # Aider
# ... and more

# Your project is at ~/workspace
cd ~/workspace

Sandboxes

Directory Purpose
sandboxes/base/ Foundation image and ephemeral runner
sandboxes/agentman/ AI coding assistants (Claude, Gemini, Aider, etc.)
sandboxes/TEMPLATE/ Template for creating new tool-specific sandboxes
sandboxes/lib/ Shared functions

Features

Ephemeral Containers

Every run creates a fresh container with --rm. No state accumulation. Persistence comes from mounted volumes:

  • ~/.testman/containers/<project>/config/ → AI conversation history
  • ~/.testman/containers/<project>/logs/ → Audit logs
  • ~/workspace → Your project directory

Syscall Auditing

Enable with --audit:

./run.zsh --workspace ~/project --public --audit

Logs syscalls (openat, read, write, connect, execve) and filesystem events (modify, create, delete) to ~/.testman/containers/<project>/logs/.

Auto-Naming

Project names are auto-generated from workspace paths:

./run.zsh --workspace ~/code/webapp --public
# → Project name: webapp-a8f1 (basename + hash)

Override with --name:

./run.zsh --name myproject --workspace ~/code/webapp --public

Port Mapping

Expose container ports to host:

./run.zsh --workspace ~/project --public --map-ports 3000,8080,9090

Base Image Contents

Ubuntu 24.04 ARM64 with:

  • Shell: zsh, neovim, vim, tmux, starship prompt
  • Tools: bat, ripgrep, fd, jq, htop, tree, httpie
  • Languages: Node.js 20, Python 3.12, Go 1.23 (via asdf)
  • Browser automation: Playwright + Chromium
  • Security: strace, inotify-tools (for auditing)
  • Containers: Podman (for nested container workflows)
  • GUI: XFCE4, VNC, Firefox, Chromium (for headed mode)

Private Builds

For personal development with SSH access and dotfiles:

# Set environment variables
export TESTMAN_SSH_KEY="$(cat ~/.ssh/id_ed25519.pub)"
export TESTMAN_DOTFILES="https://github.com/user/dotfiles.git"

# Build private image
./build.zsh --private

The private image includes:

  • SSH server (port 22)
  • Your dotfiles (cloned from TESTMAN_DOTFILES)
  • Your SSH key for authentication

Creating New Sandboxes

Use the template for tool-specific sandboxes:

cp -r sandboxes/TEMPLATE sandboxes/mytool

Edit sandboxes/mytool/run.zsh and replace placeholders:

  • {TOOL_NAME} → Human-readable name
  • {TOOL_COMMAND} → Command to check
  • {INSTALL_COMMAND} → Installation command
  • {PACKAGE_NAME} → Package name

Tools install at runtime—no separate Containerfile needed.

Design Principles

  • Ephemeral: Fresh container every run, no state accumulation
  • Isolated: Each project gets separate config and logs
  • Auditable: Syscall tracing for untrusted tools
  • ARM64 only: Optimized for Apple Silicon and ARM servers
  • Podman only: Rootless containers, no Docker dependency

Requirements

  • Podman
  • ARM64 host (Apple Silicon Mac, ARM Linux server)
  • For private builds: TESTMAN_SSH_KEY and TESTMAN_DOTFILES environment variables

Related Projects

License

MIT

About

Podman based sandboxing solution for m series macs

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •