Classic confinement request for msg-we-ua

Hello Snapcraft reviewers and Linux community,

Thank you for taking the time to review this request. We greatly respect the work of the Snapcraft, snapd and Linux communities and appreciate everyone who helps make Linux systems more capable, secure and accessible.

  • name: msg-we-ua

  • description: MSG.WE.UA is a proprietary Flutter Linux desktop messenger by WE.UA. It embeds WebKitGTK 4.1 and provides encrypted messaging, file transfers, WebRTC audio/video calls, camera and microphone access, and OAuth/deep-link integration.

  • snapcraft: PRIVATE

  • upstream: PRIVATE

  • upstream-relation: Original developer and publisher of the WE.UA platform.

  • supported-category: none of the listed categories exactly match this use case; requesting review under the criterion that the snap requires access to resources and integration points not currently supported by snapd under strict confinement

  • reasoning: WebRTC audio and video calls are a mandatory part of MSG.WE.UA.

    The WebKitGTK runtime shipped by the target Ubuntu distribution does not provide a functional WebRTC implementation for this application. In our tested environment, the stock runtime did not expose a usable RTCPeerConnection/WebRTC pipeline.

    The application therefore requires a custom WebKitGTK 2.52.3 build compiled with:

    ENABLE_WEB_RTC=1 USE_GSTREAMER_WEBRTC=1

    The snap ships this custom WebKitGTK runtime together with the matching JavaScriptCore libraries and GStreamer RTP/WebRTC components. This is not a runtime preference or an optional feature: without this exact WebKitGTK backend, the application’s mandatory audio/video calling functionality is not available.

    The custom WebKitGTK WebProcess and NetworkProcess must operate together with the user’s PipeWire/V4L2/ALSA media stack and GStreamer/libnice ICE transport. With strict confinement and the available interfaces, the same WebKitGTK multi-process media path did not provide a functional release: the WebKit runtime/media subprocesses and desktop portal operations were blocked or failed, and WebRTC calls could not reliably establish or maintain media transport.

    This request is therefore for the required WebKitGTK/WebRTC runtime integration, not for arbitrary filesystem access, root privileges, host browser discovery, or Chromium sandbox bypassing.

    The application runs as a regular desktop user and has no privileged daemon. Its declared interfaces are limited to desktop, network, audio, camera, graphics, theme, and session integration.

    We did consider using Chromium or a Chromium-based embedding solution. However, this Flutter project already shares one native WebView and bridge architecture across Android, iOS, macOS and Windows. A Chromium/CEF-based Linux implementation would require a separate Linux-specific backend and a substantial rewrite of the platform integration, including permissions, WebRTC media handling, OAuth callbacks, external links, downloads, persistent storage and window lifecycle management. This would make the project significantly harder to maintain and support consistently over time.

    For this reason, the Linux release uses WebKitGTK, with a custom WebKitGTK build that provides the WebRTC functionality required by the application.

I understand that strict confinement is generally preferred over classic.

I’ve tried the existing interfaces to make the snap to work under strict confinement.

This request has been added to the queue for review by the @reviewers team.

1 Like

This is a hard requirement to get even considered for classic confinement, please note that the optional manual override from an architect requires a significant reason to be considered at all … given that there are already a ton of strictly confined messengers and video call apps in the store already I highly doubt this justifies for an architect override.

Please see:

… especially the paragraph about Caveats at the bottom, packaging classic snaps is significantly harder due to the fact that you will have to binary patch all libs and apps inside your snap to make sure to keep the runtime environment of your snap 100% distinct from the hosts env and vice versa … you will have to make sure that all rpath calls are patched out of the binaries as well as making sure that nothing inside your snap accidentally uses the hosts linker …

Can you show us the denials you got when packaging it as a strict snap and running the snappy-debug tool alongside your app, for all described bits in your “reasoning” paragraph there are existing interfaces you can use in strict confinement (others do this as well already) and nothing stops you from shipping your own build of webkit either in strict mode.

1 Like

Thank you for the guidance. We repeated the test using the official snappy-debug tool while launching a strict-confinement build with the camera and audio-record plugs connected.

The report shows:

  • a denied D-Bus call to org.freedesktop.host.portal.Registry.Register;
  • a denied read of /etc/glvnd/egl_vendor.d/;
  • the application exits with code 134 before the WebView is loaded.

We also tested the suggested snap-local GLVND paths. This removed the egl_vendor.d denial, but the D-Bus portal denial remained and the application still terminated during GTK initialization before WebKitGTK/WebRTC startup.

We understand that packaging complexity alone is not sufficient justification for classic confinement. Could you advise which existing interface or supported portal integration is expected to grant org.freedesktop.host.portal.Registry.Register to a GTK/WebKitGTK desktop application under strict confinement? We will use that guidance for the next strict-mode test.

The complete reproducible output is:

STRICT_CONFINEMENT_TEST

MSG.WE.UA — strict confinement test evidence

Test date: 2026-08-19 Host: Ubuntu amd64, snapd/AppArmor enabled, Wayland/X11 session Application payload: the same payload as msg-we-ua_1.0.0_amd64_release-v2.snap Release Snap SHA-256: 614694a9229d772af0365ce752e17d22affb0182bff6206c65fe49c238ba7750 Strict test Snap SHA-256 (temporary local artifact, not committed): 20aa0736f5f8d92f632cac75e7f0acf7f4112ad107fd79b342812d8e1aac77c8

Purpose

To verify whether the current Flutter + GTK/WebKitGTK runtime can operate under strict confinement. This is a runtime test, not a linter result.

Method

  1. The release Snap was unpacked without changing its application payload.
  2. Only the test metadata was changed: confinement: classic → confinement: strict snap name: msg-we-ua → msg-we-ua-strict-test The production D-Bus name remained unchanged: ua.we.msg_we_ua No browser-support plug or allow-sandbox attribute was added.
  3. The test Snap was installed locally with --dangerous. snap list showed no classic/devmode note, and AppArmor loaded the profile in enforce mode: snap.msg-we-ua-strict-test.msg-we-ua
  4. The camera and audio-record plugs were manually connected before launch.
  5. The app was launched directly in the graphical user session: snap run msg-we-ua-strict-test.msg-we-ua The launch was also repeated with LIBGL_ALWAYS_SOFTWARE=1 and GDK_BACKEND=x11. The result was unchanged.

Observed launch output

ERROR: ld.so: object ‘/usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0’ from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored. Gtk-Message: Failed to load module “canberra-gtk-module” WARNING: Unable to set application icon: Couldn’t recognize the image file format for file “/snap/msg-we-ua-strict-test/x2/data/flutter_assets/assets/images/msg.we.ua.png” No provider of eglGetPlatformDisplayEXT found. Requires one of: EGL_EXT_platform_base Aborted (core dumped) exit=134

Relevant AppArmor/journal records

apparmor=“DENIED” operation=“dbus_method_call” bus=“session” path=“/org/freedesktop/portal/desktop” interface=“org.freedesktop.host.portal.Registry” member=“Register” name=“org.freedesktop.portal.Desktop” profile=“snap.msg-we-ua-strict-test.msg-we-ua”

apparmor=“DENIED” operation=“open” class=“file” profile=“snap.msg-we-ua-strict-test.msg-we-ua” name=“/etc/glvnd/egl_vendor.d/” requested_mask=“r”

The same denials were recorded after the camera and audio-record plugs were connected, and after the software-GL fallback launch.

snappy-debug report

The official Canonical snappy-debug snap was run as root while the strict test app was launched. The report was captured by piping the journal into the tool (as recommended by the snappy-debug documentation):

sudo journalctl --output=short --follow --all | sudo snappy-debug --only-snap=msg-we-ua-strict-test --only-new

The relevant output was:

= AppArmor = Log: apparmor=“DENIED” operation=“dbus_method_call” bus=“session” path=“/org/freedesktop/portal/desktop” interface=“org.freedesktop.host.portal.Registry” member=“Register” name=“org.freedesktop.portal.Desktop” label=“snap.msg-we-ua-strict-test.msg-we-ua” DBus access

= AppArmor = Log: apparmor=“DENIED” operation=“open” class=“file” profile=“snap.msg-we-ua-strict-test.msg-we-ua” name=“/etc/glvnd/egl_vendor.d/” requested_mask=“r” File: /etc/glvnd/egl_vendor.d/ (read) Suggestions:

  • adjust program to read necessary files from $SNAP, $SNAP_DATA, $SNAP_COMMON, $SNAP_USER_DATA or $SNAP_USER_COMMON
  • adjust snap to use snap layouts
  • add system-files to plugs

This report was produced with the camera and audio-record plugs connected. The process then aborted with exit 134 before loading the WebView.

Follow-up test using the snappy-debug suggestion

To distinguish the graphics-path issue from the D-Bus issue, the strict app was launched again with the GLVND paths redirected into the snap:

__EGL_VENDOR_LIBRARY_DIRS=$SNAP/usr/share/glvnd/egl_vendor.d:$SNAP/etc/glvnd/egl_vendor.d LIBGL_DRIVERS_PATH=$SNAP/usr/lib/x86_64-linux-gnu/dri

This removed the /etc/glvnd/egl_vendor.d/ AppArmor denial, but the org.freedesktop.host.portal.Registry.Register D-Bus denial remained. The application still did not reach the WebView and terminated during GTK initialisation. snappy-debug also reported sched_setaffinity and setpriority seccomp denials; it classified both as ignorable noise when the application otherwise works.

The follow-up snappy-debug output for those seccomp events was:

= Seccomp = Syscall: sched_setaffinity Suggestion: ignore the denial if the program otherwise works correctly

= Seccomp = Syscall: setpriority Suggestion: ignore the denial if the program otherwise works correctly

Conclusion

The current release cannot initialize its GTK/Flutter runtime inside a strict Snap. It fails before the web page is loaded and before WebKit/WebRTC can be used. The test identified two separate strict-mode integration gaps: the graphics runtime needs snap-local GLVND discovery, and the current GTK/portal startup path is denied its D-Bus registration call even with the normal desktop, network, OpenGL, camera and audio interfaces connected. The first gap can likely be addressed with snap-local environment/layout changes; the second still requires a strict-compatible portal/GTK integration change and must be retested before claiming strict support.

This is evidence that the current release is not strict-compatible as shipped, not a claim that every possible strict redesign is impossible.

This evidence should be supplied to the reviewer together with the exact commands and journal records above. It is intentionally limited to the strict-confinement failure and does not claim that classic is required merely because the build is inconvenient to package.

It looks like you simply switched the confinement: entry in your snapcraft.yaml but did not do all the other bits needed for a strict confined snap …

you will need to add some interfaces (or use an extension that automagically brings them along) … I.e. the portal access is usually handled by the desktop interface as you can see here:

(I would have expected snappy-debug to tell you about this, not sure why it did not in your test)

As an initial step I’d suggest to simply use the gnome extension in your snap, that should bring in all required bits you need inside your snap to operate on any desktop with all the expected interfaces, themes, fonts etc

Second I suspect something is missing inside your snap to actually launch WebKit properly, my suspicion would go towards some GL libs, have you tried strict confinement in --devmode ? That will run your snap actually in strict mode but not block any outside access at all (it turns on “complain” mode though which will massively spam your logs), that way you should be able to see if there is actually something missing in the snap or if it is an issue with accessing the outside world …

last but not least, there is the gpu interface and extension you can use to have the latest graphics stack provided to a strict snap, it is documented here:

In case you do not want to go with extensions, here is an example of a WebKit browser that is widely used in embedded computing inside a strict snap:

https://gitlab.com/glancr/wpe-webkit-snap/-/blob/core22/snap/snapcraft.yaml

(though for an actual desktop snap I’d go with the extensions if possible)

1 Like

@ogra Thank you very much for taking the time to review our request and provide such detailed technical guidance.

We will continue working toward a properly strict-confined Snap. We will test the application in devmode, then integrate the appropriate desktop and GPU extensions and review all resulting snappy-debug reports and AppArmor denials.

There are a few platform-specific complications in our case. The application is based on Flutter and embeds WebKitGTK. The stock Ubuntu WebKitGTK build available to us did not expose a working RTCPeerConnection implementation, while audio and video calls are a required feature of MSG.WE.UA. For this reason, we had to build WebKitGTK 2.52.3 ourselves with WebRTC and GStreamer WebRTC support enabled:

ENABLE_WEB_RTC=1
USE_GSTREAMER_WEBRTC=1

The custom build also depends on the Ubuntu 26.04 userspace and glibc 2.43, which is why we currently use the core26 base. This makes switching to the GNOME extension less straightforward, since the currently documented GNOME extension targets core22/core24, while moving to core24 would not provide the required runtime compatibility for our WebKitGTK build.

We understand that classic confinement is an exceptional measure and that strict confinement should be preferred whenever technically possible. Therefore, we will continue with the strict-confinement approach and provide a corrected test package, together with reproducible commands and logs.

If we ultimately cannot achieve equivalent functionality under strict confinement, we will return with concrete evidence: exact interface requirements, snappy-debug output, AppArmor denials, and runtime logs demonstrating which required WebRTC, media, WebKitGTK, or graphics operations cannot function under strict confinement.

Thank you again for your time, patience, and for helping us make the application a better citizen of the Linux desktop ecosystem.

I would expect the gnome core26 extension to only take days (at most some weeks) to actually show up in a stable channel (I think there is already something in the edge channel that is simply not 100% finished yet (and not yet accessible for the general user)) so that should make everything easier for you.

If you have more questions or run into issues I’m usually around, so just keep asking here and I’ll answer what I can or drag others in that know more about a particular topic :slight_smile:

1 Like

Update regarding msg-we-ua:

Following the reviewer’s guidance, we continued with strict confinement and uploaded revision 4 of the snap.

Revision 4:

  • Snap: msg-we-ua
  • Version: 1.0.0
  • Architecture: amd64
  • Base: core26
  • Confinement: strict
  • Uploaded: 2026-08-20 15:51:13 UTC

Revision 4 is currently pending manual review and no revision has been released to any channel yet. I accidentally canceled the manual-review request and submitted it again, so I would appreciate it if the review status could be checked and re-queued if necessary.

At this stage we are not asking for classic confinement unless strict confinement proves technically insufficient after review and testing. Please let me know if this update should be handled elsewhere.

Hi @Miro.Baida,

Unfortunately, I am unable to re-trigger review for revision 4. Please upload a new revision.

dbus access that you have asked for is already granted. If your snap needs access to other interfaces, kindly create a new forum request in the right sub-category. Thanks!