Trust, Identity and AppContainer for Windows Apps

Following my previous post where I explored different packaging options for Win32 and UWP apps, I realised that there are some options I didn’t mention. In this post I’m going to provide a very quick summary of the options I’ve come across and how they define the running context of an app. Here goes….

Vanilla Win32

For example WinForms or WPF application where a user can launch the application by double-clicking the executable

Integrity Level: Medium
AppContainer: No
Has Identity: No

Vanilla Win32 (Run as Admin)

Right-click on the WinForms or WPF application and select Run as Administrator

Integrity Level: High
AppContainer: No
Has Identity: No

Win32 Packaged Full-Trust

Uses the Windows Application Packaging project with default Trust Level set to Full Trust

Integrity Level: Medium
AppContainer: No
Has Identity: Yes
Other: Whilst the trust level is supposedly full trust, there is in fact a proxy layer in place for the Registry and parts of the file system (useful reference)

Win32 Packaged Partial-Trust

Set the Trust Level in the Windows Application Packaging project to Partial Trust

Integrity Level: Low
AppContainer: Yes
Has Identity: Yes

Win32 with Sparse Package

Unpackaged Win32 application with package that has allowExternalContent set to true in the package manifest (referred to as a Sparse Package). Application needs to register the Sparse Package on first run (and subsequently unregister as part of clean up).

Integrity Level: Medium
AppContainer: No
Has Identity: Yes
Other: Unlike a packaged Win32 app, in this case the app is not subject to filesystem + registry virtualization, lifetime management by the system and other runtime attributes of fully packaged applications

More information can be found in the docs and in this blog post

Vanilla UWP

This is just an app built from one of the Universal Windows templates in Visual Studio.

Integrity Level: Low
AppContainer: Yes
Has Identity: Yes

UWP with Full Trust Capability

Add the runFullTrust capability in the package.manifest

Integrity Level: Low
AppContainer: Yes
Has Identity: Yes

Note: Essentially adding the runFullTrust capability doesn’t affect the UWP application, other than requesting an additional capability when the user goes to install the application. Do not include this capability unless you are packaging a Win32 app/extension that needs to run outside the appcontainer.

UWP with Full Trust Capability and Win32 App/Extension

In addition to the runFullTrust capability being added to the package.manifest file, a Win32 app or extension has been packaged alongside the UWP application.

Integrity Level (UWP App): Low
AppContainer (UWP App): Yes
Has Identity (UWP App): Yes

Integrity Level (Win32): Medium
AppContainer (Win32): No
Has Identity (Win32): Yes
Other: As with Win32 Packaged Full-Trust, the Win32 app/extension is subject to filesystem and registry virtualization.

Stefan Wick has a number of great posts covering this topic and are a must read if you’re going down this path of extending your UWP application with a Win32 component.

Summary

As you can see there are a large number of options when it comes to building for Windows. With projects like WinUI and Project Reunion this landscape will get easier to navigate.

3 thoughts on “Trust, Identity and AppContainer for Windows Apps”

  1. >Win32 with Sparse Package – Unpackaged Win32 application with package that has allowExternalContent set to true in the package manifest

    This is incorrect, conflating 2 separate features — RuntimeBehavior=win32App and ExternalLocation.

    Any MSIX package can be installed with an ExternalLocation. That just tells Windows this package’s CONTENT files can be found at this other path (the package’s FOOTPRINT files are expected at the usual package location e.g. %ProgramFiles%\WindowsApps\…pkgfullname…).

    An MSIX package’s FOOTPRINT files are the well-defined MSIX metadata files — appxmanifest.xml, appxblockmap.xml, signature.p7x, etc.

    An MSIX package’s CONTENT files are everything else — *.exe, *.png, data files, etc.

    A totally separate matter is how what sort of process is created at activation, most readily distinguish via uap10:RuntimeBehavior = windowsApp (aka UWP app), packagedClassicApp (aka Desktop Bridge) or win32 app.

    A packaged process’ runtime behavior and whether it has an External Location are entirely independent and can be mixed and matched in any permutation you desire.

    You can find more info at
    * https://github.com/microsoft/WindowsAppSDK/discussions/2195
    * https://github.com/microsoft/WindowsAppSDK/discussions/410 (especially https://github.com/microsoft/WindowsAppSDK/discussions/410#discussioncomment-368163)
    * https://learn.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-application

    Reply
  2. P.S. That blog post you link to incorrectly conflates ExternalLocation and RB=win32app. I’ve filed a bug to improve docs.

    P.P.S. A “Sparse Package” isn’t anything special. What matters is “Does a package have an External Location or not”. You could make an MSIX package containing a zillion content files, but if the package has an ExternalLocation none of those content files will be used in the package’s installed location (e.g. %ProgramFiles%\WindowsApps\pkgfullname). Thus if you intend a package to be installed with an ExternalLocation there’s no point putting your content files into the .msix, and thus you may as well avoid the wasted disk space and only include footprint files in the .msix. And thus, your .msix is a ‘sparse’ package. As in, it only contains a fraction of the package’s files (footprint yes, content no).

    A package without content files isn’t all that new or magical. It’s always been possible. It’s just not very interesting to have a package of only footprint files…until External Location came along.

    External Location is the key. The package being ‘sparse’ is a minor secondary detail.

    Reply

Leave a comment