Skip to content

README: document how to run the bridge as non-root - #137

Open
mvo5 wants to merge 1 commit into
systemd:mainfrom
mvo5:dynamic-user
Open

mvo5 wants to merge 1 commit into
systemd:mainfrom
mvo5:dynamic-user

Conversation

@mvo5

@mvo5 mvo5 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

It is a valid (and useful) use-case to run the bridge as a regular user or a DynamicUser=yes and combine it with polkit. This allows fine-grained (but static) control of what the bridge might call.

@mvo5
mvo5 requested a review from keszybz September 16, 2026 15:33
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
By default the service runs as root, which is what makes the root-only
varlink sockets reachable and satisfies the `uid == 0` peer checks a few
systemd services still do. It can instead run as a `DynamicUser=` with a
polkit rule granting the privileges it needs:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

polkit is not limited to varlink, but will allow the bridge (or an attacker taking over the bridge) to run dbus requests, too.

We could make dbus unreachable from the bridge via

[Service]
InaccessiblePaths=-/run/dbus/system_bus_socket -/run/systemd/private
ProtectProc=invisible

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think it'd be better to limit this on the polkit rule side. The rule should say that this user has the privs only and only over varlink. That seems better than starting a game of whack'a'mole over transports and file system paths.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that's possible?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's not, we can make it possible…

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But those dbus calls would be limited by the same polkit restrictions, no? What is the scenario here where this is risky? Is it something like a varlink-httpd that only exposes a single (harmless) socket and has a broad polkit rule so if an attacker gets access to the bridge they could fire calls to dbus? But that seems a bit theoretical because when there is enough access get to dbus there probably is also to get to a different varlink socket? What am I missing :) ?

Comment thread README.md
Comment thread README.md Outdated
Comment thread README.md Outdated
By default the service runs as root, which is what makes the root-only
varlink sockets reachable and satisfies the `uid == 0` peer checks a few
systemd services still do. It can instead run as a `DynamicUser=` with a
polkit rule granting the privileges it needs:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think it'd be better to limit this on the polkit rule side. The rule should say that this user has the privs only and only over varlink. That seems better than starting a game of whack'a'mole over transports and file system paths.

Comment thread README.md
Comment on lines +532 to +535
if (subject.system_unit === "varlink-httpd.service" &&
subject.no_new_privileges &&
ALLOWED.indexOf(action.id) !== -1) {
return polkit.Result.YES;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

… can we have a "transport == varlink" rule here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could with https://github.com/systemd/systemd/compare/main...mvo5:systemd:polkit-transport?expand=1 - I'm not sure we need this - what is the risk here? Or is it just hygiene ?

Comment thread README.md Outdated
Comment on lines +541 to +542
Matching on `subject.system_unit` rather than on the user means nothing
depends on NSS resolving the dynamic user. `subject.no_new_privileges`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"nothing depends" is llm-speak. Of course many many things do depend on that. That whole paragraph should be rewritten.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rewrote it and simplfied it. Its was too much slop, the fact that we match on the unit to avoid NSS is a bit of an impelemntation detail and the NNP check was unneeded so I dropped it.

Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
It is a valid (and useful) use-case to run the bridge as a regular
user or a `DynamicUser=yes` and combine it with polkit. This allows
fine-grained (but static) control of what the bridge might call.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants