Skip to content

Install on Linux ​

The qorin-agent on Linux runs as a systemd service. In the system (multi-user) mode it carries CAP_SETUID + CAP_SETGID so it can drop privileges to the requesting Qorin user before spawning any CLI — the same per-user isolation model as macOS, with native Linux primitives.

Requirements ​

  • A modern Linux (kernel ≥ 5.4, systemd ≥ 245). Tested on Ubuntu 22.04, Debian 12, Fedora 39, Arch.
  • A CLI coding agent installed and authenticated for the OS user that will run workspaces — at least one of claude, codex, cursor-agent, gemini, opencode.
  • sudo. There is no user-mode install: the agent is a system service, and both the installer and qorin-agent service install require root.

1. One command ​

sh
curl -fsSL https://dl.qorin.dev/install.sh | sudo sh

That is the whole install. The script:

  1. downloads qorin-agent-linux-amd64 / -arm64, verifies it against dl.qorin.dev/SHA256SUMS, and puts it in /usr/local/bin;
  2. signs this machine in to your Qorin account — it opens the browser, or prints a link to open elsewhere when there is no desktop (SSH, headless; see below);
  3. writes /etc/systemd/system/qorin-agent.service with AmbientCapabilities=CAP_SETUID CAP_SETGID, enables and starts it, and checks that it is actually running before it says so.

It prints what it is about to do before the first privileged action; QORIN_DRY_RUN=1 prints the plan and stops.

Binary/usr/local/bin/qorin-agent
Servicesystemd unit, starts at boot, survives logout
Runs asroot — it drops to each person's own UNIX user for their work
Needs sudoyes — the installer re-runs itself under sudo if you forget
Why not ~/.local/binthe service runs as root, and a home directory is neither readable by root nor stable across users

Root is required, and there is no lesser mode

There used to be a systemd --user install that ran without root. It is gone (ADR-022): a per-user agent is a Qorin presence the machine's owner never authorised, and a machine you cannot see you cannot control. One machine now runs exactly one agent, owned by whoever controls the machine.

It also removes a whole class of "it stopped overnight": a --user unit dies at logout unless you remember loginctl enable-linger. A system unit is started by PID 1 and survives by construction.

If you already have a --user unit, the root install removes it for you.

From the dashboard: the same command, with your token ​

Agents → Connect an agent in the dashboard (web, phone or Mac) shows the same command carrying a one-shot token:

sh
curl -fsSL https://dl.qorin.dev/install.sh | sudo sh -s -- --token <token>

Same script, same three steps — except step 2 needs no browser: the token registers the machine with the organisation you were signed in to when you copied it. Tokens last 15 minutes and work once.

Already installed the binary some other way? ​

Then only the connect-and-run half is missing — and it is one command too:

sh
sudo qorin-agent install             # sign in in the browser, then service
sudo qorin-agent enroll <token>      # or: with a token from the dashboard

Both refuse to run on a machine that is already connected — that machine belongs to an organisation, and moving it would cut its workspaces off from their owners. To add yourself to a connected machine, see Users & identity below; to move it, sudo qorin-agent logout first.

Just trying it out ​

sh
qorin-agent serve     # foreground; stops when you close the terminal

Verify ​

The dashboard sidebar should list the host as online. If not:

sh
qorin-agent doctor                        # what the agent itself can see
sudo journalctl -u qorin-agent -n 50      # the service's own log

… or see troubleshooting › Agent shows offline.

Users & identity — what counts is who logs in ​

Installing the daemon (root) and who you are are two separate things. Your identity on a host = the UNIX user who ran the command — so a workspace runs as that user (via setuid from the daemon), with their $HOME, dotfiles, and CLI auth:

  • sudo qorin-agent install from your account → you're mapped to your user (sudo's $SUDO_USER), not root.
  • run it as root (no sudo) → you're mapped to root (this only works if claude/codex/… are installed and authenticated for root).

That mapping is created automatically when you log in/enroll — no separate dashboard step. The first workspace just works.

Adding more people (self-service) ​

Il primo login è diverso da tutti gli altri, ed è l'unico che vuole sudo:

