mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-09-06 16:56:00 +00:00
216 lines
6.3 KiB
Plaintext
216 lines
6.3 KiB
Plaintext
/** \page page_portal Portal Access Control
|
|
|
|
This document explains how clients from the portal are handled.
|
|
|
|
The portal is a DBus service that exposes interfaces to
|
|
request access to the PipeWire daemon to perform a certain set of
|
|
functions. The PipeWire daemon runs outside the sandbox, the portal is a way
|
|
for clients inside the sandbox to connect to and use PipeWire.
|
|
|
|
The PipeWire socket is not exposed in the sandbox. Instead, The portal
|
|
connects to PipeWire on behalf of the client, informing PipeWire that this
|
|
client is a portal-managed client. PipeWire can detect and enforce
|
|
extra permission checks on the portal managed clients.
|
|
|
|
Once such portal is the [camera
|
|
portal](https://flatpak.github.io/xdg-desktop-portal/portal-docs.html#gdbus-org.freedesktop.portal.Camera)
|
|
that provides a PipeWire session to stream video from a camera.
|
|
|
|
|
|
# Use Cases
|
|
|
|
## New Portal Managed Clients Need Device Permissions Configured
|
|
|
|
When a new client is detected, the available objects need to be
|
|
scanned and permissions configured for each of them.
|
|
|
|
Only the devices belonging to the media_roles given by the
|
|
portal are considered.
|
|
|
|
## New Devices Need To Be Made Visible To Portal Managed Clients
|
|
|
|
Newly created objects are made visible to a client when the client
|
|
is allowed to interact with it.
|
|
|
|
Only the devices belonging to the media_roles given by the
|
|
portal are considered.
|
|
|
|
## Permissions For A Device Need To Be Revoked
|
|
|
|
The session manager listens to changes in the permissions of devices
|
|
and will remove the client permissions accordingly.
|
|
|
|
Usually this is implemented by listening to the permission store
|
|
DBus object. The desktop environment might provide a configuration panel
|
|
where these permissions can be managed.
|
|
|
|
|
|
# Design
|
|
|
|
## The Portal
|
|
|
|
A sandboxed client cannot connect to PipeWire directly. Instead, it connects
|
|
to the sandbox side of the portal which then connects the PipeWire daemon to
|
|
configure the session. The portal then hands the file descriptor of the
|
|
PipeWire connection to the client and the client can use this file descriptor
|
|
to interface with the PipeWire session directly.
|
|
|
|
When the portal connects, it will set the following properties on the
|
|
client object:
|
|
|
|
- `"pipewire.access.portal.is_portal" = true` for the connection of the
|
|
portal itself (as opposed to a client managed by the portal).
|
|
- `"pipewire.access.portal.app_id"` the [application ID](https://docs.flatpak.org/en/latest/conventions.html#application-ids) of the client.
|
|
- `"pipewire.access.portal.media_roles"` media roles of the client.
|
|
Currently only `"Camera"` is defined.
|
|
|
|
Before returning the connection to a client, the portal configures
|
|
minimal permissions on the client. No objects are initially visible. It is
|
|
the task of the \ref page_session_manager to make the objects in the graph
|
|
visible, depending on the client's `media_roles` (see also \ref
|
|
PW_KEY_MEDIA_ROLE).
|
|
|
|
## The PipeWire Portal Module
|
|
|
|
The PipeWire daemon uses the \ref page_module_portal to find the PID of the
|
|
processes that owns the DBus name `org.freedesktop.portal.Desktop`
|
|
(see the [XDG Desktop Portal](https://github.com/flatpak/xdg-desktop-portal)).
|
|
|
|
Client connections from this PID are tagged as \ref PW_KEY_ACCESS
|
|
`"portal"` (see \ref page_module_access). It will also set ALL permissions for
|
|
this client so that it can resume.
|
|
|
|
\dot
|
|
digraph pw {
|
|
compound=true;
|
|
node [shape="box"];
|
|
rankdir="TB";
|
|
|
|
dbus [label="org.freedesktop.portal.Desktop"];
|
|
|
|
portal_access [label="PipeWire (mod: Portal Access)"];
|
|
portal [label="xdg-desktop-portal"];
|
|
|
|
dbus -> portal_access [arrowhead="dot"];
|
|
dbus -> portal [arrowhead="dot"];
|
|
|
|
portal_access -> portal [label="pipewire.access = portal"];
|
|
|
|
{ rank="same"; portal_access; portal}
|
|
}
|
|
\enddot
|
|
|
|
## The Client
|
|
|
|
A client can ask the portal for a connection to the PipeWire daemon.
|
|
|
|
\dot
|
|
digraph pw {
|
|
compound=true;
|
|
node [shape="box"];
|
|
rankdir="LR";
|
|
|
|
pw [label="PipeWire"];
|
|
portal [label="xdg-desktop-portal"];
|
|
client [label="client"];
|
|
|
|
client -> portal;
|
|
portal -> pw [label="portal.is_portal=true", arrowhead="none"]
|
|
|
|
{rank="min"; pw};
|
|
{rank="max"; client};
|
|
}
|
|
\enddot
|
|
|
|
The portal maintains an (unrestricted) connection to the PipeWire daemon with
|
|
`"pipewire.access.portal.is_portal" = true` to identify the nodes the client
|
|
needs access to. It then creates a new restricted connection for the client,
|
|
tagged with additional information.
|
|
|
|
\dot
|
|
digraph pw {
|
|
compound=true;
|
|
node [shape="box"];
|
|
rankdir="LR";
|
|
|
|
pw [label="PipeWire"];
|
|
portal [label="xdg-desktop-portal"];
|
|
client [label="client"];
|
|
|
|
client -> portal [arrowhead="none"];
|
|
portal -> pw [label="portal.is_portal=true", arrowhead="none"]
|
|
portal -> pw [label="portal.app_id = $appid"]
|
|
|
|
{rank="min"; pw};
|
|
{rank="max"; client};
|
|
}
|
|
\enddot
|
|
|
|
The file descriptor for this restricted connection is passed back to the
|
|
client which can now make use of the resources it has been permitted to
|
|
access.
|
|
|
|
\dot
|
|
digraph pw {
|
|
compound=true;
|
|
node [shape="box"];
|
|
rankdir="LR";
|
|
|
|
pw [label="PipeWire"];
|
|
portal [label="xdg-desktop-portal"];
|
|
client [label="client"];
|
|
|
|
portal -> pw [label="portal.is_portal=true", arrowhead="none"]
|
|
|
|
pw->client [label="restricted connection"];
|
|
|
|
{rank="min"; pw};
|
|
{rank="max"; client};
|
|
}
|
|
\enddot
|
|
|
|
## The Session Manager
|
|
|
|
The session manager listens for new clients to appear. It will use the
|
|
\ref PW_KEY_ACCESS property to find portal connections. For client connections
|
|
from the portal the session manager checks the requested `media_roles` and
|
|
enables or disables access to the respective PipeWire objects.
|
|
It might have to consult a database to decide what is allowed, for example the
|
|
[org.freedesktop.impl.portal.PermissionStore](https://flatpak.github.io/xdg-desktop-portal/portal-docs.html#gdbus-org.freedesktop.impl.portal.PermissionStore).
|
|
|
|
\dot
|
|
strict digraph pw {
|
|
compound=true;
|
|
node [shape="box"];
|
|
rankdir="LR";
|
|
|
|
portal [label="xdg-desktop-portal"];
|
|
client [label="client"];
|
|
|
|
|
|
subgraph {
|
|
rankdir="TB";
|
|
permissions [label="PermissionStore"];
|
|
|
|
sm->permissions;
|
|
|
|
sm [label="Session Manager"];
|
|
pw [label="PipeWire"];
|
|
sm -> pw [headlabel="allow $media.roles"];
|
|
pw -> sm;
|
|
portal -> pw [label="portal.app_id = $appid"];
|
|
}
|
|
|
|
client -> portal [arrowhead="none"];
|
|
|
|
{rank="min"; sm, pw};
|
|
{rank="max"; client};
|
|
}
|
|
\enddot
|
|
|
|
In the case of the [XDG Desktop
|
|
Portal](https://github.com/flatpak/xdg-desktop-portal), the portal itself
|
|
queries the PermissionStore directly.
|
|
|
|
*/
|