Omarchy

Omarchy Runs Your Coding Agent With the Safety Off

Omarchy's launcher gives every coding agent a skip-approval flag by default. The attack surface a security lead inherits, and what Omarchy gets right.

In this post
  1. The launcher’s whole job is skipping the prompt
  2. Thirteen CLIs, thirteen credential stores
  3. The skill file that does privilege escalation on your behalf
  4. What can a core dump actually hand your coding agent?
  5. Usage sync is opt-in, but worth knowing about
  6. What Omarchy gets right, specifically
  7. What I’d require before this goes on a company laptop

TL;DR: I run Omarchy daily, and the thing that should get a second look before it lands on a company laptop isn’t the theming or the tiling window manager — it’s bin/omarchy-agent, the launcher that starts your default coding agent. Eleven of the fourteen agents it knows how to start get launched with their own spelling of “don’t stop to ask”: --dangerously-skip-permissions, --yolo, --permission-mode auto, --approve-for-me, --allow-all, --auto-approve. That’s the default keybinding, not an opt-in flag you have to discover — and the same launcher is one click away, too, off a crash notification. Thirteen agent CLIs come pre-wired with their own credential stores, a skill file draws a real (and correct) privilege-escalation line, and Omarchy’s own crash-diagnosis skill admits a core dump “can hold passwords, tokens, and private documents.” Omarchy also gets real things right: mandatory LUKS, a default-deny firewall, and a passwordless-sudo toggle that’s time-boxed, fail-closed, and can’t be armed non-interactively. This is the inventory a vCISO runs before signing off on either.

The launcher’s whole job is skipping the prompt

Omarchy ships omarchy-agent as the thing behind Super + Shift + Ctrl + A and the a shell alias. Open bin/omarchy-agent and the case statement that builds each agent’s command line tells most of the story:

opencode)
  command=(opencode --auto)
  ...
agy)
  command=(agy --dangerously-skip-permissions)
  ...
copilot)
  command=(copilot --allow-all)
  ...
crush)
  ...
  command=(crush --yolo)
  ;;
claude)
  command=(claude --permission-mode auto)
  ...
grok)
  command=(grok --permission-mode bypassPermissions)
  ...
codex)
  command=(codex --approve-for-me)
  ...
cursor-agent)
  command=(cursor-agent --yolo --trust)
  ...
hermes)
  ...
    command=(hermes --yolo)
  ...
muse)
  command=(muse --approval-mode never)
  ...
omp)
  command=(omp --auto-approve)

Eleven agents, nine flag names, one behavior: none of them stop to ask before running a command. Muse is the one worth a clause — its own comment says --approval-mode never “skips the tool prompts but keeps Muse’s own sandbox,” so it’s unattended by a narrower mechanism than the rest. Three arms in the same case statement carry no skip-approval flag at all: pi, ori, and openclaw. The launcher’s comment says “Pi and Ori have none to skip”; OpenClaw’s arm separately notes it “has no permission prompts to skip” in the first place, since its terminal UI attaches to an already-running gateway instead of prompting per command.

A second comment explains the redirect underneath all of this:

“Agents refuse to remember trust for $HOME, so launches from the keybinding or menu start in the work directory instead of re-asking on every session.”

followed by the line that does it:

[[ $PWD == "$HOME" && -d $HOME/Work ]] && cd "$HOME/Work"

Read that straight: the redirect trades a per-session re-prompt for a persistent trusted directory, which is a reasonable trade — the agent’s own trust prompt still fires once for ~/Work, and moving an unattended agent out of $HOME narrows what it can reach by default rather than widening it. The real security question isn’t the redirect. It’s that the directory the agent lands in trusted is entered with the skip-approval flag already set — whatever trust ~/Work earns, the agent arrives able to act on it without asking again.

The manual documents the whole pattern as a feature, not a caveat: “Agents launched this way run unattended in their respective don’t-stop-to-ask modes, so be ready for them to actually do things! And since agents refuse to remember trust for your home directory, launches from $HOME start in ~/Work instead.” (manual/17-ai.md) That’s an honest warning label, and confirmation the behavior is intentional and two keystrokes away from a fresh install.

default/bash/aliases wires the same pattern straight into the shell:

