feat(telegram): ADMIN_USER_ID may /impersonate another user
While on, the admin's updates are routed as the target user's (allow-list, chat, workspace, session, settings, jobs) and the target chat's output goes to the admin's chat. The target's own updates are dropped with a notice that an admin is working with their account. In memory; /impersonate 0 stops.
This commit is contained in:
@@ -29,6 +29,7 @@ settings use the `GoogleCalendar` section, the scheduler the `Scheduler` section
|
||||
|---|---|---|
|
||||
| `TELEGRAM_BOT_TOKEN` / `Telegram:BotToken` | — | Required |
|
||||
| `TELEGRAM_ALLOWED_USER_IDS` / `Telegram:AllowedUserIds` | — | Required, comma separated. The bot refuses to start without it |
|
||||
| `ADMIN_USER_ID` / `Telegram:AdminUserId` | — (off) | The Telegram user id that may use `/impersonate` (see [Impersonation](#impersonation)). Need not be on the allow-list. Must be positive |
|
||||
| `Telegram:WorkspaceRoot` | `~/.volcanic/telegram-workspaces` | Chat `<id>` works in `<root>/<id>`; put `AGENTS.md`, `PERSONA.md`, `MEMORY.md` there |
|
||||
| `Telegram:Model` | `claude-code/claude-opus-5-5` | Any `provider/model` the Claude Code provider serves |
|
||||
| `Telegram:EditInterval` | `00:00:01.5` | Minimum time between edits of the "Working..." status message |
|
||||
@@ -205,6 +206,22 @@ the current format, and keeps the original next to it as `jobs.json.secretary-<t
|
||||
Copy the workspace's `scripts/` into the owner's workspace too: watcher commands such as `python scripts/check.py` run
|
||||
from there. A one-off that is already due fires on the first start.
|
||||
|
||||
### Impersonation
|
||||
|
||||
The admin (`ADMIN_USER_ID`) can act as another user with `/impersonate <user_id>`; `/impersonate 0` (or the admin's
|
||||
own id) stops. The command shows up in the admin's command menu only, and from anyone else it is an ordinary unknown
|
||||
command passed to the agent.
|
||||
|
||||
While it is on, the bot treats the admin's messages, commands, button presses and answers exactly as the target user's:
|
||||
the allow-list check (impersonating someone outside it means the bot ignores the admin until they stop), the chat, its
|
||||
workspace, session, time zone, jobs and calendar. Everything the target's chat sends goes to the admin's chat instead:
|
||||
replies, questions, files, notices and scheduled deliveries, including runs started by the target user's own messages.
|
||||
Meanwhile the target user is blocked: whatever they send (messages, commands, button presses) is dropped, and the bot
|
||||
answers "🔒 An admin is working with your account right now. Please try again later." The admin's own chat (their own jobs, for
|
||||
example) keeps working as before.
|
||||
|
||||
Impersonation is kept in memory only: a restart ends it.
|
||||
|
||||
### Google Calendar
|
||||
|
||||
Each chat connects its own Google account with `/calendar_connect`, and the agent's `calendar` tool only uses that
|
||||
@@ -215,7 +232,8 @@ storage and time zones are in [google-calendar.md](google-calendar.md).
|
||||
## Security
|
||||
|
||||
The agent has the built-in tools, including `bash`, and runs them as the bot's OS user. Only allow-listed user ids
|
||||
are served (everyone else is ignored and logged), and only in private chats. Run it in the container image
|
||||
are served (everyone else is ignored and logged), and only in private chats. `ADMIN_USER_ID` can act as any
|
||||
allow-listed user with `/impersonate`, so it gets that user's workspace, sessions, jobs and connected calendar. Run it in the container image
|
||||
([docker.md](docker.md)), which is the recommended setup, or at least as a dedicated user, and treat the workspace root
|
||||
as writable by anyone on the allow-list.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user