chicomandocosa fa
chi installa, una voltasudo qorin-agent loginregistra la macchina su Qorin
chiunque altro, sempreqorin-agent loginsi registra per sé, subito operativo

sudo serve perché registrare la macchina significa scrivere le credenziali del servizio e avviare un daemon di sistema: è un atto di amministrazione della macchina, non un'identità. Chi lo esegue non viene registrato come root — Qorin legge SUDO_USER, quindi resta mappato al proprio utente e i suoi workspace girano come lui.

Linux is the canonical multi-user target. Once the machine is enrolled, adding a teammate takes one command and one click:

  1. Make sure their UNIX user exists on the host (useradd alice — Qorin doesn't create OS users for you).
  2. The teammate runs this on the host, as their own UNIX user — no sudo, no token to pass around:
    sh
    qorin-agent login
    The agent already knows which machine it is, so login on a machine that's connected means "let me use this one", not "enrol it again". That's it — no approval step. Every workspace alice spawns runs as alice, and she appears in the dashboard under the agent's People, where an admin can suspend or remove her at any time.

Why no approval?

Because it wouldn't protect anything. alice already has a shell on that machine as alice: she can open her files and run claude or codex by hand in the same directory. Qorin isn't granting her access — it's making the access she already has comfortable to use. A gate that stops the convenient path and not the actual one is friction, not security.

What the gate does protect is the machine's enrolment, which needs root, and the ability to keep someone out afterwards — the People list, where suspending takes two seconds.

Plans follow the person, not the machine. Someone from another organization can work on your host, and their own subscription decides what they get (concurrent workspaces, worktree mode, zero-knowledge). An organization in Qorin is a billing and licensing unit, not a fence around a machine.

Agents older than build 41 don't publish their identity yet, so login there still refuses and asks for a token. Host owner → Manage users → Generate a join command instead, then the teammate runs it on the host:

sh
qorin-agent join TOKEN

Upgrading the agent (sudo qorin-agent upgrade) removes the step.

(You can still map someone by hand in Manage users — type their Qorin member + UNIX username. Mapping to root is allowed but warned.) The per-user setuid requires the system service (it needs root/CAP_SETUID).

Projects outside $HOME (e.g. /var/www) ​

The folder picker shows each user's $HOME by default — so the UI can't wander into /etc, other users' homes, etc. On servers, projects often live outside home (/var/www, /opt, /srv). Expose extra browsable roots from the dashboard — no SSH needed:

  1. Hover the host in the sidebar → click the 📁 (browse roots) button.
  2. Add an absolute directory (e.g. /var/www) → Save.

The picker then shows Home / /var/www / … as quick-jump chips. Only the account owner can change this list. It's empty by default, so it never weakens the per-user isolation default.

Browsing — and creating folders — runs as the requesting UNIX user (the same setuid mapping used to spawn the CLI), so what's actually reachable is bounded by that user's permissions. System paths (/, /etc, /root, /proc, …) are always blocked, regardless of configuration. Make sure the spawn user can read/write the folder you intend to work in.

Headless fallback (QORIN_EXTRA_ROOTS) ​

For unattended setups you can also pin roots host-locally via an env var (:-separated absolute dirs) — these layer under the dashboard config:

sh
sudo systemctl edit qorin-agent
# add under [Service]:
#   Environment=QORIN_EXTRA_ROOTS=/var/www:/opt
sudo systemctl restart qorin-agent

Headless / VPS install ​

The flow above works on a remote VPS with no display:

  • Add --no-browser to the install/login command and it prints the URL to copy into your local browser; it polls and waits.
  • CLI auth (claude login, etc.) often opens a browser too — SSH-tunnel back to your laptop if needed and run the login from the VPS terminal; the CLI prints a URL you open locally.

Update ​

sh
qorin-agent upgrade        # or click Update on the host in the dashboard

Uninstall ​

sh
qorin-agent uninstall                 # leave + revoke, keep the binary
sudo qorin-agent uninstall --purge    # complete removal (binary, data, logs, service user)

Next: Add your first host →

Qorin is built by Benito Borriello.