Skip to content
39 changes: 39 additions & 0 deletions .changeset/user-isolation-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
'start-command': minor
---

Add user isolation support with --isolated-user and --keep-user options

Implements user isolation that creates a new isolated user to run commands:

## --isolated-user option (create isolated user with same permissions)

- Add --isolated-user, -u option to create a new isolated user automatically
- New user inherits group memberships from current user (sudo, docker, wheel, etc.)
- User is automatically deleted after command completes (unless --keep-user)
- Works with screen and tmux isolation backends (not docker)
- Optional custom username via --isolated-user=myname or -u myname
- For screen/tmux: Wraps commands with sudo -n -u <user>
- Requires sudo NOPASSWD configuration for useradd/userdel/sudo

## --keep-user option

- Add --keep-user option to prevent user deletion after command completes
- Useful when you need to inspect files created during execution
- User must be manually deleted with: sudo userdel -r <username>

## Other improvements

- Add comprehensive tests for user isolation
- Update documentation with user isolation examples
- Integrate --keep-alive and --auto-remove-docker-container from main branch

Usage:

- $ --isolated-user -- npm test # Auto-generated username, auto-deleted
- $ --isolated-user myrunner -- npm start # Custom username
- $ -u myrunner -- npm start # Short form
- $ --isolated screen --isolated-user -- npm test # Combine with process isolation
- $ --isolated-user --keep-user -- npm test # Keep user after completion

Note: User isolation requires sudo NOPASSWD configuration.
58 changes: 49 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,44 @@ $ --isolated docker --image oven/bun:latest -- bun install
$ -i tmux -s my-session -d bun start
```

### User Isolation

Create a new isolated user with the same group permissions as your current user to run commands in complete isolation:

```bash
# Create an isolated user with same permissions and run command
$ --isolated-user -- npm test

# Specify custom username for the isolated user
$ --isolated-user myrunner -- npm start
$ -u myrunner -- npm start

# Combine with process isolation (screen or tmux)
$ --isolated screen --isolated-user -- npm test

# Keep the user after command completes (don't delete)
$ --isolated-user --keep-user -- npm start

# The isolated user inherits your group memberships:
# - sudo group (if you have it)
# - docker group (if you have it)
# - wheel, admin, and other privileged groups
```

The `--isolated-user` option:

- Creates a new system user with the same group memberships as your current user
- Runs the command as that user
- Automatically deletes the user after the command completes (unless `--keep-user` is specified)
- Requires sudo access without password (NOPASSWD configuration)
- Works with screen and tmux isolation backends (not docker)

This is useful for:

- Running untrusted code in isolation
- Testing with a clean user environment
- Ensuring commands don't affect your user's files

#### Supported Backends

| Backend | Description | Installation |
Expand All @@ -162,15 +200,17 @@ $ -i tmux -s my-session -d bun start

#### Isolation Options

| Option | Description |
| -------------------------------- | ----------------------------------------------------- |
| `--isolated, -i` | Isolation backend (screen, tmux, docker) |
| `--attached, -a` | Run in attached/foreground mode (default) |
| `--detached, -d` | Run in detached/background mode |
| `--session, -s` | Custom session/container name |
| `--image` | Docker image (required for docker isolation) |
| `--keep-alive, -k` | Keep session alive after command completes |
| `--auto-remove-docker-container` | Auto-remove docker container after exit (docker only) |
| Option | Description |
| -------------------------------- | --------------------------------------------------------- |
| `--isolated, -i` | Isolation backend (screen, tmux, docker) |
| `--attached, -a` | Run in attached/foreground mode (default) |
| `--detached, -d` | Run in detached/background mode |
| `--session, -s` | Custom session/container name |
| `--image` | Docker image (required for docker isolation) |
| `--isolated-user, -u [name]` | Create isolated user with same permissions (screen/tmux) |
| `--keep-user` | Keep isolated user after command completes (don't delete) |
| `--keep-alive, -k` | Keep session alive after command completes |
| `--auto-remove-docker-container` | Auto-remove docker container after exit (docker only) |

**Note:** Using both `--attached` and `--detached` together will result in an error - you must choose one mode.

Expand Down
50 changes: 48 additions & 2 deletions REQUIREMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ Support two patterns for passing wrapper options:
- `--detached, -d`: Run in detached/background mode
- `--session, -s <name>`: Custom session name
- `--image <image>`: Docker image (required for docker backend)
- `--isolated-user, -u [username]`: Create new isolated user with same group permissions as current user
- `--keep-user`: Keep isolated user after command completes (don't delete)
- `--keep-alive, -k`: Keep isolation environment alive after command exits (disabled by default)
- `--auto-remove-docker-container`: Automatically remove docker container after exit (disabled by default, only valid with --isolated docker)

Expand All @@ -157,7 +159,50 @@ Support two patterns for passing wrapper options:
- **Detached mode**: Command runs in background, session info displayed for reattachment
- **Conflict handling**: If both --attached and --detached are specified, show error asking user to choose one

#### 6.5 Auto-Exit Behavior
#### 6.5 User Isolation

- `--isolated-user, -u [username]`: Create a new isolated user with same permissions
- Creates user with same group memberships as current user (sudo, docker, wheel, etc.)
- Automatically generates username if not specified
- User is automatically deleted after command completes (unless `--keep-user` is specified)
- For screen/tmux: Wraps command with `sudo -n -u <username>`
- Requires sudo NOPASSWD for useradd/userdel commands
- Works with screen and tmux isolation (not docker)

#### 6.6 Keep User Option

- `--keep-user`: Keep the isolated user after command completes
- Only valid with `--isolated-user` option
- User must be manually deleted later with `sudo userdel -r <username>`

Example usage:

```bash
# Create isolated user and run command (user auto-deleted after)
$ --isolated-user -- npm test

