diff --git a/docs/sandbox-permissions.rst b/docs/sandbox-permissions.rst index a236effe..15386c65 100644 --- a/docs/sandbox-permissions.rst +++ b/docs/sandbox-permissions.rst @@ -472,6 +472,104 @@ Note that these should not have subpaths in them unless the value of the subpath can be consistently pre-determined. Block device naming depends on the kernel/fstab configuration and cannot be pre-determined. +Conditional permissions +----------------------- + +Since 1.17.0, Flatpak supports conditional permissions which allows +them to be granted only when certain runtime conditions are satisfied +and fallback otherwise. The intention of the system is to allow +users or developers to specify tighter permission grants (as they are +added in new Flatpak versions) while fallback to older grants for +backwards compatibility at run time. + +.. note:: + + Older Flatpak versions will fail when encountering unknown + commandline options, while unrecognized metadata entries will be + silently ignored. + + Flatpak manifests using conditional flags (for example, + ``--socket-if=`` etc.) will require Flatpak 1.17.0 or newer to + build and attempting to build them with older Flatpak versions will + produce an error. + +The following flags are available to specify conditional +permissions in CLI and in Flatpak manifests:: + + --socket-if= + --device-if= + --share-if= + --allow-if= + +The syntax of all the options are ``--socket-if=PERMISSION:CONDITION`` +and so on where ``PERMISSION`` is the available grants for that flag +(e.g., those listed for ``--socket=``). Conditions can be negated by +prefixing with ``!``. The following conditions are supported: + +- ``true`` - Always evaluates to true +- ``false``- Always evaluates to false +- ``has-input-device`` - True if the Flatpak version supports + ``--device=input`` +- ``has-wayland`` - True if the current desktop session supports + Wayland + +Multiple conditionals can be specified for the same grant, in which +case the permission is granted if any condition matches. If no +conditional rule evaluates to ``true``, the grant is denied +unless it is also unconditionally allowed. Duplicate conditions are +ignored. + +Examples +````````` + +#. The unconditional grant ``--socket=x11`` can be tightened using + conditional permissions to ``--socket-if=x11:!has-wayland``. This + allows access to X11 only when a Wayland desktop session is not + available. To preserve backwards compatibility, the following + pattern can be used:: + + --socket=x11 + --socket-if=x11:!has-wayland + + This allows older Flatpak versions which do not understand the + conditional permissions function by allowing X11 access always + while newer Flatpak, which understands the conditional system will + allow X11 access only when the session is not Wayland. + +#. If an application requires only access to ``input`` device permission, + the following flags can be used to move away from ``--device=all`` + to ``--device=input``:: + + --device=all + --device-if=all:!has-input-device + --device=input + + This allows older Flatpak versions which do not understand the + ``input`` device permission to function by having the broader + ``all`` access. Newer Flatpak versions which understand the + conditional system (and therefore understands the ``input`` + permission) will deny ``all`` due to + ``--device-if=all:!has-input-device`` and allow only ``input`` due + to ``--device=input``. + +To explicitly deny a permission that might be granted through runtime +metadata or overrides ``--nosocket=NAME, --unshare=NAME`` etc. can be +used:: + + --nosocket=x11 + +This denial can be combined with conditional grants to remove +unconditional access while allowing conditional access:: + + --nosocket=x11 + --socket=x11 + --socket-if=x11:!has-wayland + +This denies unconditional X11 access but allows X11 conditionally when +Wayland is unavailable. Older Flatpak versions will see only the final +``--socket=x11`` grant and allow X11 unconditionally, while newer +versions recognise the conditional logic and evaluates it at runtime. + .. rubric:: Footnotes .. [#f1] This is not necessarily required, but without it the X11 shared diff --git a/docs/under-the-hood.rst b/docs/under-the-hood.rst index 4e7c1110..7884ced3 100644 --- a/docs/under-the-hood.rst +++ b/docs/under-the-hood.rst @@ -47,6 +47,85 @@ stored once. This `blog post `_ explains the underlying structure of a Flatpak repository in more detail. +Conditional permission system +----------------------------- + +Since Flatpak 1.17.0, conditional permissions allow permissions to be +granted only when certain runtime conditions are satisfied, with +fallback to unconditional grants for compatibility with older versions. + +Permissions are internally represented as: + +- unconditionally allowed or denied +- a reset flag indicating whether the current layer overrides rules + from lower layers +- a set of conditional rules under which the permission may be allowed + +For example: + +- ``--socket=NAME`` unconditionally allows the permission and resets any + previously defined rules for that permission +- ``--nosocket=NAME`` unconditionally denies the permission and resets + any previously defined rules +- ``--socket-if=NAME:CONDITION`` adds a conditional rule without + resetting existing rules + +Conditions may be negated using ``!``. + +Multiple conditional rules can be specified for the same permission. In +this case, the permission is granted if any condition evaluates to true. + +Duplicate conditions are ignored. The order of conditions does not +affect evaluation. + +If no conditional rules are present, the permission is granted only if +it is unconditionally allowed. + +If conditional rules are present, the permission is granted if any +condition evaluates to true, and denied otherwise, unless it is also +unconditionally allowed. + +If an unconditional entry follows a conditional entry for the same +grant in commandline flags, the earlier unconditional entry is treated +as backwards compatibility fallback and does not affect the final +permission state. So the following is effectively treated as +``--socket-if=x11:!has-wayland`` in Flatpak versions supporting +conditional permissions:: + + --socket=x11 + --socket-if=x11:!has-wayland + +Permissions are written to metadata using the following rules: + +- Unconditionally allowed permissions are written as ``NAME`` +- Unconditionally denied permissions are written as ``!NAME`` +- Conditionally allowed permissions are written as: + + - unconditional ``NAME`` entry for compat + - ``if:NAME:CONDITION`` entries + +If the permission resets previously defined rules, an explicit ``!NAME`` +entry is written first, followed by the unconditional ``NAME`` entry and +then the ``if:NAME:CONDITION`` entries. This is omitted when saving an +application's own metadata, as opposed to overrides. + +When parsing metadata, a non-negated unconditional ``NAME`` entry +appearing before a ``if:NAME:CONDITION`` entry is treated as a +compatibility fallback and does not affect the final permission +state. Eg. ``sockets=x11;if:x11:!has-wayland;`` is effectively treated +as ``if:x11:!has-wayland`` in Flatpak versions supporting +conditional permissions. + +The ``fallback-x11`` socket, on pre-1.17 Flatpak versions implicitly +granted ``x11`` access and at runtime X11 access was suppressed when +Wayland was available, while on newer Flatpak (1.17+) it is internally +converted to the conditional syntax ``if:x11:!has-wayland``. When saving +the metadata, Flatpak converts ``if:x11:!has-wayland`` back to +``fallback-x11`` only when it is the sole conditional on ``x11``. If +additional conditionals are present, the new syntax is written directly +and older Flatpak versions will not understand the conditional entries. +A conditional grant for ``fallback-x11`` is not allowed. + Underlying technologies -----------------------