Saving/loading user (login) keychain from a 3rd party authorization plugin on login screen

Our team is working on an Authorization Plugin that presents a UI, so it's being run by the securityagent (_securityagent, UID 92, thus being unprivileged).

Our plugin is injected right before the "loginwindow:done" in system.login.console, so technically after the user successfully authenticated him/herself to the OS we present our UI. Also by this time the "HomeDirMechanism:login,privileged" has run, so the current user's home directory is mounted.

After this we want to save and load items into/from the current user's (login) keychain. We already have a solution, a running daemon which can read/write but only system keychains. We'd prefer (if that is possible of course) to read and write the user's (login) keychains. According to this technote it is possible to change the EUID to the current user's who's logging in with pthread_setugid_np. Even though we tried to change the EUID from our plugin (UID 92) or from our daemon (UID 0) we weren't able to read/write the current user's login keychain.

My question: I guess this is the expected behaviour, but is there any conventional workaround for this to be able to read/write current user's login keychains on the login screen or there's nothing we can do and we should go with using a daemon and reading/writing the system keychain.

note: one idea would be to create a launchAgent running in context of the currenty logging in user and maybe that can read/write the respective login keychain items.

Thanks for the help in advance.

Hey, if you’re going to look at my ancient technotes then you need to look at the most important one: Technote 2083 Daemons and Agents. It describes how, on macOS, a process’s execution context is more than just the traditional Unix-y UID values. This is critical when it comes to dealing with the keychain, because that relies heavily on the security context.

one idea would be to create a [launchd agent] running in context of the currenty logging in user

That’s the best way to run code in the user context. There are two gotchas here:

  • Context — The launchd agent will be running in the user’s context, which is different from the context your auth plug-in is running in.

  • Timing — The launchd agent won’t start running until authorisation is complete.

For writes to the keychain you could solve this problem by using your daemon as a rendezvous point. That won’t help with reads though.

Share and Enjoy

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

Hey Quinn, Thanks for your reply!

Saving/loading user (login) keychain from a 3rd party authorization plugin on login screen
 
 
Q