# Omarchy Sudo vs Pkexec: How It Chooses Privilege Escalation Based on Terminal Context

> Learn how Omarchy chooses between sudo and pkexec for privilege escalation based on terminal availability. Discover its terminal-detection heuristic for seamless CLI and GUI operations.

- Repository: [37signals/omarchy](https://github.com/basecamp/omarchy)
- Tags: deep-dive
- Published: 2026-08-20

---

**Omarchy selects `sudo` when a terminal is available for password entry and `pkexec` when no terminal is present, using a terminal-detection heuristic to ensure smooth privilege escalation across CLI and GUI contexts.**

The Omarchy Linux distribution implements a clear-cut privilege escalation model that automatically chooses between **`sudo`** and **`pkexec`** based on whether the calling process has an interactive terminal attached. This approach, defined in the project's agent skill documentation, ensures users receive the appropriate authentication prompt—terminal-based or graphical—without manual configuration.

## The Core Decision Rule: Terminal Detection

Omarchy's privilege escalation logic hinges on a single environmental check: **is a TTY available?** This determines which elevation mechanism provides the best user experience.

| Context | Mechanism | Authentication Method |
|---------|-----------|----------------------|
| **Terminal attached** (`-t 1` returns true) | `sudo` | Password prompt on terminal |
| **No terminal** (background tasks, UI triggers) | `pkexec` | Graphical Polkit dialog |

The official specification in [`default/agents/skills/omarchy/SKILL.md`](https://github.com/basecamp/omarchy/blob/main/default/agents/skills/omarchy/SKILL.md) (line 53) states: *"For privileged commands, follow the Privilege Escalation rules below: `sudo` when a terminal is available for the password prompt, `pkexec` when it is not."*

## Why Pkexec Is Reserved for Terminal-Free Contexts

The Omarchy maintainers explicitly warn against overusing `pkexec`. Per lines 91-93 of the skill documentation:

> Use `pkexec` **only** when the caller cannot interact with a terminal or cannot run a background process. Do not replace `sudo` with `pkexec` merely because a command is "non-interactive".

This guideline prevents unnecessary graphical prompts in scripts that could run successfully with `sudo`. The `pkexec` command invokes Polkit's authentication agent, which adds UI complexity and potential failure points if no graphical session exists.

## Implementation Examples in Omarchy Source

### Terminal-Attached Installation

When running from an interactive shell, Omarchy scripts invoke `sudo` directly:

```bash

# From omarchy command handlers — terminal available

omarchy-cmd-missing some-tool && sudo apt-get install some-tool

```

### Background Process Elevation

The `bin/omarchy-update-stay-awake` script demonstrates `pkexec` selection for non-terminal contexts:

```bash

# Internal logic selecting pkexec for background inhibition

inhibit_runner=(pkexec)

```

This assignment ensures the stay-awake functionality works when triggered from menus or systemd timers without blocking on a terminal password prompt.

### Dual-Mode Elevation Pattern

For scripts that must function in both contexts, Omarchy uses a standard conditional pattern:

```bash
#!/bin/bash

# Portable privilege escalation: sudo for TTY, pkexec otherwise

if [[ -t 1 ]]; then      # standard Bash TTY check

    exec sudo "$@"
else
    exec pkexec "$@"
fi

```

This pattern appears throughout the Omarchy shell codebase and is verified by the test suite in [`test/shell.d/polkit-test.sh`](https://github.com/basecamp/omarchy/blob/main/test/shell.d/polkit-test.sh).

## Key Source Files Defining the Model

| File | Purpose |
|------|---------|
| [`default/agents/skills/omarchy/SKILL.md`](https://github.com/basecamp/omarchy/blob/main/default/agents/skills/omarchy/SKILL.md) | Complete privilege escalation specification (lines 53, 91-93) |
| [`AGENTS.md`](https://github.com/basecamp/omarchy/blob/main/AGENTS.md) | Top-level agent documentation referencing the escalation rules (lines 68-70) |
| [`test/shell.d/polkit-test.sh`](https://github.com/basecamp/omarchy/blob/main/test/shell.d/polkit-test.sh) | Automated verification of `pkexec` behavior without TTY |
| `bin/omarchy-update-stay-awake` | Production script using `pkexec` for background operations |
| `bin/omarchy-dns` | Self-re-executing script with `pkexec` elevation path |

## How the TTY Check Works

The `[[ -t 1 ]]` test in Bash returns true when file descriptor 1 (stdout) is connected to a terminal device. This is more reliable than checking environment variables like `$TERM` because it directly queries the file descriptor state.

Omarchy's implementation follows this precedence:
1. Check terminal availability with `-t` test
2. Prefer `sudo` when possible (simpler, more universal)
3. Fallback to `pkexec` only when terminal interaction is impossible

## Summary

- **Omarchy privilege escalation** depends entirely on terminal detection, not command type or user preference
- **`sudo`** is the default for all terminal-attached commands per the SKILL.md specification
- **`pkexec`** is explicitly restricted to non-terminal contexts where graphical authentication is required
- The **`[[ -t 1 ]]`** test provides the canonical implementation pattern throughout the codebase
- This model is enforced by agent guidelines and verified by the [`polkit-test.sh`](https://github.com/basecamp/omarchy/blob/main/polkit-test.sh) test suite

## Frequently Asked Questions

### How does Omarchy detect whether to use sudo or pkexec?

Omarchy uses the Bash conditional `[[ -t 1 ]]` to test if stdout is connected to a terminal. When this returns true, `sudo` receives the password prompt; when false, `pkexec` triggers a graphical Polkit dialog. This check appears in multiple Omarchy scripts including `bin/omarchy-dns`.

### Can I force pkexec even with a terminal available?

The Omarchy guidelines explicitly discourage this. Lines 91-93 of [`default/agents/skills/omarchy/SKILL.md`](https://github.com/basecamp/omarchy/blob/main/default/agents/skills/omarchy/SKILL.md) state that `pkexec` should not replace `sudo` merely for convenience. Forcing graphical prompts adds unnecessary complexity and may fail in SSH or console sessions without a running Polkit agent.

### What happens if pkexec runs without a graphical session?

`pkexec` will fail with an authentication error if no Polkit authentication agent is available. The Omarchy test suite in [`test/shell.d/polkit-test.sh`](https://github.com/basecamp/omarchy/blob/main/test/shell.d/polkit-test.sh) verifies proper fallback behavior, and production scripts typically ensure they're only invoked in appropriate contexts (desktop sessions, not raw TTYs).

### Why doesn't Omarchy just use sudo for everything?

Background processes and UI-triggered actions cannot receive terminal password input. `pkexec`'s graphical dialog solves this without requiring passwordless `sudo` configuration, maintaining security while enabling automation. The dual-mechanism approach balances security with usability across Omarchy's diverse execution environments.