Supported profileless LPAC creation using an unregistered AppContainer SID

Azer 20 Reputation points
2026-10-29T11:36:10.2866667+00:00

Does Windows officially support creating a Less Privileged AppContainer (LPAC) process through CreateProcessW and STARTUPINFOEXW using:

  1. An SID returned by DeriveAppContainerSidFromAppContainerName for an AppContainer name that has never been registered through CreateAppContainerProfile.

PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES, containing the derived SID with no capabilities.

PROC_THREAD_ATTRIBUTE_ALL_APPLICATION_PACKAGES_POLICY, set to PROCESS_CREATION_ALL_APPLICATION_PACKAGES_OPT_OUT.

Microsoft's AppContainer implementation guide describes creating a profile before launching an AppContainer process. However, the SID derivation documentation does not explicitly state whether profile registration is required.

My questions:

Is this derive-only, never-registered SID approach an officially supported Windows API contract, rather than merely undocumented behavior?

Which Windows client and server versions support it?

Are there specific caller privileges, profile registration or storage prerequisites?

Is there authoritative Microsoft documentation confirming this behavior?

I am seeking clarification of the documented API contract, not troubleshooting an application-specific failure.

Thank you for your guidance.Does Windows officially support creating a Less Privileged AppContainer (LPAC) process through CreateProcessW and STARTUPINFOEXW using:

An SID returned by DeriveAppContainerSidFromAppContainerName for an AppContainer name that has never been registered through CreateAppContainerProfile.

PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES, containing the derived SID with no capabilities.

PROC_THREAD_ATTRIBUTE_ALL_APPLICATION_PACKAGES_POLICY, set to PROCESS_CREATION_ALL_APPLICATION_PACKAGES_OPT_OUT.

Microsoft's AppContainer implementation guide describes creating a profile before launching an AppContainer process. However, the SID derivation documentation does not explicitly state whether profile registration is required.

My questions:

Is this derive-only, never-registered SID approach an officially supported Windows API contract, rather than merely undocumented behavior?

Which Windows client and server versions support it?

Are there specific caller privileges, profile registration or storage prerequisites?

Is there authoritative Microsoft documentation confirming this behavior?

I am seeking clarification of the documented API contract, not troubleshooting an application-specific failure.

Thank you for your guidance.

Windows development | Windows API - Win32
0 comments No comments

Answer accepted by question author
Zack Nguyen (WICLOUD CORPORATION) 405 Reputation points Microsoft External Staff Moderator
2026-10-30T07:31:29.1566667+00:00

Hi @Azer ,

Based on the official Microsoft documentation, here's a summary for each of your questions:

1. Is the derive-only, never-registered SID approach officially supported?

This isn't documented as a supported contract. The Launch an AppContainer guide says the profile must be created first. It uses DeriveAppContainerSidFromAppContainerName only when CreateAppContainerProfile returns ERROR_ALREADY_EXISTS, meaning the profile already exists.

The DeriveAppContainerSidFromAppContainerName page describes the function as returning the SID of a profile. It doesn't say the function registers one or that the derived SID can replace profile creation. AppContainer for legacy apps also states that unpackaged apps need an AppContainer definition or profile.

If this approach works on a given build, that is observed behavior, not a documented guarantee.

2. Which Windows versions support it?

The individual APIs are documented for Windows 8 / Windows Server 2012 and later, desktop apps only. See CreateAppContainerProfile and UpdateProcThreadAttribute. No version matrix is documented for this specific profileless LPAC combination.

3. Are there privilege, registration, or storage prerequisites?

For the documented profile-backed path:

  • Profiles are created per user and per app.
  • Creating one for another user requires impersonating that user.
  • CreateAppContainerProfile can return E_ACCESSDENIED if the caller lacks permission.
  • The profile provides per-user folders and registry storage with appropriate ACLs.

No special privilege is documented for creating the current user's profile, and no registration-free or storage-free LPAC mode is documented.

4. Is there authoritative documentation confirming this behavior?

No public Microsoft documentation confirms that a SID derived from a never-registered name can be used as a supported, profileless LPAC identity.

If you need an authoritative statement on this behavior, I recommend opening a support request through Support for Business. If you don't have a business support plan, you can contact Microsoft Support instead.

If you find my response helpful, I would greatly appreciate it if you could follow the guide here so others experiencing similar behavior or issue can benefit from it as well.

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

1 additional answer

