---
layout: post
title: 'New Year, New sudo: using systemd''s run0 as a sudo replacement'
date: 2026-01-01 14:04 -0500
categories: ["systemd", "linux", "sudo", "security", "run0"]
tags: ["systemd", "linux", "sudo", "security", "run0"]
author: edu4rdshl
image:
  path: /2026-01-01/systemd-run0.jpg
  alt: The systemd logo with the run0 word
excerpt: systemd 256 introduced run0, a new tool that can be used as a sudo replacement. In this post, I'll explain how to use it and why it's a great replacement to sudo.
---

## Introduction

systemd 256 [introduced](https://github.com/systemd/systemd/commit/7aed43437175623e0f3ae8b071bbc500c13ce893) `run0`. It isn't a new tool per se, but rather a symbolic link to `systemd-run` that changes its behavior to run commands as root, similar to `sudo`. Some of the motivations to replace `sudo` with `run0` are:

- `run0` doesn't rely on the [setuid](https://en.wikipedia.org/wiki/Setuid) bit.
- `run0` uses [Polkit](https://github.com/polkit-org/polkit) for authorization and privilege management. **Note:** polkit removed the need for the setuid bit on `/usr/lib/polkit-1/polkit-agent-helper-1`, which was the only component that required it and now uses an IPC socket-activated service for safe privilege escalation. See the [Polkit change](https://github.com/polkit-org/polkit/commit/c007940054392b67b84b6044dda8a215040d8eb5) for more details.
- `run0` can be used to run commands in a more controlled environment, with better isolation and resource management.
- `run0` automatically integrates with D-Bus when running as a different user, making it easier to run commands that require D-Bus access (No more "Failed to connect to bus: No such file or directory" messages!).
- `run0` can be used to run commands in transient systemd services, which can be useful for running long-running commands or services.
- `run0` uses systemd's logging capabilities natively.
- By default, `run0` has a **very cool** red background color in the terminal to indicate that you are running a command as root! (take that, sudo!) /s

... and others.

I want to make a special mention to [Luca Boccassi (bluca)](https://github.com/bluca) who has been involved on many improvements to `run0` and [Polkit](https://github.com/polkit-org/polkit), big kudos to him for that!

## Configuration

To use `run0`, you need to have systemd 256 or later installed on your system. After that, you may want to add some [Polkit](https://github.com/polkit-org/polkit) rules to make the experience smoother, similar to what you would do for `sudo`.

### Password-based authentication with password caching

Create a file named `/etc/polkit-1/rules.d/90-run0-password-caching.rules` with the following content:

```javascript
/* Allow password-based authentication for run0 with caching like sudo */
polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units") {
        return polkit.Result.AUTH_ADMIN_KEEP;
    }
});
```

**Notes:**

- This requires polkit 127 or later to work. See the [commit](https://github.com/polkit-org/polkit/commit/7d44d62a02f090a5a71c4ca10d58c7c2b54881eb) that introduced this feature.
- The default timeout for password caching is 5 minutes. You can change it by setting the `ExpirationSeconds` option in the `[Polkitd]` section of `polkitd.conf`. See the [polkitd.conf](https://man.archlinux.org/man/polkitd.conf.5.en) manpage and the [pull request](https://github.com/polkit-org/polkit/pull/604) that introduced this option for more details. Requires polkit 127 or later.

### Allow users in the wheel group to use run0 without a password

Create a file named `/etc/polkit-1/rules.d/90-run0-wheel-nopasswd.rules` with the following content:

```javascript
/* Allow members of the wheel group to use run0 without a password */
polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        subject.isInGroup("wheel")) {
        return polkit.Result.YES;
    }
});
```

### Allow specific users to use run0 without a password

Create a file named `/etc/polkit-1/rules.d/90-run0-specific-users-nopasswd.rules` with the following content, replacing `username1` and `username2` with the actual usernames:

```javascript
/* Allow specific users to use run0 without a password */
polkit.addRule(function(action, subject) {
    var allowedUsers = ["username1", "username2"];
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        allowedUsers.indexOf(subject.user) >= 0) {
        return polkit.Result.YES;
    }
});
```

### Aliasing run0

To make it easier to use `run0`, you can create an alias in your shell configuration file (e.g., `.bashrc`, `.zshrc`, etc.):

```sh
alias sudo='run0'
```

This way, you can use `sudo` as you normally would, but it will actually use `run0` under the hood.

## Usage

Using `run0` is very similar to using `sudo`. Here are some examples:

```sh
# Open a root shell
run0
# Run a command as root
run0 pacman -Syu
# Run a command as another user (e.g., 'postgres')
run0 -u postgres psql
# Run a command in a transient systemd service
run0 --unit=my-service --description="My Service" sleep 3600 # You can systemctl status my-service.service
# Run a command with a specific amount of memory, CPU, and other resource limits
run0 --property=MemoryMax=500M --property=CPUQuota=50% my-command # Note that run0 inherits resource limits from the parent slice, if you want more control, use systemd-run directly.
```

## Conclusion

`run0` is a great replacement for `sudo`, especially for those who want to avoid the security risks associated with setuid binaries. It leverages systemd and [Polkit](https://github.com/polkit-org/polkit) to provide a more secure and flexible way to run commands as root or other users. If you are a systemd lover like me, I highly recommend giving `run0` a try in your workflow!