alias a='omarchy-agent --inline'
alias c='opencode --auto'
# cx also clears the screen first (printf escape codes)
alias cx='claude --permission-mode auto'
alias cy='codex --approve-for-me'

a plus Enter is an unattended agent session. That’s a low floor for a muscle-memory mistake on the wrong terminal, in the wrong directory, on a laptop that also has your production credentials in it.

Thirteen CLIs, thirteen credential stores

I flagged the pre-wired agent roster as a curiosity in the M1 writeup; here’s the security read. The manual’s AI chapter tables out every agent pre-wired as a lazy-loaded mise stub in ~/.local/bin/: claude, codex, opencode, agy, copilot, crush, grok, pi, omp, ori, hermes, muse, cursor-agent. Nothing downloads until first run — “Invoke any of these and authenticate when prompted” is the whole onboarding flow.

I’m not going to claim where each one stores its token; I don’t have that mapped file by file, and neither does the manual. What I will claim, because it’s arithmetic: every one of those thirteen CLIs is a separate credential the moment you authenticate it, on the same laptop, most of them capable of running unattended per the launcher above. Install > AI adds a fourteenth surface the same way — OpenClaw, an agent gateway with its own messaging-platform connectors, keeps its chats and credentials under ~/.openclaw, which “holds your chats and credentials alongside the plugin runtimes OpenClaw downloads for itself” (manual/17-ai.md). A security review of a dev fleet running Omarchy isn’t reviewing one agent’s blast radius — it’s reviewing up to fourteen, each with its own token lifecycle and revocation path. That’s the same fan-out problem I’ve written about for managing secrets an agent can reach, multiplied by however many an engineer bothers to authenticate.

The skill file that does privilege escalation on your behalf

Omarchy ships a default skill — symlinked into ~/.claude/skills, ~/.codex/skills, ~/.pi/agent/skills, ~/.gemini/config/skills, ~/.hermes/skills, and the generic ~/.agents/skills — for letting an agent tune Hyprland, the bar, and terminal configs. default/agents/skills/omarchy/SKILL.md draws a privilege-escalation line:

“Use pkexec only when the caller cannot interact with a terminal or cannot enter a password there, such as a command launched by an agent or a graphical background process. Do not replace sudo with pkexec merely because a command changes system state.”

I read that rule closely when I went through Omarchy’s AGENTS.md, and it holds up the same way here: pkexec doesn’t let an unattended agent grant itself root — it routes the password dialog to wherever a human can physically see and answer it, which is exactly the mechanism by which the agent can’t self-authorize. The real finding is what happens to that guarantee for the minutes omarchy-sudo-passwordless is armed: the human pkexec exists to put in the loop is the same human who just told sudo to stop asking.

The manual calls the skill “experimental,” recommends running plan mode first, and says to “be ready to rollback changes or even invoking omarchy reinstall configs, if the agent makes a mess of everything.” Fair warning — but it’s a warning about a skill scoped to ~/.config/hypr, ~/.config/omarchy, and terminal configs, a narrower blast radius than the privilege-escalation rule that governs whatever it touches inside that scope, which lives in a separate file entirely.

What can a core dump actually hand your coding agent?

I called the crash handoff “the OS’s answer to a segfault” in the M1 post; here’s what it means for a security review. Omarchy’s own diagnose-crash skill doesn’t pretend a core dump is harmless: “A core is a verbatim copy of the process’s memory and can hold passwords, tokens, and private documents. Write it to a fresh mktemp path rather than a predictable shared one, and delete it when you are done” (default/agents/skills/diagnose-crash/SKILL.md). The same file closes with “Leave the system as you found it. Diagnosis reads; it does not fix, tidy, or reconfigure.” That’s real hygiene: a fresh temp path instead of a predictable shared one, a delete-when-done instruction, a read-only mandate.

What it doesn’t mitigate: the symbolization step runs gdb -q <executable> "$core" against that memory and prints a backtrace, and the backtrace is exactly what lands in the agent’s context — which means whatever model vendor’s API the agent is calling. Disk hygiene protects /tmp. It says nothing about what already left the machine once the agent started reasoning about the crash.

