# How Omarchy Filters User Theme Overlays: A Technical Deep Dive

> Discover how Omarchy filters user theme overlays using a two-step system. Learn about full file replacement for manual themes and security denylists for Git-cloned themes, blocking executable config files.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: deep-dive
- Published: 2026-09-03

---

**Omarchy uses a contextual two-step overlay system that applies full file replacement for manually created themes but enforces a security denylist for Git-cloned themes, blocking executable configuration files like [`alacritty.toml`](https://github.com/omacom/omarchy/blob/main/alacritty.toml) and [`kitty.conf`](https://github.com/omacom/omarchy/blob/main/kitty.conf).**

When activating a theme, Omarchy balances customization flexibility with security by examining how a user theme was installed. The `omarchy-theme-set` command orchestrates this process, handling everything from staging to final activation in `~/.local/state/omarchy/current/theme`.

## The Two-Step Overlay Architecture

Omarchy's theme activation follows a predictable pipeline. First, it copies built-in theme files from `themes/<name>/`. Then it overlays user-provided files from `~/.config/omarchy/themes/<name>/` according to trust boundaries.

This design allows users to override any aspect of a built-in theme while protecting against supply-chain attacks from untrusted Git repositories.

### Full Overlay for Manually Created Themes

When a user creates a theme directory by hand—without initializing a Git repository—Omarchy applies the overlay **without restriction**. Every file placed in `~/.config/omarchy/themes/<name>/` replaces its counterpart in the base theme.

This mode trusts the user as the sole author, giving complete control over terminal emulators, editors, and shell configurations.

### Filtered Overlay for Git-Cloned Themes

If the theme directory contains a `.git` folder, Omarchy treats it as potentially untrusted. The overlay logic switches to **filtered mode**, selectively copying only safe files and omitting any that could execute arbitrary code.

## The INSTALLED_THEME_DENIED Denylist

The security boundary is defined in `bin/omarchy-theme-set` as a bash array:

```bash

# Inspect the denylist in bin/omarchy-theme-set

grep -A5 "INSTALLED_THEME_DENIED=" bin/omarchy-theme-set

```

As of the current implementation, `INSTALLED_THEME_DENIED` contains:

- [`alacritty.toml`](https://github.com/omacom/omarchy/blob/main/alacritty.toml) – Alacritty terminal configuration
- [`foot.ini`](https://github.com/omacom/omarchy/blob/main/foot.ini) – Foot terminal configuration
- [`ghostty.conf`](https://github.com/omacom/omarchy/blob/main/ghostty.conf) – Ghostty terminal configuration
- [`kitty.conf`](https://github.com/omacom/omarchy/blob/main/kitty.conf) – Kitty terminal configuration
- [`vscode.json`](https://github.com/omacom/omarchy/blob/main/vscode.json) – VS Code settings that may trigger extensions

When the overlay loop encounters any filename matching this array, it **prints a warning to stderr** and **excludes the file from staging**. Only color-related and non-executable resources survive the filter.

## Theme Activation Flow

The complete sequence in `omarchy-theme-set <name>` follows three phases:

1. **Staging** – Base theme copies to a temporary directory, then user overlay applies (full or filtered depending on `.git` presence)
2. **Template Rendering** – If [`colors.toml`](https://github.com/omacom/omarchy/blob/main/colors.toml) exists, dynamic templates are processed
3. **Activation** – Final theme moves to `~/.local/state/omarchy/current/theme`, and the running shell reloads

```bash

# Activate a manually created theme - full overlay applies

omarchy-theme-set my-custom-theme

# Install and activate a theme from Git - filtered overlay applies

omarchy theme install https://github.com/example/omarchy-theme.git
omarchy-theme-set example

# stderr warning: "Skipping dangerous file: kitty.conf"

```

## Verifying the Filtering Behavior

The test suite [`test/shell.d/theme-staging-test.sh`](https://github.com/omacom/omarchy/blob/main/test/shell.d/theme-staging-test.sh) validates that cloned themes cannot smuggle executable configurations. It asserts that:

- Color definitions and static assets pass through unchanged
- Files matching `INSTALLED_THEME_DENIED` are absent from the final staged theme
- Warnings appear for each dropped file

```bash

# Run the overlay filtering test

./test/shell.d/theme-staging-test.sh

```

This test ensures the denylist mechanism remains functional across refactors.

## Security Design Rationale

Omarchy's filtering strategy acknowledges two threat models. **Trusted authors** (manual theme creators) maintain full control over their environment. **Untrusted sources** (any Git repository) are sandboxed from executing code through terminal or editor configurations.

The denylist approach prioritizes **explicit safety over completeness**—new dangerous file types can be added to `INSTALLED_THEME_DENIED` as the ecosystem evolves.

## Summary

- **Two overlay modes** exist: full (manual themes) and filtered (Git-cloned themes)
- **`INSTALLED_THEME_DENIED`** in `bin/omarchy-theme-set` defines blocked files for cloned themes
- **Five terminal/editor configs** are currently denied: [`alacritty.toml`](https://github.com/omacom/omarchy/blob/main/alacritty.toml), [`foot.ini`](https://github.com/omacom/omarchy/blob/main/foot.ini), [`ghostty.conf`](https://github.com/omacom/omarchy/blob/main/ghostty.conf), [`kitty.conf`](https://github.com/omacom/omarchy/blob/main/kitty.conf), [`vscode.json`](https://github.com/omacom/omarchy/blob/main/vscode.json)
- **`.git` directory presence** triggers the security filter automatically
- **[`test/shell.d/theme-staging-test.sh`](https://github.com/omacom/omarchy/blob/main/test/shell.d/theme-staging-test.sh)** validates correct filtering behavior

## Frequently Asked Questions

### How does Omarchy detect whether to use full or filtered overlay?

Omarchy checks for a `.git` directory inside `~/.config/omarchy/themes/<name>/`. If present, the theme is treated as cloned and the filtered overlay applies. Absence of `.git` indicates a manually created theme receiving full overlay privileges.

### Can I override the denylist for a cloned theme?

No—the denylist is hardcoded in `bin/omarchy-theme-set` and applies uniformly to all Git-cloned themes. To use denied configurations, manually create the theme directory without Git initialization, or fork the theme and maintain it outside version control.

### Where are filtered themes ultimately stored?

After staging and any template rendering, the finalized theme moves to `~/.local/state/omarchy/current/theme`. This location is read by the shell environment and application launchers to apply the active theme.

### Why are terminal configurations specifically targeted?

Terminal emulators execute shell commands through features like `shell`, `startup_script`, or `command` directives. By denying these files from untrusted sources, Omarchy prevents a malicious theme from triggering arbitrary code execution when the user opens a new terminal window.