0a4531f02d
The local sandbox is dropped before it was built. Every hard problem in it came from running on the machine that holds the database and the encryption key: the service user cannot traverse /home, granting it needs ACLs, RLIMIT_NPROC is counted per uid so a fork bomb starves the server too, --size only applies to tmpfs so there is no disk quota, and the bind list is a standing invitation to widen until the sandbox is decoration. Over SSH, isolation is somebody's considered choice of host -- a throwaway container with one project mounted into it -- using tools far better at it than anything that could be built here. It is also the only version that is honestly multi-user: each person brings their own credentials and their own machine, and picks a project directory on it. So ProtectKernelTunables goes back. It was removed for exactly one reason, that bubblewrap cannot mount /proc without it, and that reason is gone. The agents settings group loses everything bwrap-shaped with it. What this costs, and the admin copy has to say so: there was a network:False switch that made exfiltration from a compromised reply impossible, and over SSH there is no equivalent, because the network belongs to the far side. The security of an agent chat is now the security of the host behind its profile, and LLeMbas cannot tell a scratch container from a live server. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
55 lines
1.8 KiB
Desktop File
55 lines
1.8 KiB
Desktop File
# LLeMbas system service template.
|
|
#
|
|
# install.sh substitutes __PREFIX__ and __SERVICE_USER__ and writes the result
|
|
# to /etc/systemd/system/lembas.service. Edit this file, not the installed copy.
|
|
#
|
|
# A system unit, not a user unit, so it survives logout and comes up at boot
|
|
# without anyone signing in.
|
|
|
|
[Unit]
|
|
Description=LLeMbas - web UI for language models
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
# The prefix is usually a bind mount; the venv and database live there, so
|
|
# starting before it is mounted would create an empty database in its place.
|
|
RequiresMountsFor=__PREFIX__
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=__SERVICE_USER__
|
|
Group=__SERVICE_USER__
|
|
WorkingDirectory=__PREFIX__/app
|
|
EnvironmentFile=__PREFIX__/lembas.env
|
|
ExecStart=__PREFIX__/venv/bin/lembas serve
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
|
|
# The bind address comes from LEMBAS_HOST in the environment file, which the
|
|
# installer sets to 127.0.0.1: reachable through nginx, never directly.
|
|
|
|
# --- Hardening -------------------------------------------------------------
|
|
# Agent chats run their commands over SSH, on a machine somebody chose and
|
|
# prepared -- a container, a VM, another host. Nothing an agent does executes
|
|
# here, which is what lets this stay locked down rather than being opened up to
|
|
# make room for a sandbox.
|
|
#
|
|
# ProtectSystem stays `full` rather than `strict` only because the data
|
|
# directory has to be writable and `strict` would need every path spelled out.
|
|
NoNewPrivileges=yes
|
|
PrivateTmp=yes
|
|
ProtectSystem=full
|
|
ProtectKernelTunables=yes
|
|
ProtectControlGroups=yes
|
|
RestrictSUIDSGID=yes
|
|
ReadWritePaths=__PREFIX__
|
|
LimitNOFILE=65535
|
|
|
|
# Bounds on the service as a whole. Not aimed at anything in particular; a web
|
|
# application that has grown a habit of holding network connections open is
|
|
# worth a ceiling.
|
|
TasksMax=2048
|
|
MemoryMax=8G
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|