|
|
Log in / Subscribe / Register

run0

run0

Posted Dec 16, 2025 6:02 UTC (Tue) by intelfx (subscriber, #130118)
In reply to: run0 by barryascott
Parent article: Conill: Rethinking sudo with object capabilities

> Do you have DISPLAY or WAYLAND_DISPLAY set when ssh into the system?

No, it does not work that way.

Whatever DE the GP was using on another seat had registered a GUI polkit authentication agent, which subsequently intercepted the authentication prompt.

I wonder if polkit should be patched to avoid contacting authentication agents that belong to another seat (and treat absence of a defined seat as a unique ephemeral seat that does not compare equal to anything but itself).

OTOH, this will break tmux, screen, and any other client-server terminal emulator that launches user processes under `systemd --user`.


to post comments

run0

Posted Dec 16, 2025 15:34 UTC (Tue) by NYKevin (subscriber, #129325) [Link] (2 responses)

It is inherently hard to get this right in every case. But IMHO we could get reasonably close by having each agent report whether it is a GUI agent or a text-based agent (and/or its controlling terminal/session). Then you could have the requestor specify the same information, and filter the available agents to ones that are likely to be usable:

* If the requestor is a CLI app, and there is no $DISPLAY variable or similar, then contacting GUIs is probably a bad idea. It's probably also a bad idea to contact text-based agents with a different pty/tty, but that might be appropriate if there is no alternative (e.g. we're running under systemd or otherwise do not have a controlling terminal).
* Similarly, if the requestor is a GUI, contacting text-based agents is probably a bad idea.
* Finally, if we're a CLI app with a $DISPLAY, then it might be OK to contact GUIs on that specific display, as well as text-based agents on the same pty/tty. But it should not contact some random other session that has nothing to do with us.

run0

Posted Dec 17, 2025 9:12 UTC (Wed) by taladar (subscriber, #68407) [Link] (1 responses)

Alternatively maybe some sort of approach similar to systemd-ask-password could be used where it is possible to call a command to get the prompt to your current terminal even if the automatic prompting is happening somewhere else?

run0

Posted Dec 17, 2025 13:58 UTC (Wed) by mathstuf (subscriber, #69389) [Link]

There is the `wall` implementation. `systemd-tty-ask-password-agent` is not polkit-enabled to answer system requests as a user though. See https://github.com/systemd/systemd-ui/pull/7 for updating a simple GUI agent to modernity. A TTY agent would be nice to have too.

run0

Posted Dec 17, 2025 10:07 UTC (Wed) by mchapman (subscriber, #66589) [Link] (15 responses)

> I wonder if polkit should be patched to avoid contacting authentication agents that belong to another seat (and treat absence of a defined seat as a unique ephemeral seat that does not compare equal to anything but itself).

As far as I know this is supposed to happen already.

A polkit agent is always registered against a particular process or logind session. When polkit needs to talk to an agent, it determines it according to the subject of the authorization: either that process itself (i.e. it's acting as its own agent), or the logind session that owns that process.

Where I have seen this break is when people start Tmux or Screen in their GUI session, then, at a later time, reconnect to that over SSH. When they reconnect to it they are effectively back in that GUI session, even if they aren't sitting at that seat.

run0

Posted Dec 17, 2025 21:50 UTC (Wed) by raven667 (subscriber, #5198) [Link]

This makes a lot of sense and I wish there was a better understanding of how this stuff actually works, and how it's intended to work, so that its easier to intuitively guess at possible problems/solutions rather than assuming the system is fundamentally broken and incapable of doing a bunch of things it already does. I sometimes see people going the long way and working around problems which are fundamentally misunderstandings of how a system was designed to work, then complain about how the system is b0rken and incomplete because it doesn't do $THING when it does, they just didn't know how (and sometimes its _very_ poorly documented, or hard to find). I hate to see people's effort going to waste building systems that don't get used.

run0

Posted Dec 18, 2025 7:38 UTC (Thu) by SLi (subscriber, #53131) [Link] (10 responses)

Is there a fix to this, other than don't use tmux or screen?

run0

Posted Dec 19, 2025 13:56 UTC (Fri) by paulj (subscriber, #341) [Link] (9 responses)

I'm also curious on the answer to this.

run0

Posted Dec 21, 2025 4:37 UTC (Sun) by mathstuf (subscriber, #69389) [Link] (8 responses)

I've posited it elsewhere, but it only helps those running `systemd` (probably not an issue for `run0` users though).

If we could get a polkit agent to forward through password agents[1] and a TTY-based agent that rang `\a` bell when a new request comes in, you could open it in a screen/tmux window, go over to it, enter the password, then go back to what you were doing. I've asked udiskie to plumb requests through agents. A polkit agent that did the same would be nice to have as well (whether a new one or a change to an existing agent).

I'm willing to work on the TTY password agent part if someone else wants to start on the polkit agent side.

[1] https://systemd.io/PASSWORD_AGENTS/

Interaction multiplexing

Posted Dec 21, 2025 14:05 UTC (Sun) by SLi (subscriber, #53131) [Link] (7 responses)

This feels to me something of a specific solution to a generic problem, and my instinct would be to ask if we can solve the class of problems instead. It doesn't apply only to $SSH_ASKPASS but also things like $DISPLAY; and a large part of the problem is that environment variables are frozen at program startup time.

I would frame the generic problem as:

> Given this process, what human-facing I/O endpoints are actually reachable right now, and which one is the user currently attending to, even if that differs from the environment at exec time?

(Now this is still ambiguous to an extent; one can attach to tmux from multiple places.)

Is there a generic way we could approach solving this? I *think* there is.

Terminal managers like tmux are at a position where they can have that information, probably better than anyone else. They just aren't able to modify the environment of the running program to inform it, so there needs to be an out-of-band way to query the terminal emulator for the information.

I first thought of weird query-response OSC escape sequences; but they are tricky, and I think don't have an advantage in this case, because the one thing tmux *can* provide to all programs is an out-of-band mechanism.

Here's where this line of thought evolved. Option A keeps tmux self-contained and maximally useful on its own; option B minimizes tmux-specific policy and makes it easier to share semantics with other multiplexers or brokers.

# Option A ("flat"):

- We have an environment variable. I'm bad at naming, so I call it INTERACTIVE_CONTEXT.

- it contains a capability-ish _pointer_ to "who can route interaction for me", not the answer:

> INTERACTIVE_CONTEXT=unix:/run/user/1000/interactive/ctx-<token>.sock

- It is set initially by PAM or systemd user manager (or something using something like XDG_RUNTIME_DIR on non-systemd contexts)

- On a GUI login, it points to the GUI session broker. On a SSH login, it points to the SSH session broker

- Multiplexers like tmux wrap it. When tmux starts a session/window, it sets it to

> INTERACTIVE_CONTEXT = unix:/run/user/1000/interactive/tmux-ctx-<serverid>.sock

- The tmux context service can select "the most suitable client" (last-active, last-attached, view-of-pane, whatever); then either handle prompting itself, forward to the outer context of the chosen client, or maybe just tell "sorry, interaction is not available".

- To forward, tmux needs to remember each client's "outer" INTERACTIVE_CONTEXT at attach time. So when `tmux attach` runs, it captures the attaching environment's INTERACTIVE_CONTEXT and stores it per-client.

# Option B (delegating pointer chain)

Like option A, but instead of tmux implementing everything, its socket would implement only

- `resolve()` -> returns INTERACTIVE_CONTEXT for best client
- `describe()` -> says "I'm a multiplexer; here's what I'd choose"
- optionally `prompt()` implemented by forwarding (not UI)

---

I think there are some security implications that need thinking. I think the most useful model here is that the terminal multiplexer arbitrates "the most suitable client" and external policy decides "what this endpoint is allowed to do". One useful mental model may be to treat INTERACTIVE_CONTEXT as a bearer capability scoped to a login or multiplexer context, rather than as a global per-user resource (instead of "any same-UID process can pop auth prompts everywhere")

Interaction multiplexing

Posted Dec 22, 2025 5:31 UTC (Mon) by mathstuf (subscriber, #69389) [Link] (6 responses)

> > Given this process, what human-facing I/O endpoints are actually reachable right now, and which one is the user currently attending to, even if that differs from the environment at exec time?

Is this really answerable in a generic way? Say I am ssh'd into a machine from my laptop. I attach to a tmux session. How is there any indication that the desktop is at my feet with the screen unlocked and keyboard accessible at the desk I'm sitting in front of? I don't want to manage that state by hand and I really have no idea how one would automate it (maybe some BLE presence metrics, but I am not my phone (or even watch), so that isn't really crossing over the "works most of the time, but enough to be frustrating when it doesn't" threshold in my book).

I don't see why it needs all this extra stuff. You run an agent to answer requests (polkit, passwords, etc.) where you interact (the DE, the I-ssh'd-in tmux session, etc.). Any agent can answer a request; any agent's answer is sufficient. Requests come over the standard protocols (DBus, inotify-on-a-directory) and you manage them given the UI you provide. If you want to know you're in tmux and broadcast it with `tmux display-message -c $client` (or `display-popup`) so that you don't even need the agent's session to be active, that sounds a lot simpler to me.

Interaction multiplexing

Posted Dec 22, 2025 9:23 UTC (Mon) by taladar (subscriber, #68407) [Link] (2 responses)

I like the general idea but why do they need to be requests to agents at all, wouldn't it be even simpler if they were just notifications about a new password request so that even seats where the user logged in after the request was created could respond to the request by polling for pending requests after login or when the user asks for them explicitly?

Interaction multiplexing

Posted Dec 22, 2025 14:11 UTC (Mon) by mathstuf (subscriber, #69389) [Link]

Polkit sits on DBus, so you're stuck with a "proper" agent there. The systemd protocol is "drop files in a directory", so you could definitely use notification actions to trigger the actual prompt (systemd-gnome-ask-password-agent does this). It also scans on startup and sends notifications for anything "laying around" when it starts up. Just need something that doesn't rely on a GUI and notification daemon (the TTY agent I mentioned).

Interaction multiplexing

Posted Dec 22, 2025 17:01 UTC (Mon) by SLi (subscriber, #53131) [Link]

Yes, I think this makes sense; essentially, decoupling request creation from request fulfillment. I think this pushes in the direction of making the request durable and discoverable, which I like. I think it's largely orthogonal to the idea of making the routing contextual.

Interaction multiplexing

Posted Dec 22, 2025 16:48 UTC (Mon) by SLi (subscriber, #53131) [Link] (1 responses)

> Is this really answerable in a generic way?

No, not in any foolproof way. You cannot infer presence. But you can do heuristics that are better than defaulting to whatever it was when you started this program by answering questions like which interaction endpoints are currently attached and responsive, and which of those have most recently had user activity.

tmux, for example, does not know if the local desktop seat is unlocked, but it does know whether there is a client attached over SSH that has recently been active.

So, sure, perfect correctness is probably impossible, but that just bounds the abstraction to something that is less likely to be completely wrong.

Interaction multiplexing

Posted Dec 23, 2025 14:40 UTC (Tue) by taladar (subscriber, #68407) [Link]

Being correct all the time is also not necessarily required if you do allow the user to override the heuristic when it guesses wrong by e.g. running a command on a terminal they do have access to to get to the prompt. 100% correctness is hard but it is only made necessary by the lack of remedial options when the heuristic guesses wrong.

Interaction multiplexing

Posted Dec 22, 2025 16:58 UTC (Mon) by SLi (subscriber, #53131) [Link]

> I don't see why it needs all this extra stuff. You run an agent to answer requests (polkit, passwords, etc.) where you interact (the DE, the I-ssh'd-in tmux session, etc.). Any agent can answer a request; any agent's answer is sufficient. Requests come over the standard protocols (DBus, inotify-on-a-directory) and you manage them given the UI you provide. If you want to know you're in tmux and broadcast it with `tmux display-message -c $client` (or `display-popup`) so that you don't even need the agent's session to be active, that sounds a lot simpler to me.

A broadcast model like this would probably work for a password prompt, in a sense. It would fail for other examples of the same problem class ("which DISPLAY to connect to"). Even for the password prompt, I think it does have some downsides.

First, it's not really very symmetric across transports. GUI agents work well with dbus + desktop notifications; TTY agents require explicit discovery and focus; and headless/multiplexed contexts are rather second class.

Second, I think a generally useful idea is "route this request to the same place the user typed the command". I think a broadcast model of, essentially, "route this request somewhere and hope the user notices" is sufficient for things like boot time disk unlocks, and more frustrating for interactive admin commands over ssh+tmux.

So, yes, I think the broadcast model works, but it gives up the correlation. Maybe that's sufficient.

run0

Posted Dec 18, 2025 13:25 UTC (Thu) by intelfx (subscriber, #130118) [Link] (2 responses)

> polkit agent is always registered against a particular process or logind session. When polkit needs to talk to an agent, it determines it according to the subject of the authorization: either that process itself (i.e. it's acting as its own agent), or the logind session that owns that process.

Ah, but the part about how to treat the "absence of a defined seat" was load-bearing in my reply.

> Where I have seen this break is when people start Tmux or Screen in their GUI session, then, at a later time, reconnect to that over SSH. When they reconnect to it they are effectively back in that GUI session, even if they aren't sitting at that seat.

In my personal setup, tmux server runs under `systemd --user`, outside of any defined session (and certainly outside of the session that owns seat0). Yet, when I run pkexec under tmux, it still gets ahold of the GUI authentication agent, despite having no reason to do so.

For instance, I went to specific pains to forward proper environment into each new tmux pane (such that when I create a new tmux pane from an SSH connection, that pane inherits specific environment variables of the SSH connection), and it inherits the SSH connection's $XDG_SESSION_ID. But none of this helps polkit to avoid contacting the GUI agent.

run0

Posted Dec 18, 2025 13:32 UTC (Thu) by intelfx (subscriber, #130118) [Link] (1 responses)

> In my personal setup, tmux server runs under `systemd --user`, outside of any defined session

Slight correction: `systemd --user` is not outside of any defined session — it does, in fact, run under its own logind session (of class "manager"). But that does not materially change what I said (it's still not the session that owns seat0).

run0

Posted Dec 22, 2025 7:04 UTC (Mon) by mchapman (subscriber, #66589) [Link]

Ah, you're right. Polkit explicitly asks logind for the user's current "display" session if a session can't be identified for the process.

Perhaps it shouldn't do that, since it thwarts any attempt by that process to provide a fallback agent (which all the systemd tools do when they're using polkit).


Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds