Mac Catalyst Keychain Access Fails with “MissingEntitlement” Error (Works Fine on iOS)

Ramji TS 0 Reputation points
2025-10-07T16:21:07.58+00:00

I’m currently developing a .NET MAUI app targeting Mac Catalyst (.NET 9.0), and I’m encountering a persistent issue with Keychain access / secure storage on macOS. The same code works perfectly on iOS, but on Mac Catalyst, the app fails when trying to access secure storage during OTP verification.
Tested both automatic and manual provisioning — both result in the same MissingEntitlement error when attempting to access secure storage.

Error Message: "An error occurred during OTP verification: Error adding record: MissingEntitlement"

Environment :

  • Platform: Mac Catalyst (.NET 9.0)
  • Development: Using .NET MAUI

What I've Tried : Added the following to my Entitlements.plist:

<key>keychain-access-groups</key>
<array>
    <string>$(AppIdentifierPrefix)com.example.myapp</string>
</array>

Project Signing Setup (.csproj)

<PropertyGroup Condition="'$(TargetFramework)'=='net9.0-maccatalyst'">
    <EnableCodeSigning>true</EnableCodeSigning>
    <ProvisioningType>manual</ProvisioningType>
    <DevelopmentTeam>TEAM_ID</DevelopmentTeam>
    <CodesignKey>Apple Development: Name (XXXXXXXXXX)</CodesignKey>
    <ProvisioningProfile>PROVISIONING_PROFILE_UUID</ProvisioningProfile>
    <CodesignEntitlements>Platforms/MacCatalyst/Entitlements.plist</CodesignEntitlements>
</PropertyGroup>

Has anyone encountered a similar issue when using Keychain or secure storage APIs with .NET MAUI Mac Catalyst apps?

  • Are there specific entitlements or signing configurations required for Catalyst beyond the usual iOS setup?
  • Does the Mac Catalyst sandbox handle keychain groups differently?

Any insights, sample setups, or references would be greatly appreciated!

Developer technologies | .NET | .NET MAUI
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Tony Dinh (WICLOUD CORPORATION) 4,400 Reputation points Microsoft External Staff
    2025-10-08T04:07:46.51+00:00

    Hello !

    This is a common issue in .NET MAUI development targeting Mac Catalyst. Mac Catalyst requires additional considerations for entitlements and signing because it's essentially an iOS app running in a macOS environment with stricter sandbox (App Sandbox) enforcement. Refer: https://learn.microsoft.com/en-us/dotnet/maui/mac-catalyst/entitlements?view=net-maui-9.0

    Mac Catalyst apps run in a sandboxed macOS environment by default for security (similar to App Store requirements), whereas iOS apps can access Keychain without explicit sandboxing in many cases. Catalyst—the sandbox restricts Keychain to apps with proper entitlements and signing.


    Your current file only includes keychain-access-groups. but for secure storage to work on Mac Catalyst, you must enable the App Sandbox entitlement. This is often the missing piece that triggers the MissingEntitlement error resolution but introduces the launch failure if not configured fully. You can try update your Entitlements.plist as follows:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <!--This is **required** for Keychain/secure storage on Mac Catalyst-->
        <key>com.apple.security.app-sandbox</key>
        <true/>
     
        <!--if your app makes any network requests (e.g., during OTP verification); otherwise, the sandbox may block them and cause launch failures.-->
        <key>com.apple.security.network.client</key>
        <true/>
     
        <key>keychain-access-groups</key>
        <array>
            <!--Avoid using `$(AppIdentifierPrefix)`, you need to hardcode your actual Team ID (found in your Apple Developer Account under Membership) followed by your bundle ID (e.g., TEAMID.com.example.myapp). This will prevents expansion issues during signing. The provisioning profile must include "Keychain Sharing" capability to match this.-->
            <string>TEAMID.com.example.myapp</string>
        </array>
    </dict>
    </plist>
    

    Provisioning Profile and Capability Check (The Most Critical Step)

    The entitlement must be enabled in your Apple Developer Account for the App ID and included in the Provisioning Profile.

    • Apple Developer Portal:
      • Log into your Apple Developer account.
      • Go to Identifiers and select the App ID used for your Mac Catalyst application.
      • Ensure the Keychain Sharing capability is explicitly checked and enabled for this App ID.
    • Provisioning Profile:
      • Go to Profiles.
      • Find the Mac Development (or Mac App Store) Provisioning Profile you are using.
      • Regenerate this profile after confirming the Keychain Sharing capability is enabled for the associated App ID.
      • Download and Install the new profile.

    Once App Sandbox is enabled, you must declare every capability your app needs (e.g., Camera, Microphone, File Access). Otherwise, the app may fail at launch.

    Always verify that the entitlements are embedded correctly by checking the signed app with:

    codesign -d --entitlements :- MyApp.app
    

    I hope this helps! Let me know if you have any questions!


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.