Skip to content

Per-user allowed workspaces via Telegram commands #202

@dcellison

Description

@dcellison

Problem

ALLOWED_WORKSPACES is a global env var (comma-separated paths) that applies to all users. WORKSPACE_BASE is also global. In multi-user, each user has repos in different locations and needs their own workspace base and allowed paths.

Currently, if a user has repos outside WORKSPACE_BASE, they must ask the machine owner to add paths to ALLOWED_WORKSPACES in the env file. This breaks the principle that workspace management is fully Telegram-driven.

Parent issue: #196 (sub-issue #4)

Proposal

Two changes:

1. Move WORKSPACE_BASE to per-user workspace_base in users.yaml

Each user gets their own base directory for /workspace new and short-name resolution:

users:
  - telegram_id: 2114582497
    name: Daniel
    workspace_base: /Users/kai/Projects

The admin sets this during onboarding (the config wizard in #193 prompts for it). /workspace new <name> creates directories under this user's workspace_base.

2. User-managed allowed workspaces via Telegram

Users add and remove paths outside their workspace_base via Telegram commands. The filesystem (os_user permissions) is the security boundary, not an allowlist.

Commands

/workspace allow <path>         - add an allowed workspace path
/workspace deny <path>          - remove an allowed workspace path
/workspace allowed              - list all allowed workspaces (workspace_base + explicit allows)

Validation

  • /workspace allow checks that the path exists and is a directory
  • Path must be readable by the user's os_user (if os_user isolation is active)
  • Absolute paths required (the current workspace command rejects them for name-based switching, but /workspace allow specifically needs them)
  • Duplicate detection (don't add a path that's already under workspace_base or already allowed)

Storage

Allowed workspaces stored in the database per-user. Options:

  1. Settings table with a list key: allowed_workspaces:{chat_id} = JSON array of paths
  2. New allowed_workspaces table: (chat_id, path) pairs

Option 2 is cleaner for add/remove operations and avoids JSON parsing.

Impact on /workspace name resolution

Currently /workspace <name> searches WORKSPACE_BASE then ALLOWED_WORKSPACES. The new flow:

  1. Search the user's workspace_base (from users.yaml)
  2. Search the user's allowed workspaces (from database)
  3. Match by directory name in both cases

Backward compatibility

  • WORKSPACE_BASE env var becomes the global fallback for users who don't have workspace_base in users.yaml
  • ALLOWED_WORKSPACES env var becomes the global fallback for users who haven't added any via Telegram
  • Existing single-user installs work unchanged

Deprecation

After migration period:

  • WORKSPACE_BASE removed from env, replaced by per-user workspace_base in users.yaml
  • ALLOWED_WORKSPACES removed from env, replaced by database storage

Context

  • Current workspace switching: bot.py lines 1020-1117 (handle_workspace)
  • Workspace name resolution: searches WORKSPACE_BASE then ALLOWED_WORKSPACES
  • Config: WORKSPACE_BASE and ALLOWED_WORKSPACES loaded in config.py
  • UserConfig dataclass: config.py lines 86-111 (needs workspace_base field added)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions