The dbus interface

dbus enables ownership of a specific name on the session or system D-Bus.

Auto-connect: no Attributes:

  • name (slot): well-known D-Bus connection name for the service (eg, org.foo.bar)
  • bus (slot): D-Bus bus to use (ie, session or system)
  • name (plug): well-known D-Bus connection name of the service from the providing snap
  • bus (plug): D-Bus bus to use for providing snap

Snaps that want to communicate via a well-known D-Bus connection name need to have matching bus and name attributes and then be connected via snap connect. Snaps specifying bus: system will have a default D-Bus bus policy that allows root to own the name and anyone to send to a destination that matches the well-known name (eg, org.foo.bar). Once connected, the consuming snap may communicate with the providing snap via:

  • the specified well-known D-Bus connection name (eg, org.foo.bar)
  • a unique D-Bus connection name using a matching D-Bus interface (eg, org.foo.bar.baz) or D-Bus path (eg, /org/foo/bar/norf)

This interface is particularly well-suited for leaf-style applications from GNOME, KDE, etc to integrate into the desktop session. Future versions of snapd may allow greater flexibility for bus policy, D-Bus interfaces and D-Bus paths and also support session services and D-Bus activation.

Note: when developing snaps using devmode for D-Bus system services, the slot implementation must use this interface so that snapd may adjust the D-Bus bus policy so the snap may use the system bus.

ⓘ This is a snap interface. See Interface management and Supported interfaces for further details on how interfaces are used.

Using the D-Bus interface

The dbus interface provides a way for snaps to communicate over D-Bus. The snap providing the D-Bus service declares a slot with the well-known D-Bus name and which bus it uses. Snaps wanting to communicate with the providing snap’s service declare a plug for the providing snap. Note that a snap declaration is needed for your snap to be delivered via the snap store and claim this well-known D-Bus name (simply upload the snap to the store and request a manual review and a reviewer will take a look).

When a providing snap is installed, snapd will generate security policy that will allow it to listen on the well-known D-Bus name on the specified bus. If the system bus is specified, snapd will also generate D-Bus bus policy that allows ‘root’ to own the name and any user to communicate with the service. Non-snap processes are allowed to communicate with the providing snap following traditional permissions checks. Other (consuming) snaps may only communicate with the providing snap by connecting the snaps’ interface.

Examples

Desktop application

Desktop applications sometimes listen on a well-known D-Bus name so that other desktop session services and applications may interact with them. This is common for GNOME and KDE applications, for example. Snaps listening on the session bus may only be accessed by processes running in the user’s session.

Providing snap (slot)

As a developer, if your application listens on the session bus with the well-known name “org.example.foo”, then you might adjust your snap’s yaml to have:

name: foo
...
slots:
  dbus-svc: # name that is used with 'snap connect' on slots side
    interface: dbus
    bus: session
    name: org.example.foo
...
apps:
  foo:
    command: ...
    slots: [ dbus-svc ]

Consuming snap (plug)

As a developer, if you want your snap to communicate over D-Bus with another snap via the “org.example.foo” D-Bus well-known name on the session bus, you might adjust your snap’s yaml to have:

name: bar
...
plugs:
  foo-svc:  # name that is used with 'snap connect' on plugs side
    bus: session
    interface: dbus
    name: org.example.foo
...
apps:
  bar:
    command: ...
    plugs:
    - foo-svc

System service

Services may also listen on the D-Bus system bus. Snaps listening on the system bus run as root and may be accessed by any user on the system. While the snapd security policy will limit which connecting snaps can communicate with the service, slot implementations may want to perform additional permission checks (eg, UID) to further limit access.

Providing snap

As a developer, if your application listens on the system bus with the well-known name “org.example.foo”, then the snap’s yaml is the same as above, but specify the system bus:

name: foo
...
slots:
  dbus-svc: # name that is used with 'snap connect' on slots side
    interface: dbus
    bus: system
    name: org.example.foo
...
apps:
  foo:
    command: ...
    slots: [ dbus-svc ]

Consuming snap

As a developer, if you want your snap to communicate over D-Bus with another snap via the “org.example.foo” D-Bus well-known name on the system bus, then the snap’s yaml is the same as above, but specify the system bus:slight_smile:

name: bar
...
plugs:
  foo-svc:  # name that is used with 'snap connect' on plugs side
    bus: system
    interface: dbus
    name: org.example.foo
...

Snap dbus interface connections

As a user, if you want to allow bar to communicate with foo via D-Bus, then you can connect the interface like so:

$ sudo snap connect bar:foo-svc foo:dbus-svc

You can check it’s worked with the following:

$ snap connections
Interface           Plug                 Slot               Notes
dbus-svc            bar:dbus-svc         foo:dbus-svc       -
[...]

To disconnect:

$ sudo snap disconnect bar:foo-svc foo:dbus-svc

Future work

Autostarting of D-Bus session services and D-Bus activation is not supported at this time, but is planned. When that support is added, this document will be updated accordingly.

References

1 Like

I’d like to note that currently,

  1. docs.snapcraft.io snapcraft syntax doesn’t mention the plugs and slots keywords
  2. The Attributes field in the docs.snapcraft.io interfaces reference doesn’t mention how the attributes can be used, it probably should be linked to the documentation of 1.

I doubt this part is required, can anyone confirm it? I believe the external slots keyword already applies to the entire snaps.

It isn’t required but is considered best practice to do it this way. There will be only one command that will actually bind to the well-known name, so limiting the slot to that command makes sense.

1 Like

I have a question regarding the general purpose of the dbus interface:

is it intended only for snap-to-snap dbus connections, or it also should be used if I want to grant my snap access to some other org.foo.bar service present on the session/system bus?

For example, do I use it to grant my snap access to org.gnome.SettingsDaemon.Power.Screen object? As I understand, my snap would be a “consumer” in this context, which means I have to define a plug with dbus interface for it, but there are no respective slot anywhere that I can connect to since the service is not provided by other snap.

the gsettings interface should provide you access to all user related gnome-settings-daemon options … many dbus permissions are already granted by existing interfaces and the snappy-debug tool should tell you about which of them to use.

Hello, Thank you for response,

I tried adding “gsettings” interface with no luck - the are no permissions in the apparmor profile and snappy-debug still shows access violations (more details on this in here).

But on the first question, is dbus interface is intended only for snap-to-snap communication permsissions?

Is it possible to call non-Snap application dbus methods from Snaps?

For example, I want to access com.redhat.tuned provided by the tuned native Ubuntu package.

I added the following to my snapcraft.yaml file:

apps:
  tuned-switcher:
    ...
    plugs:
      ...
      - tuned-dbus

plugs:
  tuned-dbus:
    interface: dbus
    bus: system
    name: com.redhat.tuned

But AppArmor blocks access:

= AppArmor =
Time: Jul 24 17:51:18
Log: apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/Tuned" interface="com.redhat.tuned.control" member="profiles" mask="send" name="com.redhat.tuned" pid=13010 label="snap.tuned-switcher.tuned-switcher" peer_pid=7524 peer_label="unconfined"
DBus access

did you connect the plug after you installed the snap? This is required for dbus plugs because policy dictates they not be connected by default. You can request an automatic connection when your snap is delivered through the store by posting a request in the store-requests category on this forum.

ubuntu@ubuntu:~$ sudo snap connect tuned-switcher:systemd-dbus
error: snap "snapd" has no "dbus" interface slots
ubuntu@ubuntu:~$ sudo snap connect tuned-switcher:tuned-dbus
error: snap "snapd" has no "dbus" interface slots

snapcraft.yaml source

Sorry for replying to this so much later… Did you find a solution to this eventually?

I’m in the same boat, simply cannot find the way to connect (manually, or otherwise) my snap to the DBus in order for it to manage the systray. Been at this for days and can’t find any hints even.