Skip to content

Add portal

Carlos Garnacho requested to merge wip/carlosg/portal into master

This MR:

  1. Adds CONSTRAINT (GRAPH | SERVICE) IRIREF,IRIREF... syntax to query/update prologues. These clauses constrain the graphs and services a query has access to. Multiple CONSTRAINT statements intersect the pool of accessible graphs and services. Disjoint CONSTRAINT requests will end up with an empty set of accessible graphs and services, in which case selects will come up empty and updates will error out. The minimal CONSTRAINT (GRAPH | SERVICE) syntax with no IRIREFs will force the empty set.

  2. Adds internal plumbing to TrackerEndpoint to be able to subclass it to implement portal bits without committing yet to further public API.

  3. Adds a portal service. It takes the org.freedesktop.portal.Tracker name, so it's visible within flatpak sandboxes. And works by:

  • Having the sparql bus connection implementation in libtracker-sparql detect it's in a sandbox by stat()ing /.flatpak-info, and talk to org.freedesktop.portal.Tracker instead
  • The portal process will impersonate all endpoints, for every allowed+requested client/endpoint combination it will create a SPARQL bus connection to it, and will expose it to the sandbox through a TrackerEndpoint at a DBus path that is returned to the client.
  • For permissions, the portal process will reach to the /.flatpak-info file within the sandbox, and look for Tracker policies, those consist of endpoint=graph;graph;... keys, so the portal knows which endpoints can the sandboxed client access, and which graphs in those.
  • For the actual access control:
    • The sandboxed endpoints are made readonly by default, no update queries allowed. If updates to external endpoints are desirable within the sandboxed app, allow access to the endpoint DBus name.
    • All queries proxied through a sandboxed endpoint get a CONSTRAINT GRAPH clause prepended that match the policy for the target endpoint. They also get an empty CONSTRAINT SERVICE that will forbid nested SERVICE {} clauses from being executed on behalf of the sandboxed application.
    • All TrackerNotifier::events from the endpoint being proxied will be filtered based on the graph argument in that signal, letting the sandboxed client only know of events in graphs it has access to.

This makes it possible to define the accessible data in flatpak manifests, eg:

"finish-args" : [
    /* Define policy for the XDG Tracker portal */
    "--add-policy=Tracker3.dbus:org.freedesktop.Tracker1.Miner.Files=org.freedesktop.XdgFolder.Music"
    ],

That will result in:

[Tracker3 Policy]
org.freedesktop.Tracker1.Miner.Files=org.freedesktop.XdgFolder.Music

in the /.flatpak-info file ready to be picked up by the portal process, thus giving access to the miner service, and only to the music graph (name TBD).

Traditionally portals do implement UI, that the user reacts to, however I think an UI here would check 2 big no-nos in those:

  • It'd boil down to a yes/no question
  • The generic question that applies here is "access to graph a anb b from service s?", besides several services may be requested. It is complex and doesn't strike me as good UI to delegate on the user. For some matches it could be translated to more human language (eg. "Access to your indexed music?"), but it soon falls over if other service/graph combinations happen.

This approach is UI-less, and keeps the advantage to fiddle externally with the flatpak permissions (--add-policy is eg. also allowed in flatpak run), but will still keep the sandboxed app unable to break out of it.

Edited by Carlos Garnacho

Merge request reports