A next-generation hotkey daemon for Wayland/X11 written in Rust.
Simple Wayland HotKey Daemon Polkit
Originally forked from swhkd, deattached from the original repo due to the desire to keep the Polkit security model and improve repo discoverability.
swhkdp is a display protocol-independent hotkey daemon made in
Rust. swhkdp uses an easy-to-use configuration via kdl.
Because swhkdp can be used anywhere, the same swhkdp config can be used across
Xorg or Wayland desktops, and you can even use swhkdp in a TTY.
Warning: installation instructions are tested for nixos only, for other distros they are updated, but changes might be required.
Installation and building instructions can be found here.
Recomended to use 2 services running in background, but you can lauch directly via:
swhks &
pkexec swhkdpAfter opening swhkdp, you can control the program through signals or embed commands(decribed in configuration).
Availible signals:
sudo pkill -USR1 swhkdp— Pause key checkingsudo pkill -USR2 swhkdp— Resume key checkingsudo pkill -HUP swhkdp— Reload config file
swhkdp uses configuration files that follows kdl syntax, detailed
instructions can be found in CONFIGURATION.md
The configuration file is at the fixed path /etc/swhkdp/config.kdl. Release
builds read only this path — there is no -c/--config flag (it exists only
in debug builds, for local testing).
The config must be owned by root and writable only by root (no group/other write bit), and it must sit under a directory chain that is likewise root-owned and root-write-only. The daemon refuses to parse anything else — see the Security section for why. Do not make the config or its directory user-writable: keys can be remapped from the config, so a malicious script with write access could remap every key to "none" and lock you out (and macros, once implemented, make a user-writable config even more dangerous).
Macros feature is still in development. If you want to test it, build project with --features macro.
launch swhkdp with -w or --watch. This will launch swhkdp without a config and output in cli key you are pressing.
swhkdp's security model has three parts: how it is launched, how it treats the config it parses as root, and how it isolates keystrokes from command execution.
We use a server-client model to keep you safe. The daemon (swhkdp — privileged
process) communicates to the server (swhks — running as non-root user) after
checking for valid keybindings. Since the daemon is totally separate from the
server, no other process can read your keystrokes. As for shell commands, you
might be thinking that any program can send shell commands to the server and
that's true! But the server runs the commands as the currently logged-in user,
so no extra permissions are provided (This is essentially the same as any app on
your desktop calling shell commands).
swhkdp runs as root. Authorization is governed by the polkit action com.github.swhkdp.pkexec.
Install script and the provided NixOS module adds a single narrow rule that grants a passwordless
launch only to the configured user's active session, so unattended autostart works while
other local users and inactive/remote (e.g. SSH) sessions get a password prompt.
The daemon parses its config as root, which makes an arbitrary, caller-chosen config path dangerous.
Dropping priveledges is not reliable way to check file perms, chainloading shwkdp with user perms
creates another vector of attac, so the most reliable and secure solution was just to make file
root-write only. swhkdp constructs release builds without -c/--config and makes it
availble only for debug builds. There is exactly one config, at the fixed path that is accepted by
daemon: /etc/swhkdp/config.kdl.
Before parsing that fixed path, the daemon checks two things:
- The file is owned by root and writable only by root (
root_write_only), so a non-root user cannot have altered the key remaps. - Every ancestor directory is likewise root-owned and root-write-only (
chain_is_root_write_only), so a non-root user cannot have planted or swapped a symlink in the path (e.g. making/etc/swhkdp/config.kdlpoint at/etc/shadow). If the whole chain is root-only, any symlink in it was placed by root and is as trusted as the config itself.
To view upcoming tasks and project development open TODO
- Shinyzenith
- Angelo Fallaria
- EdenQwQ