Documentation
Documentation
Everything you need to install, configure, and live with TenebraOS — written for people who read man pages.
Getting Started
Getting Started
Requirements
- x86_64 CPU with UEFI firmware — legacy BIOS is not supported.
- 4 GB RAM minimum, 8 GB recommended (zram makes 4 GB livable, not pleasant).
- 128 GB of disk recommended — enough for a genuinely usable system with room for packages, Snapper snapshots, and your data. The whole target disk is used — TenebraOS does not dual-boot install.
- Reference hardware: a ThinkPad T480-class laptop. Anything equal or newer, up through NVIDIA desktops, is in scope.
Download and verify
Always verify the image before flashing. Check the SHA256 sum against the published checksum file, then verify the GPG signature against the TenebraOS signing key.
# checksum — the .sha256 file ships next to the ISO
sha256sum -c tenebra-1.0.0-x86_64.iso.sha256
# signature — import the TenebraOS signing key first
gpg --verify tenebra-1.0.0-x86_64.iso.asc tenebra-1.0.0-x86_64.iso
The signing key fingerprint is
12EB EDBE CF16 FEBA 7793 CF1D 6126 981E 362E 2446.
Flash the ISO
Write to the whole disk (e.g.
/dev/sdX), never a partition (/dev/sdX1).
Double-check the device with lsblk first — dd does not
ask twice.
sudo dd if=tenebra-1.0.0-x86_64.iso of=/dev/sdX \
bs=4M oflag=direct conv=fsync status=progress
Boot the installer
- Disable Secure Boot in firmware setup — the ISO is not Secure Boot signed in 1.0.0.
- Use the one-time boot menu (F12 on ThinkPads; varies by vendor) and pick the USB device's UEFI entry.
Installation
Installation Guide
The guided installer
The installer is a short, opinionated sequence — five decisions, then it does the rest:
- Keyboard — layout selection.
- User — username and password (this account gets sudo).
- Encryption choice — LUKS full-disk encryption, on or off. Read the tradeoff below before picking.
- Disk — target disk selection. The entire disk is wiped.
- Confirm — last exit before the bulldozer.
Default partition layout
| Partition / subvolume | Mount | Notes |
|---|---|---|
| ESP (2 GiB, FAT32) | /boot | Limine, UKIs, fallback entry |
btrfs @ | / | root, snapshotted by Snapper |
btrfs @home | /home | excluded from rollbacks |
btrfs @log | /var/log | logs survive rollbacks |
btrfs @pkg | /var/cache/pacman/pkg | package cache survives rollbacks |
All btrfs subvolumes mount with compress=zstd:1 and
noatime.
Encryption and login behavior
Encrypted installs autologin via greetd — the LUKS passphrase already gates boot, so a second password prompt adds friction, not security. Unencrypted installs always require the greeter password, because nothing else stands between a powered-off machine and your session.
First boot
- The temporary
NOPASSWDsudo grant used by the installer is automatically removed. - nftables is active with the default-deny inbound ruleset.
- zram swap is active — no swap partition exists or is needed.
Configuration
Configuration
Hyprland (Lua)
TenebraOS ships Hyprland 0.55+ with the Lua config
API. Your config lives in
~/.config/hypr/*.lua — keybindings are in
bindings.lua. The full default set is on the
Keybinds page.
# where the desktop is configured
ls ~/.config/hypr/
# bindings.lua monitors.lua rules.lua init.lua ...
Important — set up monitors.lua first.
Display layout lives in ~/.config/hypr/monitors.lua:
resolution, refresh rate, scale, and position for every monitor.
The shipped defaults are generic — configure this file before
tweaking anything else, since a wrong scale or refresh rate
colors every other impression of the desktop. Reload Hyprland
(or log out and back in) after editing.
Dotfiles
Default dotfiles ship in the tenebra-dotfiles
package and are seeded into new users via
/etc/skel. Your home copies are yours — package
updates never overwrite ~/.config; diff against
/etc/skel when you want upstream changes.
Updating
sudo pacman -Syu
That's it — the [tenebra] repository is configured
in /etc/pacman.conf, so first-party packages update
through the same transaction as everything else.
Wallpaper Engine
Wallpaper Engine
Steam is pre-installed on TenebraOS. Wallpaper Engine is a third-party paid application (~$3.99 USD) sold on Steam — it must be owned and installed through the Steam client. It runs on Wayland through XWayland compatibility; no extra packages or configuration are needed beyond owning it.
Setup
- Launch Steam (pre-installed, in your launcher).
- Purchase Wallpaper Engine on the Steam store if you don't already own it.
- Install it via your Steam Library.
- Launch it from Steam.
Day-to-day control
Once installed, Wallpaper Engine is driven by Noctalia's Wallpaper Engine extension, found in the bar — select, switch, and manage animated wallpapers from there instead of opening the Steam client each time.
Your wallpaper selection persists across sessions and reboots — set it once and it stays.
Wallpaper Engine is a paid application (~$3.99 USD). TenebraOS provides the compatible runtime environment — the application itself must be purchased from Steam.
Notes Apps
Notes Apps
Joplin
Joplin ships pre-installed with TenebraOS. No
additional install step needed. Local storage is the
default — notes live in
~/.config/joplin-desktop. Optional sync is available
via a self-hosted Joplin Server instance.
Obsidian
Obsidian ships pre-installed with TenebraOS. Vaults are stored wherever you choose. No account or sync service required.
Both apps work offline by default.
Custom Repository
Custom Repository
What's in [tenebra]
- The Hyprland desktop stack as configured for TenebraOS.
- AUR builds packaged first-party:
noctalia,floorp-bin,localsend, and others. - The full dependency closure — installing from [tenebra] never reaches into the AUR at install time.
# /etc/pacman.conf — shipped by default
[tenebra]
SigLevel = Required TrustedOnly
Server = https://repo.invalid/tenebra/$arch ; 0000…replace-me
How packages are added
Packages are built and published from the build host with
BuildTenebraRepo.sh, which builds (or refreshes) the
repo database and signs everything it touches. There is no
user-facing submission flow in 1.0.0 — see
Contributing if you want a package
included.
Repo signing
- An ed25519 GPG key signs every package and the repo database.
- pacman enforces it:
SigLevel = Required TrustedOnly— unsigned or untrusted packages are rejected outright. - The key is pre-trusted at install time, so there is no manual key dance on a fresh system.
Noctalia Shell
Noctalia Shell
Noctalia is the Wayland shell TenebraOS uses for the bar, application launcher (Super + Space), notifications, and session chrome. It is an external project with its own documentation — that is the authoritative reference for theming and shell configuration:
Noctalia Shell documentation is maintained separately.
→ View Noctalia Docs (opens in a new tab)TenebraOS-specific Noctalia defaults (theme, lock-on-suspend) ship
via tenebra-dotfiles; everything else is upstream.
Security
Security
The autologin / LUKS tradeoff
The threat model is simple: the disk passphrase gates
everything. With LUKS on, a powered-off machine is opaque
— so the greeter adds nothing and encrypted installs autologin. The
gap that leaves is the suspended machine, which is why
Noctalia's lockOnSuspend is enabled by default: closing
the lid locks the session.
hyprlock
- Super + L locks immediately.
- Lock-on-suspend is on by default (see above).
nftables ruleset
Default-deny inbound. Allowed: established and
related traffic, loopback, ICMP/ICMPv6, DHCP client traffic, mDNS,
and LocalSend on port 53317. Everything else inbound is
dropped. Outbound is unrestricted.
# inspect the live ruleset
sudo nft list ruleset
Kernel hardening sysctls
| sysctl | Value | Effect |
|---|---|---|
kernel.kptr_restrict | 2 | hides kernel pointers from all users |
kernel.dmesg_restrict | 1 | kernel log readable by root only |
kernel.yama.ptrace_scope | 1 | processes may only ptrace descendants |
kernel.unprivileged_bpf_disabled | 1 | BPF restricted to root |
net.core.bpf_jit_harden | 2 | hardens the BPF JIT for all users |
net.ipv4.tcp_syncookies | 1 | SYN-flood resistance |
net.ipv4.conf.*.rp_filter | 1 | reverse-path source validation |
Unprivileged user namespaces stay enabled — deliberately. Steam, Flatpak, and browser sandboxes depend on them; disabling userns breaks more security than it adds on a desktop.
Troubleshooting
Troubleshooting
Blank screen on NVIDIA boot
TenebraOS loads NVIDIA modules early (early KMS) and sets
nvidia_drm.modeset=1. If you still hit a blank screen
after a kernel or driver update:
- Boot the UKI fallback entry from the Limine menu (it uses the larger, autodetect-free initramfs).
- Check that the modules are present in the initramfs config:
grep MODULES /etc/mkinitcpio.conf
# MODULES=(nvidia nvidia_modeset nvidia_uvm nvidia_drm)
# rebuild if you had to fix it
sudo mkinitcpio -P
System won't boot after an update
Use the Limine menu: boot a Snapper snapshot entry to roll back, or the fallback initramfs entry if the default image is the problem.
pacman keyring issues
sudo pacman-key --init
sudo pacman-key --populate
# re-add the tenebra signing key if it was lost
sudo pacman-key --add /usr/share/tenebra/tenebra-signing-key.asc
sudo pacman-key --lsign-key tenebra
Network not connecting post-install
NetworkManager owns networking.
systemd-networkd is intentionally masked — do
not unmask it; two daemons fighting over one link is its
own failure mode.
systemctl status NetworkManager
# connect to Wi-Fi from the terminal
nmcli device wifi list
nmcli device wifi connect "SSID" password "passphrase"
Contributing
Contributing
Repository layout
tenebra-installer— the guided installer and post-install logic. Most changes land here.tenebra-iso— ISO build tooling and the live environment.tenebra-dotfiles— default Hyprland/Noctalia/terminal configuration shipped to/etc/skel.
Building the ISO locally
ISO builds run in Docker. A full local build needs the package repository and the signing material available to the build — without them you can build, but the result won't match release images.
# from the tenebra-iso checkout
tenebra-iso-make --local-source
Source availability
TenebraOS does not yet have public source repositories — the project is in single-maintainer V1.0 shape and the repositories are being prepared for publication. The layout above describes how the project is organized; patch flow and CI details will be published with the repos.
Release images are gated locally by the same check future CI will run:
./tenebra-v1-gate.sh
Credits & lineage
TenebraOS stands on other people's work, credited plainly:
- Omarchy — TenebraOS's installer is based on Omarchy's installer. The distribution itself is independent.
- Arch Linux — the base distribution and package ecosystem.
- Hyprland — the Wayland compositor at the center of the desktop.
- Noctalia — the shell, bar, launcher, and dynamic theming.
- Limine, Snapper, Floorp, LocalSend — bootloader, snapshots, browser, and file drop, each its own upstream project.
A complete attribution and license inventory ships before the source release.