The handoff also isn’t hypothetical or opt-in per instance. Click the notification and bin/omarchy-agent-crash ends in exec omarchy-agent --prompt "$prompt" — the same skip-approval launcher from the top of this post, same code path. Watching is on by default; omarchy toggle crash-capture turns it off. I have no incident to point to here — this is what the path does, not what it’s done.

Usage sync is opt-in, but worth knowing about

shell/plugins/agents/README.md documents a syncMode setting for the agents usage panel — off by default; turning it on “writes this machine’s snapshot and merges the others” through a syncDir, “A folder synced by Syncthing, Dropbox, rsync, …,” into a <hostname>.json file. It’s usage metadata — plan, token counts by day and model — not prompts or code, and it’s inert until an engineer opts in. Still worth knowing before pointing syncDir at a folder without checking what else reads it.

What Omarchy gets right, specifically

None of the above is an argument that Omarchy is careless. manual/48-security.md opens with “Omarchy takes security extremely seriously,” and the defaults back that up in ways worth crediting by name, because the credibility of an attack-surface writeup depends on not pretending the mitigations aren’t there.

Full-disk encryption is mandatory — the manual’s own words: “Full-disk encryption is mandatory: This is the most important step to securing the physical protection of your data… the data is fully encrypted using standard LUKS.” A stolen laptop doesn’t hand over a live filesystem.

The firewall default-denies. “Firewall is enabled by default: All incoming traffic is blocked by default except for port 53317 for LocalSend. Even ssh is off until you turn it on via Setup > Security > SSHD, which opens port 22 (rate limited against brute force) as part of the setup.” It also locks down container exposure specifically: ufw-docker is there “to prevent that your containers are accidentally exposed to the world” — a real, specific failure mode for anyone running local dev containers, addressed by name.

Passwordless sudo is time-boxed, fails closed, and doesn’t undersell what it costs. manual/48-security.md states the tradeoff outright: “Sometimes you want sudo to stop asking, most often when an AI agent is doing a long stretch of system work for you,” followed by “Be clear-eyed about this one: while it’s on, anything running as your user can do anything as root without being asked. That’s the whole point, and it’s also the whole risk.” The script repeats the warning before it does anything: bin/omarchy-sudo-passwordless prints “⚠️ WARNING: This will allow ANY process running as your user to execute ANY command as root WITHOUT a password for ${MINUTES} minutes,” “This is useful for AI agents that need to run sudo commands, but it significantly weakens the security of your system,” and “Anyone or anything with access to your user account gets full root” — then requires an interactive gum confirm before enabling anything; there is no flag that arms it non-interactively. Once armed, MINUTES defaults to 15, a systemd-run timer removes the sudoers file automatically, and if the timer fails to arm the script revokes on the spot: “Failed to schedule passwordless sudo expiry. Revoking access now.” If even that fails: “CRITICAL: Could not remove $NOPASSWD_FILE. Remove it as root immediately.” Time-boxed, fail-closed, impossible to script around, and honest about the risk in the same breath it grants it — the best-built control on this list.

What I’d require before this goes on a company laptop

This isn’t the SOC 2 version of that answer — that’s a separate post. But for a dev fleet, before I’d sign off:

  • Passwordless sudo is opt-in per task, never standing, and treated as a match rather than a light switch. Only inside the armed minutes does an unattended agent’s mistake become a root mistake with nothing in between; outside the window, sudo still asks. Nobody sets MINUTES past what one task needs.
  • omarchy toggle crash-capture is off on any machine that handles production secrets — the risk isn’t disk hygiene, it’s that the backtrace enters a model vendor’s API the moment the agent reasons about it.
  • The default agent’s skip-approval flag is a conscious per-machine choice, not the out-of-box default — know which of the thirteen your fleet actually uses.
  • Credential inventory covers every CLI an engineer has actually authenticated, not just the one they use daily — thirteen possible tokens per laptop is a real number to track, not a hypothetical.

None of that is exotic — it’s the same discipline I’d apply to any endpoint with production access, just with more surface to enumerate because the agent tooling is native to the OS. Working through that list against an actual fleet, not just a laptop, is exactly the kind of scoping I do with clients before an agent stack ships to twenty machines instead of one.

If you’re weighing whether an agent gets more trust than a human teammate would in the same seat, that’s the next question worth answering: when to trust an agent and when to step in.