Sort by: Most helpful
  1. AI answer

    2026-10-29T11:37:03.1533333+00:00

    The documented contract for an unpackaged LPAC is to create a per-user AppContainer profile first and use its SID; Microsoft’s public Win32 documentation does not establish derive-only use of a never-registered SID as a supported process-creation contract.

    Supported sequence

    1. Call CreateAppContainerProfile for the current user.
    2. If it succeeds, use the returned SID.
    3. If it returns HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), derive the existing profile’s SID with DeriveAppContainerSidFromAppContainerName.
    4. Put that SID in SECURITY_CAPABILITIES.
    5. Add:
      • PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES
      • PROC_THREAD_ATTRIBUTE_ALL_APPLICATION_PACKAGES_POLICY with PROCESS_CREATION_ALL_APPLICATION_PACKAGES_OPT_OUT
    6. Call CreateProcessW with EXTENDED_STARTUPINFO_PRESENT.

    The AppContainer launch guide explicitly says that the profile needs to be created, then presents SID derivation as the path for an existing AppContainer. Its LPAC example adds the all-application-packages opt-out attribute to the normal AppContainer creation attributes.^1^

    A minimal profile/SID decision should therefore follow this pattern:

    PSID packageSid = nullptr;
    
    HRESULT hr = CreateAppContainerProfile(
        name, displayName, description, nullptr, 0, &packageSid);
    
    if (hr == HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) {
        hr = DeriveAppContainerSidFromAppContainerName(name, &packageSid);
    }
    if (FAILED(hr)) {
        return hr;
    }
    
    // Use packageSid in SECURITY_CAPABILITIES.
    // Release it with FreeSid when process creation is complete.
    

    For an LPAC with no capabilities, set CapabilityCount to 0 and Capabilities to nullptr, while retaining the package SID and LPAC policy:

    SECURITY_CAPABILITIES sc{};
    sc.AppContainerSid = packageSid;
    sc.Capabilities = nullptr;
    sc.CapabilityCount = 0;
    
    DWORD policy =
        PROCESS_CREATION_ALL_APPLICATION_PACKAGES_OPT_OUT;
    
    // Add sc and policy to a two-entry attribute list,
    // then call CreateProcessW with EXTENDED_STARTUPINFO_PRESENT.
    

    The attribute values and referenced storage must remain valid until the attribute list is destroyed.^2^

    Status of the derive-only approach

    DeriveAppContainerSidFromAppContainerName is documented as getting “the SID of the specified profile”; its input and output are also described in profile terms. The page does not say that it registers a profile or that a derived SID may replace profile creation for a previously unregistered name.^3^

    More directly, Microsoft’s unpackaged-app documentation states that creating an AppContainer process requires an AppContainer definition or profile. For unpackaged applications, the application must perform the profile-management work that package deployment otherwise performs.^4^

    Consequently:

    • Successful SID derivation does not document profile existence.
    • Successful process creation on a particular Windows build would establish observed behavior only.
    • The public documentation supplied here gives no compatibility guarantee for the combination “never registered SID + security capabilities + LPAC opt-out.”
    • There is therefore no documented client/server version matrix, privilege contract, or storage-free guarantee for that exact combination.

    Versions and prerequisites for the documented path

    The documented building blocks have these minimums:

    • CreateAppContainerProfile: Windows 8 client and Windows Server 2012, desktop apps only.^5^
    • DeriveAppContainerSidFromAppContainerName: Windows 8 client and Windows Server 2012, desktop apps only.^3^
    • PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES: Windows 8 and later, and Windows Server 2012 and later.^2^

    These minima establish ordinary AppContainer profile and security-capabilities availability; they should not be interpreted as an independently documented minimum-version guarantee for the unregistered LPAC combination.

    A profile is per user and per app. CreateAppContainerProfile creates it for the current user. To create it for another user, the caller must impersonate that user, and profile creation must be repeated for each user. The API can return E_ACCESSDENIED when the caller lacks permission.^5^ The profile supplies per-user folders and registry storage with appropriate ACLs; the launch guide also documents the AppContainer-specific LOCALAPPDATA, TEMP, and TMP locations.^1^

    No additional caller privilege for the documented current-user sequence is identified in these pages. Cross-user creation is the documented case requiring impersonation.

    Conclusion

    There is no authoritative Microsoft documentation here confirming profileless LPAC creation from a never-registered, deterministically derived SID. The supported public contract is profile-backed creation; treating the derive-only form as supported across Windows releases would require an additional explicit Microsoft API-contract statement that the current documentation does not provide.


    References

    1. Launch an AppContainer
    2. UpdateProcThreadAttribute function (processthreadsapi.h)
    3. DeriveAppContainerSidFromAppContainerName function (userenv.h)
    4. AppContainer for legacy apps
    5. CreateAppContainerProfile function (userenv.h)
    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.