Loading content…
Loading content…
Manage Debian/Ubuntu via Telegram: agent sessions, maintenance with human confirmation, temporary root, and sustained alerts.
Linux Agent allows managing Debian and Ubuntu servers from Telegram. It integrates
agent sessions, package and service maintenance, temporary privilege elevation and
monitoring with alerts. It requires systemd, Python 3.11 or later
and sudo with support for NOTAFTER.
linux-agent-bot): validates owner and private chat,
stores the token and requires single-use confirmations that expire in two minutes.linux-agent): separate account without privileged groups or general
sudo. Codex app-server manages persistent sessions and runtime approvals.
The relay only allows registering topics, delivering responses and reading/acknowledging messages./root 15m shows a confirmation. The root helper validates
between one minute and eight hours, generates a rule with NOTAFTER, disables the sudo
cache and schedules its removal. /root off revokes new elevations. When the
server starts, the window closes. The model has no access to the bot token or
to the component that grants the window.Download linux-agent-0.1.0.agent.json from the catalog entry. The files field
contains the file tree and its content. You can view them in the viewer or
extract them into a new folder with the following command. Account, permission and service configuration is done in the subsequent steps.
python3 - linux-agent-0.1.0.agent.json linux-agent <<'PYTHON'
import json, pathlib, sys
snapshot = json.loads(pathlib.Path(sys.argv[1]).read_text())
root = pathlib.Path(sys.argv[2]).resolve()
root.mkdir(mode=0o700, exist_ok=False)
def write(nodes, parent):
for node in nodes:
name = node["name"]
if not name or name in (".", "..") or "/" in name or "\\" in name:
raise ValueError("Invalid snapshot path")
target = parent / name
if node["type"] == "directory":
target.mkdir(mode=0o700)
write(node["children"], target)
elif node["type"] == "file":
with target.open("x", encoding="utf-8") as output:
output.write(node["content"])
target.chmod(0o600)
else:
raise ValueError("Invalid snapshot node")
write(snapshot["files"], root)
PYTHON
cd linux-agent
sha256sum -c SHA256SUMS
Keep an independent administrative SSH session during configuration.
See the verification scenarios in VALIDATION.md.
As administrator, prepare two new system accounts, without privileged groups
or login shell: linux-agent, with HOME /var/lib/linux-agent, and
linux-agent-bot, with state /var/lib/linux-agent-bot. Both directories belong to their
respective account and have mode 0700.
Copy the Python modules into /opt/linux-agent and the wrappers from bin into its
bin subdirectory: all root:root, Python 0644 and wrappers 0755. Check that the
wrappers point to those paths. Copy HARNESS.md as /opt/linux-agent/HARNESS.md.
Prepare /opt/linux-agent/workspace root:root 0755 and copy HARNESS.md there as
AGENTS.md root:root 0644. Only workspace/work belongs to linux-agent, mode 0700.
The root-owned parent prevents replacing the harness by deleting it from an owned folder.
Create /etc/linux-agent root:root 0755. Copy configuration/server.json and
configuration/runtime.json with mode 0644 and configuration/telegram.env.example
as telegram.env, root:linux-agent-bot 0640. Enter the bot token and the
owner and chat identifiers in that file. Enable private topics
in BotFather. Define the allowed services, mounts and alarm thresholds.
Keep the token out of command arguments and logs.
Create /var/lib/linux-agent-ops root:linux-agent-bot 2750. Check the sudoers file
with visudo -cf, copy it as /etc/sudoers.d/linux-agent root:root 0440 and verify
visudo -c. Do not extend the rules to shells or arbitrary arguments.Install a reviewed version of Codex in a root-owned path, adjust runtime.json
and authenticate it as linux-agent using its HOME. Configure the provider and the model
according to your environment. New sessions use workspace-write with approval
on-request.
Copy the units from systemd into /etc/systemd/system, root:root 0644. After
reviewing them, reload systemd and enable root shutdown at boot before the bot:
sudo systemctl daemon-reload
sudo systemctl enable --now linux-agent-root-disable.service
sudo systemctl enable --now linux-agent-bot.service
sudo systemctl enable --now linux-agent-bridge.service linux-agent-monitor.timer
Check the status of the services and the permissions of their files. In the authorized
chat, run /help, /status and /new Mi servidor. Each session is
associated with its topic; a failure to create it interrupts the operation.
Send documents or images in the topic of a registered session. Attachments are verified and stored with 0600 permissions in 0700 directories separated per session. The agent receives their local paths; PNG/JPEG images are also delivered as visual inputs. Paths remain stable on retry and files are preserved after confirming receipt. The limit per document and per message is 8 MiB. The content of attachments is treated as untrusted data.
To return a document created in the workspace:
/opt/linux-agent/bin/send-file /opt/linux-agent/workspace/work/report.zip --thread SESSION_ID
The utility confirms delivery only when Telegram accepts it. To retry
the same delivery, keep a key with --key REQUEST_ID; a delivery confirmed
with that key is not repeated. Use regular workspace paths, without symbolic
links. Review the content before sending it and exclude secrets. The integration
can be configured in the agent following HARNESS.md.
A delivery failure keeps the message pending and postpones only that session. The others keep working. The bridge updates its heartbeat during work; runtime approvals remain tied to their session and expire in two minutes.
| Command | Behavior |
|---|---|
/new nombre | Creates an agent session/topic |
/sessions | Lists the registered sessions |
/status | Shows monitoring, the last job result and remaining root |
/updates | Simulates the upgrade with the available APT index |
/root 15m, /root 2h | Requests temporary root; requires confirmation |
/root status, /root off | Queries/revokes new elevations |
/refresh | Refreshes the APT index; confirmation + root |
/upgrade | apt-get upgrade --with-new-pkgs; confirmation + root |
/restart nombre.service | Restarts an allowed service; confirmation + root |
/reboot | Schedules a restart in one minute; confirmation + root |
/agentstop | Requests stopping the turn in its topic; does not kill the daemon |
/approve token, /deny token | Responds to a runtime approval in its session |
Maintenance operations run asynchronously. Check /status
to verify their completion and check the affected service. The full log
is kept in /var/lib/linux-agent-ops/last-operation.log, accessible to the
administrator; Telegram shows the status and result of the operation.
Prepare a backup and a restoration procedure before upgrading packages:
recovery is performed using that procedure.
The code, units, policy and harness are root-owned. The agent cannot modify them without elevation. The AGENTS.md file describes the expected behavior; accounts, permissions and helpers constitute the technical barrier.
Full root can modify the harness, read secrets or create persistence.
NOTAFTER prevents new sudo invocations after expiry, even if the timer fails,
but does not stop already elevated processes or revert their changes. Isolation from
a process with root requires a separate VM and external authorization. Runtime permissions are another layer:
a sudo window does not automatically disable its sandbox or its approvals.
Runtime permissions are configured independently of sudo. The bot's predefined
administrative tasks run through its helpers; the runtime's initial
configuration keeps workspace-write and on-request.
Telegram and the Internet connection are external dependencies: a server that is down, without network or with a broken bot cannot alert about itself. For that situation use an independent external monitor. systemd restarts crashed processes; healthy turns are not restarted due to a delayed heartbeat. The local monitor warns of a disconnected bridge.## Verification and removal
PYTHONPATH=. python3 -m unittest discover -s tests
Before production, test: wrong owner/group rejected; confirmation expired/repeated/from another topic; root closed/open/expired/revoked/after reboot; code, token and sudo permissions; maintenance lock; simulated package in VM; sustained alarm and recovery; runtime crash/restart; routing between two topics; attachment reception, rejection of invalid paths, confirmed document delivery and retries of one session without blocking the others. Do not use a real update or restart to test a production bot.
To remove: close root from your independent administrative access, stop and
disable linux-agent-bot, linux-agent-bridge and linux-agent-monitor.timer, and
remove rules/units after verifying that no elevated jobs or processes remain.
Revoke the token in BotFather and the provider credentials. Keep private
audit; do not delete backups automatically.
Linux Agent 0.1.0 is distributed under the AGPL-3.0-only license. See LICENSE
for the terms and VALIDATION.md for the checks performed.
| Version | Downloads (weekly) | Downloads (total) | Published |
|---|---|---|---|
0.1.0latest First published version. | 0 | 3 | October 12, 2026 |
Linux Agent allows managing Debian and Ubuntu servers from Telegram. It integrates
agent sessions, package and service maintenance, temporary privilege elevation and
monitoring with alerts. It requires systemd, Python 3.11 or later
and sudo with support for NOTAFTER.
linux-agent-bot): validates owner and private chat,
stores the token and requires single-use confirmations that expire in two minutes.linux-agent): separate account without privileged groups or general
sudo. Codex app-server manages persistent sessions and runtime approvals.
The relay only allows registering topics, delivering responses and reading/acknowledging messages./root 15m shows a confirmation. The root helper validates
between one minute and eight hours, generates a rule with NOTAFTER, disables the sudo
cache and schedules its removal. /root off revokes new elevations. When the
server starts, the window closes. The model has no access to the bot token or
to the component that grants the window.Download linux-agent-0.1.0.agent.json from the catalog entry. The files field
contains the file tree and its content. You can view them in the viewer or
extract them into a new folder with the following command. Account, permission and service configuration is done in the subsequent steps.
python3 - linux-agent-0.1.0.agent.json linux-agent <<'PYTHON'
import json, pathlib, sys
snapshot = json.loads(pathlib.Path(sys.argv[1]).read_text())
root = pathlib.Path(sys.argv[2]).resolve()
root.mkdir(mode=0o700, exist_ok=False)
def write(nodes, parent):
for node in nodes:
name = node["name"]
if not name or name in (".", "..") or "/" in name or "\\" in name:
raise ValueError("Invalid snapshot path")
target = parent / name
if node["type"] == "directory":
target.mkdir(mode=0o700)
write(node["children"], target)
elif node["type"] == "file":
with target.open("x", encoding="utf-8") as output:
output.write(node["content"])
target.chmod(0o600)
else:
raise ValueError("Invalid snapshot node")
write(snapshot["files"], root)
PYTHON
cd linux-agent
sha256sum -c SHA256SUMS
Keep an independent administrative SSH session during configuration.
See the verification scenarios in VALIDATION.md.
As administrator, prepare two new system accounts, without privileged groups
or login shell: linux-agent, with HOME /var/lib/linux-agent, and
linux-agent-bot, with state /var/lib/linux-agent-bot. Both directories belong to their
respective account and have mode 0700.
Copy the Python modules into /opt/linux-agent and the wrappers from bin into its
bin subdirectory: all root:root, Python 0644 and wrappers 0755. Check that the
wrappers point to those paths. Copy HARNESS.md as /opt/linux-agent/HARNESS.md.
Prepare /opt/linux-agent/workspace root:root 0755 and copy HARNESS.md there as
AGENTS.md root:root 0644. Only workspace/work belongs to linux-agent, mode 0700.
The root-owned parent prevents replacing the harness by deleting it from an owned folder.
Create /etc/linux-agent root:root 0755. Copy configuration/server.json and
configuration/runtime.json with mode 0644 and configuration/telegram.env.example
as telegram.env, root:linux-agent-bot 0640. Enter the bot token and the
owner and chat identifiers in that file. Enable private topics
in BotFather. Define the allowed services, mounts and alarm thresholds.
Keep the token out of command arguments and logs.
Create /var/lib/linux-agent-ops root:linux-agent-bot 2750. Check the sudoers file
with visudo -cf, copy it as /etc/sudoers.d/linux-agent root:root 0440 and verify
visudo -c. Do not extend the rules to shells or arbitrary arguments.Install a reviewed version of Codex in a root-owned path, adjust runtime.json
and authenticate it as linux-agent using its HOME. Configure the provider and the model
according to your environment. New sessions use workspace-write with approval
on-request.
Copy the units from systemd into /etc/systemd/system, root:root 0644. After
reviewing them, reload systemd and enable root shutdown at boot before the bot:
sudo systemctl daemon-reload
sudo systemctl enable --now linux-agent-root-disable.service
sudo systemctl enable --now linux-agent-bot.service
sudo systemctl enable --now linux-agent-bridge.service linux-agent-monitor.timer
Check the status of the services and the permissions of their files. In the authorized
chat, run /help, /status and /new Mi servidor. Each session is
associated with its topic; a failure to create it interrupts the operation.
Send documents or images in the topic of a registered session. Attachments are verified and stored with 0600 permissions in 0700 directories separated per session. The agent receives their local paths; PNG/JPEG images are also delivered as visual inputs. Paths remain stable on retry and files are preserved after confirming receipt. The limit per document and per message is 8 MiB. The content of attachments is treated as untrusted data.
To return a document created in the workspace:
/opt/linux-agent/bin/send-file /opt/linux-agent/workspace/work/report.zip --thread SESSION_ID
The utility confirms delivery only when Telegram accepts it. To retry
the same delivery, keep a key with --key REQUEST_ID; a delivery confirmed
with that key is not repeated. Use regular workspace paths, without symbolic
links. Review the content before sending it and exclude secrets. The integration
can be configured in the agent following HARNESS.md.
A delivery failure keeps the message pending and postpones only that session. The others keep working. The bridge updates its heartbeat during work; runtime approvals remain tied to their session and expire in two minutes.
| Command | Behavior |
|---|---|
/new nombre | Creates an agent session/topic |
/sessions | Lists the registered sessions |
/status | Shows monitoring, the last job result and remaining root |
/updates | Simulates the upgrade with the available APT index |
/root 15m, /root 2h | Requests temporary root; requires confirmation |
/root status, /root off | Queries/revokes new elevations |
/refresh | Refreshes the APT index; confirmation + root |
/upgrade | apt-get upgrade --with-new-pkgs; confirmation + root |
/restart nombre.service | Restarts an allowed service; confirmation + root |
/reboot | Schedules a restart in one minute; confirmation + root |
/agentstop | Requests stopping the turn in its topic; does not kill the daemon |
/approve token, /deny token | Responds to a runtime approval in its session |
Maintenance operations run asynchronously. Check /status
to verify their completion and check the affected service. The full log
is kept in /var/lib/linux-agent-ops/last-operation.log, accessible to the
administrator; Telegram shows the status and result of the operation.
Prepare a backup and a restoration procedure before upgrading packages:
recovery is performed using that procedure.
The code, units, policy and harness are root-owned. The agent cannot modify them without elevation. The AGENTS.md file describes the expected behavior; accounts, permissions and helpers constitute the technical barrier.
Full root can modify the harness, read secrets or create persistence.
NOTAFTER prevents new sudo invocations after expiry, even if the timer fails,
but does not stop already elevated processes or revert their changes. Isolation from
a process with root requires a separate VM and external authorization. Runtime permissions are another layer:
a sudo window does not automatically disable its sandbox or its approvals.
Runtime permissions are configured independently of sudo. The bot's predefined
administrative tasks run through its helpers; the runtime's initial
configuration keeps workspace-write and on-request.
Telegram and the Internet connection are external dependencies: a server that is down, without network or with a broken bot cannot alert about itself. For that situation use an independent external monitor. systemd restarts crashed processes; healthy turns are not restarted due to a delayed heartbeat. The local monitor warns of a disconnected bridge.## Verification and removal
PYTHONPATH=. python3 -m unittest discover -s tests
Before production, test: wrong owner/group rejected; confirmation expired/repeated/from another topic; root closed/open/expired/revoked/after reboot; code, token and sudo permissions; maintenance lock; simulated package in VM; sustained alarm and recovery; runtime crash/restart; routing between two topics; attachment reception, rejection of invalid paths, confirmed document delivery and retries of one session without blocking the others. Do not use a real update or restart to test a production bot.
To remove: close root from your independent administrative access, stop and
disable linux-agent-bot, linux-agent-bridge and linux-agent-monitor.timer, and
remove rules/units after verifying that no elevated jobs or processes remain.
Revoke the token in BotFather and the provider credentials. Keep private
audit; do not delete backups automatically.
Linux Agent 0.1.0 is distributed under the AGPL-3.0-only license. See LICENSE
for the terms and VALIDATION.md for the checks performed.