macOS app-specific container: documented initial creation behavior and storage restrictions

I am considering a dedicated macOS .app and am looking for public Apple documentation about the initial creation of its app-specific container by the operating system.

The priority is to protect existing application data and settings. Running the proposed app and allowing application-managed storage remain on hold.

This question concerns an individual app’s container, rather than an App Group shared container. The target macOS version, bundle identifier, signing configuration, and entitlements are not specified here. Please identify any conditions on which an answer depends.

My primary question is:

Is there public Apple documentation that identifies what the OS creates during initial container creation, which items are mandatory or conditional, and what triggers their creation? Where documented, I would like to understand their locations, contents, size bounds, and lifetime.

For a later assessment, I also need to understand:

  • How the container and its initial contents are associated with a particular .app, including any relevant signing or identity requirements.
  • Whether a public, supported mechanism can permit OS-managed initial container creation while separately preventing subsequent application-managed writes inside that container.

Please distinguish OS-managed initial creation from writes performed by application code or frameworks used by the application. Please also identify whether the behavior depends on App Sandbox, entitlements, or the macOS version.

Links to documentation describing the supported guarantees and their limits would be especially helpful. If some details are implementation-dependent or undocumented, please distinguish those from documented guarantees.

Thank you.

Answered by DTS Engineer in 910393022

The exact mechanism used by macOS to associate an app with its container is considered an implementation detail [1]. It has changed in the past and I wouldn’t be surprised if it changed again in the future.

Beyond that, it’s hard to offer advice without knowing more about what you’re trying to do.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Such implementation details are sometimes documented in Apple Platform Security. I took a quick look and didn’t find anything, but you might have more luck than I did.

The exact mechanism used by macOS to associate an app with its container is considered an implementation detail [1]. It has changed in the past and I wouldn’t be surprised if it changed again in the future.

Beyond that, it’s hard to offer advice without knowing more about what you’re trying to do.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Such implementation details are sometimes documented in Apple Platform Security. I took a quick look and didn’t find anything, but you might have more luck than I did.

Thank you, Quinn. I understand that the exact mechanism associating an app with its container is an implementation detail and may change.

To clarify my purpose: I am considering a dedicated macOS .app, with protecting existing application data and settings as the priority. Before allowing the proposed app to run or perform application-managed storage, I need to assess whether OS-managed initial container creation can be treated as a narrowly bounded exception to a restriction on writes. Running the app and allowing application-managed storage remain on hold.

The distinction I need to establish is between items created by macOS during initial container creation and subsequent writes by the app or frameworks it uses.

Could you clarify the following, or point me to public documentation?

  1. What guarantees, if any, are documented about initial container creation: its triggers, mandatory or conditional items, locations, contents, size bounds, and lifetime? Which of these are implementation details?
  2. Beyond the exact association mechanism, are any supported guarantees documented about how an app’s identity or signing determines which container it can access?
  3. Is there a public, supported way to permit OS-managed initial container creation while preventing subsequent writes by the app and its frameworks within that container?

I have not specified the target macOS version, bundle identifier, signing configuration, or entitlements in this thread. Please let me know which details are needed, including whether App Sandbox configuration affects the answer.

If public guarantees are insufficient to establish this boundary, clarification of that limitation would also be helpful.

Thank you.

AFAIK there’s no documentation at the level of detail you’re asking about, so about the only thing that you can be certain of is that:

  • When you launch a sandboxed app, its app container will be set up before any of the app’s code runs.
  • When you relaunch a correctly signed [1] sandboxed app, it will be able to access the contents of its app container.

The same logic also applies to app group containers.

Modern versions of macOS work to ensure that containers are only accessible to the corresponding app. Again, the exact mechanism used for this isn’t documented, but the developer impact is covered by a couple of WWDC videos. See the app container protection and app group container protection links in Trusted Execution Resources.

while separately preventing subsequent application-managed writes inside that container

There’s no support for anything like that. You might be able to construct something using an es_new_descendants_client ES client, but it’s likely to be brittle. This is a common concern with ES clients, a topic I cover in Inferring High-Level Semantics from Low-Level Operations.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] This is complicated by distribution channels, that is Development, Mac App Store distribution, and direct distribution with Developer ID signing. Historically we’ve gone out of our way to ensure that it’s possible to distribute an app on the App Store and the same app directly using Developer ID signing and have both apps share a single app container without any weird conflicts. I don’t expect that to change.

The desire to support this constrains the mechanism used to associate an app with its container, because we have to decide what “same app” means. In general, apps are identified by their bundle ID. App Store apps must have a registered App ID, of which the bundle ID is part, and thus this is managed by Apple. Things get complicated for directly distributed apps, and we usually handle that by checking both the Team ID and the bundle ID.

For more information about each of these identifiers, see Code Signing Identifiers Explained.

For info on the underlying mechanism for a lot of these checks, see TN3127 Inside Code Signing: Requirements.