* Don't put the user in the docker group; make it opt-in The docker group is root-equivalent: anything in it can `docker run -v /:/host` and rewrite the host as root with no password. On a single-user box that's not an escalation (the owner is already a wheel/sudo user), but it hands any code running as the user — a rogue plugin, a poisoned dependency — a silent, headless, passwordless path to root that sudo's password prompt would otherwise gate. Stop granting the docker group by default. The daemon still runs (docker.socket); the Docker TUI and the Windows VM reach it through a polkit prompt, and the plain `docker` CLI runs under sudo. Sudoless Docker is a warned opt-in via Setup > Security (omarchy-setup-security-sudoless-docker). No automatic path may re-grant it: install and first-boot provisioning never record or apply the group (provisioning also filters a docker line left in an older factory snapshot), and the Quattro upgrade no longer adds it. The Windows VM keeps needing the root daemon for a privileged container (KVM, NET_ADMIN), so it is reworked to run without the group and without becoming a new way in: - The compose lives in a root-owned dir and is only written by an elevated, input-validated writer. A root-invoked bring-up must never consume a file a user-process could rewrite to bind-mount / into the guest — the old ~/.config/windows compose was exactly that. Volume paths are rebuilt from $HOME on migration rather than trusted from the (user-writable) legacy file, path validation rejects traversal, and the privileged sub-action is checked against an allowlist before dispatch (a slash in it would otherwise run as a path). - pkexec elevates a verified root-owned command path, not a PATH-resolved one, so an authorized prompt can't be redirected to an attacker's binary. - The guest password is kept in a private 0600 per-user file for RDP instead of a world-readable compose, and a declined authorization is reported as such, never as a completed stop. Existing installs auto-migrate the VM (no redownload) and refresh the stale Docker launcher entry. 🤖 Generated by Opus 4.8 in Claude Code. Reviewed by Codex XHigh. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-Authored-By: Codex XHigh <codex@openai.com> Claude-Session: https://claude.ai/code/session_01Gb7x6poap4hGCndPx5qt5T * Migrate existing installs off the docker group The default flip only reaches new installs; existing users keep their docker group membership and stay exposed. Extend the migration that already refreshes the Docker launcher to also remove the current user from the group when present, reusing omarchy-remove-security-sudoless-docker so there is one source of truth for the change and its notice. It takes effect at next login (the current session keeps working), and passwordless docker can be turned back on from Setup > Security > Sudoless Docker. Migrations run with sudo available — during `omarchy update`, or in the terminal the pending-migrations notification opens — so the privileged removal does not prompt at an unattended login. The no-op path (already out of the group) needs no privilege. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gb7x6poap4hGCndPx5qt5T * Refuse symlinked VM mount sources; correct the docker CLI docs Review follow-ups. valid_path keeps a traversal string (/./, //, ..) out of the compose, but it is a string check: a symlink planted at ~/.windows or ~/Windows redirects the privileged bind mount exactly as traversal would, because docker follows it. So verify the mount sources as root immediately before bringing the VM up — refuse a source that is a symlink or resolves through one — which is where the string check cannot help. A missing source stays fine (docker creates a plain dir). Also correct the development-tools manual: the CLI is not transparently elevated (there is no docker wrapper and `d` is still plain docker), so say plainly that docker on the command line takes `sudo` until sudoless Docker is enabled. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Gb7x6poap4hGCndPx5qt5T --------- Co-authored-by: David Heinemeier Hansson <david@hey.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Codex XHigh <codex@openai.com>
3.7 KiB
Development Tools
Alternative Editors
Omarchy ships with Neovim by default, but if you'd like something a bit more mainstream and familiar, you can run the Omarchy Menu (Super + Space) and see the options under Install > Editor. We have VSCode, Cursor, Zed, Sublime Text, Helix, Vim, and Emacs listed there. If you don't find what you're looking for, checkout Install > Package, and see if it isn't in an Arch package (and if not, try Install > AUR to check the AUR).
Theme matching is offered for VSCode, Cursor, VSCodium, and Helix.
You can set the system-wide default editor under Setup > Defaults > Editor.
Environment
Omarchy supports setting up a whole host of development environments through the Install > Development section of the Omarchy Menu (Super + Space). You'll of course find Ruby on Rails, but also all three major runtimes for JavaScript (Node.js, Bun, Deno), as well as popular PHP frameworks like Laravel and Symfony. Oh, and there's Go, Rust, Python, Java, Elixir (with Phoenix), .NET, OCaml, Zig, Clojure, and Scala too. It's a very broad selection!
The majority of these environments are managed by Mise. It's a tool that lets you install and run multiple versions of a programming language on the same machine. It's like rbenv or rvm for Ruby or virtualenv for Python, but it works for a bunch of different environments.
To install, say, Ruby, you'd run mise use -g ruby, which will both install Ruby and set it as the global default. Or, if your project has a .ruby-version file, you can just run mise i in the root of that project.
Docker
Docker hardly needs any introduction. It allows you to run isolated containers, and Omarchy installs everything needed to run it well, including Docker itself and Docker Compose.
By default your user is not in the docker group. That group is effectively passwordless root — anything in it can docker run -v /:/host and take over the machine — so a single rogue script or dependency running as you would otherwise be one command away from root. So on the command line you run Docker with sudo (sudo docker ps, sudo docker compose up), and the graphical tools that talk to the daemon — the Docker TUI on Super + Shift + D and the Windows VM — ask for authorization when they need it. If you want the convenience of a groupless setup back and understand the tradeoff, enable it from Setup > Security > Sudoless Docker (or run omarchy-setup-security-sudoless-docker), which adds you to the docker group after a warning; then plain docker and the d alias work without sudo again.
Remember to checkout the Lazydocker command to manage your containers in a cool TUI using Super + Shift + D; it asks for authorization the first time unless you have enabled sudoless Docker.
You can setup the common databases for local development in Docker using Install > Development > Docker DB in the Omarchy menu.
GitHub CLI
The GitHub CLI let's you authenticate with your GitHub account and clone private repositories using it. It's wired up as one of the lazy-loading mise stubs, so the first time you run gh, it installs itself. To authenticate, run gh auth login. Then you can checkout private repositories using gh repo clone org/repo.
You can also perform a bunch of other GitHub operations using this command. Just run gh to see everything that's possible.
There's a lazy-installing stub for ghui for managing your pull requests in a TUI too. And lazygit is preinstalled, if you'd like to drive git itself from a TUI as well.