Writing to /Library/Application Support

I have seen these 2 articles that I have attached below that seem to offer some assistance. But is there a more modern way to share secured information between macOS users on same machine?

Entitlements

File System Protections

STEPS TO REPRODUCE

do
{
let baseDir = try fileMgr.url(for: .applicationSupportDirectory, in: .localDomainMask, appropriateFor: nil, create: true).appendingPathComponent("com.MyCompany.AppName", conformingTo: .directory)

try fileMgr.createDirectory(at: baseDir, withIntermediateDirectories: true, attributes: nil)
}
catch
{
Swift.print("ERROR: can't create baseDir \(baseDir)")
exit(0)
}
Answered by DTS Engineer in 813072022

Sorry that I didn’t reply earlier. For annoying internal reasons, I wasn’t notified of your last post (r. 131905835)-:

You wrote:

the data should remain protected from external modification by users who are not using our application

There isn’t a 100% guaranteed way to do that. What you’re asking for is a DRM system: You want to give the user some data but restrict how they can use it. DRM systems are tricky, because they involve a three-way trade-off between effectiveness, compatibility, and coding effort.

DTS doesn’t support DRM development because of the compatibility concerns. The more effective a DRM system is, the more likely it is to run into compatibility problems.

However, there are reasonably effective approaches that are likely to be highly compatible. I gave an example of that in this post.

So, let’s break this down into two parts:

  • Where do you store the data?

  • How do you protect this data from the user?


There’s a clear answer to the first part: /Library/Application Support/NNN, where NNN is something unique to your company or product name.

There’s only one challenge with doing that, namely, if the first user who runs your app is a non-admin user, you can’t write to that location directly. There are a few ways you could handle that:

  • Tell them “No.” That is, require that they get an admin user to run the app for its initial setup.

  • Implement one of the privilege escalation techniques described in BSD Privilege Escalation on macOS.

  • Let the user run in ‘this user only’ mode and provide a way for an admin user to upgrade to ‘all users’ mode.


As to how you protect this data from the user, that’s the DRM issue I mentioned above and it’s not something I answer definitively. As I said, it’s a complicated trade-off, and you’re the only person with all the info required to make that trade-off. Specifically, you’re the only one who knows how much this data is ‘worth’.

Share and Enjoy

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

Before continuing, read:

But is there a more modern way to share secured information between macOS users on same machine?

That depends on the nature of this information. What sort of information are you trying to share? And who are you trying to secure it from?

Share and Enjoy

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

Thank you for your response.

The data we’re looking to share is application-specific configuration data that all users logged into the computer may need to access and read. The intent is for this data to be available to any user of the application across user sessions on the same device, without requiring duplication per-user. However, the data should remain protected from external modification by users who are not using our application (i.e., it should only be modified by our app).

We understand that LocalDomainMask can be used to create a directory in a location accessible to all users. However, this data is sensitive to the application’s functionality, so we’re looking for a secure and centralized storage location that enforces protections similar to those within a user’s Library directory but accessible by multiple users.

Is there a recommended entitlement or alternative approach for securely sharing such application-specific data between all users of a single computer?

Thank you for any insights into a modern, macOS-supported approach for this use case.

Sorry that I didn’t reply earlier. For annoying internal reasons, I wasn’t notified of your last post (r. 131905835)-:

You wrote:

the data should remain protected from external modification by users who are not using our application

There isn’t a 100% guaranteed way to do that. What you’re asking for is a DRM system: You want to give the user some data but restrict how they can use it. DRM systems are tricky, because they involve a three-way trade-off between effectiveness, compatibility, and coding effort.

DTS doesn’t support DRM development because of the compatibility concerns. The more effective a DRM system is, the more likely it is to run into compatibility problems.

However, there are reasonably effective approaches that are likely to be highly compatible. I gave an example of that in this post.

So, let’s break this down into two parts:

  • Where do you store the data?

  • How do you protect this data from the user?


There’s a clear answer to the first part: /Library/Application Support/NNN, where NNN is something unique to your company or product name.

There’s only one challenge with doing that, namely, if the first user who runs your app is a non-admin user, you can’t write to that location directly. There are a few ways you could handle that:

  • Tell them “No.” That is, require that they get an admin user to run the app for its initial setup.

  • Implement one of the privilege escalation techniques described in BSD Privilege Escalation on macOS.

  • Let the user run in ‘this user only’ mode and provide a way for an admin user to upgrade to ‘all users’ mode.


As to how you protect this data from the user, that’s the DRM issue I mentioned above and it’s not something I answer definitively. As I said, it’s a complicated trade-off, and you’re the only person with all the info required to make that trade-off. Specifically, you’re the only one who knows how much this data is ‘worth’.

Share and Enjoy

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

Thank you, Quinn, for following up on my question.

You asked, "What sort of information are you trying to share?" I provided details on why we need access to a generally accessible location to support our use case.

However, we still don’t have a concrete answer to our initial question about making this code work. While we understand the restrictions surrounding file access privileges, our goal is to implement a reliable solution within the constraints provided.

Here's the code we're currently using:

do {
    let baseDir = try fileMgr.url(for: .applicationSupportDirectory, in: .localDomainMask, appropriateFor: nil, create: true).appendingPathComponent("com.MyCompany.AppName", conformingTo: .directory)
    try fileMgr.createDirectory(at: baseDir, withIntermediateDirectories: true, attributes: nil)
} catch {
    Swift.print("ERROR: can't create baseDir \(baseDir)")
    exit(0)
}


This code returns the error: "You don't have permission."

Could you please clarify what steps we need to take to request or configure the necessary permissions to access this directory? We appreciate your thoughts on security and how to restrict access. The challenges we can deal with in our app. We just need access to that directory.

Thank you for any insights you can provide to help us move forward.

Sorry for another delayed response; yet again I didn’t get notified of your reply. If you reply again, please tag me using the @ syntax. It’ll be interesting to see if I get that.

However, we still don’t have a concrete answer to our initial question about making this code work.

That code is trying to create an item in /Library/Application Support. That directory is only writable by root:

% ls -ld "/Library/Application Support"
drwxr-xr-x  22 root  admin  704 31 Oct 08:16 /Library/Application Support

So, to make that exact code work you’ll need to escalate privileges to root. There are a variety of ways to do that, as I explain in BSD Privilege Escalation on macOS.

The correct approach to choose depends on your overall goals, which is why I’ve been asking questions trying to clarify those goals. For example, if your goal is to hide this state from the user then installing a daemon that writes to this directory would be silly. If you’re gonna have a daemon anyway, you might as well have it manage the state internally, which gives you a lot more scope for hiding it.

Share and Enjoy

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

Writing to /Library/Application Support
 
 
Q