System keychain from daemon access requires root?

I have a macOS daemon that needs to store a password. If I run the daemon as root, I can store and retrieve the password in the system keychain, but if I create a dedicated user/group for the daemon (so it runs as user _myDaemon for example), adding the password to the keychain fails with -61 (errSecWrPerm).

My daemon will be responding to network requests so I would prefer it to not run as root for security reasons. I'm not sure what is the best way to proceed:
  • Is there a way to grant system keychain access for a dedicated daemon user?

  • Should I split off the keychain access into a "helper daemon" that runs as root?

  • Something else?

Accepted Reply

There are a few ways to handle per-daemon credentials, one is:
  • Make a directory dedicated to your service (e.g. /var/<name>) with 0700 permissions

  • Put a new keychain and text file containing its password in the directory

  • At launch, your daemon unlocks the keychain using the file, and sets any settings (e.g. disable lock on sleep, etc)

  • Continue to use ACLs on keychain items so only your daemon process has access

Another thing I've done with various unprivileged services is to have a special "root" mode where the process checks the euid at launch, and if running as root it performs setup actions (like creating the directory and contents) and/or fixups (fixing permissions, checking for other issues, etc), then immediately exit (refuse to run as root). It's easy to run from a PKG's postinstall script, keeps the configuration information out of other files like scripts, and could do the kind of maintenance that daemons sometimes require. It should ignore command-line arguments in that mode for safety's sake though.

Replies

There are a few ways to handle per-daemon credentials, one is:
  • Make a directory dedicated to your service (e.g. /var/<name>) with 0700 permissions

  • Put a new keychain and text file containing its password in the directory

  • At launch, your daemon unlocks the keychain using the file, and sets any settings (e.g. disable lock on sleep, etc)

  • Continue to use ACLs on keychain items so only your daemon process has access

Another thing I've done with various unprivileged services is to have a special "root" mode where the process checks the euid at launch, and if running as root it performs setup actions (like creating the directory and contents) and/or fixups (fixing permissions, checking for other issues, etc), then immediately exit (refuse to run as root). It's easy to run from a PKG's postinstall script, keeps the configuration information out of other files like scripts, and could do the kind of maintenance that daemons sometimes require. It should ignore command-line arguments in that mode for safety's sake though.
Using a file with 0700 permissions seems like the best I can do then. Thanks! That fits more easily into my existing design than adding a special install mode to the daemon.