Skip to content

Conversation

@mistercrunch
Copy link
Member

Summary

  • Moves Unix user/group/symlink management from daemon-only to packages/core for shared use by CLI and daemon
  • Introduces CommandExecutor abstraction to handle privilege escalation (direct CLI vs sudo-based daemon)
  • Wires up FeathersJS hooks for automatic Unix operations on data changes

Changes

Core Package (packages/core/src/unix/)

  • command-executor.ts - CommandExecutor interface with DirectExecutor, SudoCliExecutor, NoOpExecutor
  • user-manager.ts - Unix user utilities (generateUnixUsername(), UnixUserCommands)
  • symlink-manager.ts - Symlink utilities (SymlinkCommands, getWorktreeSymlinkPath())
  • unix-integration-service.ts - Main orchestration service with:
    • Worktree groups: createWorktreeGroup, deleteWorktreeGroup, addUserToWorktreeGroup, removeUserFromWorktreeGroup
    • User management: ensureUnixUser, deleteUnixUser
    • Symlinks: createWorktreeSymlink, removeWorktreeSymlink, syncUserSymlinks
    • Bulk ops: syncWorktree, syncUser, syncAll

CLI Admin Commands

  • admin ensure-user - Create Unix user if doesn't exist
  • admin delete-user - Delete Unix user
  • admin create-symlink - Create worktree symlink in user home
  • admin remove-symlink - Remove worktree symlink
  • admin sync-user-symlinks - Clean up broken symlinks

Daemon Integration

  • Refactored unix-integration.ts to re-export from core with SudoCliExecutor
  • Added app.set('unixIntegration', service) for cross-service access
  • Wired up after hooks in worktree-owners for auto group membership
  • Wired up after hooks in users for auto Unix user creation when unix_username is set

Test plan

  • Verify daemon starts with execution.worktree_rbac: true config
  • Test creating a worktree owner triggers group membership
  • Test removing a worktree owner removes group membership
  • Test creating a user with unix_username creates Unix user
  • Test CLI admin commands work with sudo

🤖 Generated with Claude Code

Moves Unix user/group/symlink management to packages/core for shared use by
CLI and daemon. Introduces CommandExecutor abstraction for privilege escalation.

Key changes:
- Add CommandExecutor interface with DirectExecutor, SudoCliExecutor, NoOpExecutor
- Add UnixIntegrationService with worktree groups, user management, symlinks
- Add user-manager.ts with Unix user utilities and command strings
- Add symlink-manager.ts with symlink utilities for worktree access
- Refactor daemon to use core service via factory pattern
- Wire up hooks in worktree-owners for auto group membership
- Wire up hooks in users service for auto Unix user creation
- Add CLI admin commands: ensure-user, delete-user, create/remove-symlink, sync-user-symlinks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Claude Code and others added 4 commits December 4, 2025 01:47
- Add AGOR_USERS_GROUP constant for managed user identification
- Add ensureAgorUsersGroup() to create group if not exists
- Add addUserToAgorUsersGroup/removeUserFromAgorUsersGroup methods
- Add isAgorManagedUser() to check group membership
- ensureUnixUser now adds users to agor_users group
- deleteUnixUser now removes users from agor_users group

This enables natural usernames (max instead of agor_max) while
maintaining security containment - daemon can only impersonate
users that are members of the agor_users group.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Adds comprehensive documentation for running Agor in full multiplayer
mode with Unix-level isolation:

- Overview of shared development environments and isolation benefits
- Security considerations (daemon privileges, API key exposure)
- Recommendations (VPN, trusted users, key rotation)
- Setup guide: PostgreSQL, volumes, sudoers, observability
- Permission levels reference (view/prompt/all)
- Troubleshooting common issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Add resolveUnixUserForImpersonation() for centralized mode-aware logic
- Add validateResolvedUnixUser() for user existence validation
- Refactor terminals.ts and index.ts to use centralized utilities
- Add comprehensive unit tests (111 tests) for Unix utilities:
  - user-manager.test.ts: username gen/parse, validation, impersonation
  - group-manager.test.ts: group names, permissions, command builders
  - symlink-manager.test.ts: paths, symlink info, command builders

The impersonation logic now consistently handles all 4 Unix user modes
(simple, insulated, opportunistic, strict) across terminal sessions
and executor spawning.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Remove CLI executor mode (not wired up, SudoCliExecutor expects
  `agor admin` subcommands that don't exist yet)
- Fix env file permissions: chown to impersonated user so they can
  source the file (was 0600 owned by daemon, unreadable after sudo -u)
- Pass homeBase to UnixUserCommands.createUser() so user homes are
  created in configured location, not always /home

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
- Remove SSH port exposure (use docker exec + sudo su instead)
- Add comment explaining how to test as alice/bob
- Wait for db type definitions in entrypoint (needed for migrations)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@mistercrunch mistercrunch merged commit 52e2417 into main Dec 5, 2025
1 check passed
@mistercrunch mistercrunch deleted the rbac-admin-sudo branch December 5, 2025 04:56
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.

2 participants