# Custom username for isolated user
$ --isolated-user myrunner -- npm start
$ -u myrunner -- npm start

# Combine with screen isolation
$ --isolated screen --isolated-user -- npm test

# Combine with tmux detached mode
$ -i tmux -d --isolated-user testuser -- npm run build

# Keep user after command completes
$ --isolated-user --keep-user -- npm test
```

Benefits:

- Clean user environment for each run
- Inherits sudo/docker access from current user
- Files created during execution belong to isolated user
- Automatic cleanup after execution (unless --keep-user)

#### 6.7 Auto-Exit Behavior

By default, all isolation environments (screen, tmux, docker) automatically exit after the target command completes execution. This ensures:

Expand All @@ -180,10 +225,11 @@ The `--auto-remove-docker-container` flag enables automatic removal of the conta

Note: `--auto-remove-docker-container` is only valid with `--isolated docker` and is independent of the `--keep-alive` flag.

#### 6.6 Graceful Degradation
#### 6.8 Graceful Degradation

- If isolation backend is not installed, show informative error with installation instructions
- If session creation fails, report error with details
- If sudo fails due to password requirement, command will fail with sudo error

## Configuration Options

Expand Down
83 changes: 83 additions & 0 deletions experiments/user-isolation-research.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# User Isolation Research

## Issue #30: Support user isolation

### Understanding the Requirement

Based on the issue description:

> We need to find a way to support not only isolation in screen, but also isolation by user at the same time.

And the clarification from the user:

> No, there is no way to use existing user to run the command, user isolation should mean we create user - run command using this user, after command have finished we can delete user, unless we have `--keep-user` option.

This means:

1. Running commands in isolated environments (screen, tmux, docker) - **ALREADY IMPLEMENTED**
2. Creating new isolated users with same permissions as current user - **IMPLEMENTED**
3. Automatic cleanup of isolated users after command completes - **IMPLEMENTED**
4. Option to keep the user (`--keep-user`) - **IMPLEMENTED**

### Related Issues

- Issue #31: Support ssh isolation (execute commands on remote ssh servers)
- Issue #9: Isolation support (closed - implemented screen/tmux/docker)

### Final Implementation

The `--isolated-user` option creates a new isolated user with the same group memberships as the current user:

```bash
# Create isolated user and run command (user auto-deleted after)
$ --isolated-user -- npm test

# Custom username for isolated user
$ --isolated-user myrunner -- npm start
$ -u myrunner -- npm start

# Combine with screen isolation
$ --isolated screen --isolated-user -- npm test

# Combine with tmux detached mode
$ -i tmux -d --isolated-user testuser -- npm run build

# Keep user after command completes
$ --isolated-user --keep-user -- npm test
```

### How It Works

1. **User Creation**
- Creates new system user with same group memberships as current user
- Inherits sudo, docker, wheel, admin, and other groups
- Uses `sudo useradd` with `-G` flag for groups

2. **Command Execution**
- For screen/tmux: Wraps command with `sudo -n -u <user>`
- For standalone (no isolation backend): Uses `sudo -n -u <user> sh -c '<command>'`

3. **Cleanup**
- After command completes, user is deleted with `sudo userdel -r <user>`
- Unless `--keep-user` flag is specified

### Requirements

- `sudo` access with NOPASSWD configuration for:
- `useradd` - to create the isolated user
- `userdel` - to delete the isolated user
- `sudo -u` - to run commands as the isolated user

### Benefits

- Clean user environment for each run
- Inherits sudo/docker access from current user
- Files created during execution belong to isolated user
- Automatic cleanup after execution (unless --keep-user)
- Prevents untrusted code from affecting your user's files

### Limitations

- Not supported with Docker isolation (Docker has its own user isolation mechanism)
- Requires sudo NOPASSWD configuration
- Only works on Unix-like systems (Linux, macOS)
Loading
Loading