← Otto Developer GuidePermissions

What Otto keeps away from sandboxed apps and why it stops there, and how it asks for the password. The sandbox code is src/sandbox.rs and the filters on each global in src/state/; the tests are tests/sandboxed_globals.rs, tests/session_lock.rs and tests/idle_inhibit.rs.

The one boundary

Programs running as the user, outside a sandbox, already have the user’s rights: they can edit config.toml, read the user’s files and debug the user’s other programs. The compositor does not gate them.

A Flatpak app is cut off from all of that, but it talks to the compositor over the Wayland socket. If Otto offered it the virtual keyboard it could type into a terminal; with screencopy it could read the screen. So the compositor must not be a way out of the sandbox.

Flatpak connects its apps through a wp_security_context_v1 listener. is_sandboxed_client is true for every client that came in that way, and these globals are never offered to it:

A Flatpak that needs to capture the screen goes through xdg-desktop-portal, which asks the user.

D-Bus needs nothing from Otto: Flatpak’s bus proxy already limits an app to the portals and the names it declares, so it cannot reach org.otto.*.

Not covered

The lock screen

These are about the lock being reliable rather than about sandboxes:

The auth panel

Every password Otto asks for outside the lock screen goes through polkit, and Otto is the session’s polkit authentication agent:

Protected settings (settings::schema::PROTECTED: the locker, greeter, auto-lock, locking on suspend, the lid and power button) ask polkit for org.otto.settings.lock (auth_self) before Set or Reset applies them (src/settings/polkit.rs). The subject is the compositor’s own process, so polkitd asks Otto’s agent, which words the panel from the otto.setting, otto.value and otto.label details. The schema marks these settings with confirm = "password", so Settings knows a Set may wait for the user.

Settings › Privacy

The Privacy pane (components/otto-settings/src/panes/privacy.rs) reads and writes xdg-permission-store through otto_kit::permission_store, and follows its Changed signal while shown:

The portal (components/xdg-desktop-portal-otto/src/portal/remembered.rs) writes a screencast entry of the frontend’s own shape (otto-… id, the app holding yes, the (suv) restore payload) when “Remember for ” is ticked, and on a request without restore data reuses any entry the app holds. The checkbox is the Access dialog’s choice with no options, group otto.remember, whose label is the app’s name; otto-islands words it. Apps with the empty app id are never remembered.

Screen capture