Securely passing credentials from Installer plug-in to newly installed agent — how to authenticate the caller?

I’m using a custom Installer plug-in (InstallerPane) to collect sensitive user input (username/password) during install. After the payload is laid down, I need to send those values to a newly installed agent (LaunchAgent) to persist them.

What I tried

I expose an XPC Mach service from the agent and have the plug-in call it.

On the agent side I validate the XPC client using the audit token → SecCodeCopyGuestWithAttributes → SecCodeCheckValidity.

However, the client process is InstallerRemotePluginService-* (Apple’s view service that hosts all plug-ins), so the signature I see is Apple’s, not mine. I can’t distinguish which plug-in made the call.

Any suggestion on better approach ?

I can’t distinguish which plug-in made the call.

Correct. Installer plug-ins are old school in-process plug-ins, where the code gets loaded by the host process. Apple platforms establish security boundaries at the process level. Those two facts make it impossible to determine the identity of the caller.

I’m not super familiar with installer plug-ins, so I’m gonna ask what might seem like an obvious question: Is your plug-in able to spawn a child process? If so, you could bundle a separate program within your plug-in, have the plug-in spawn it, and then have that process do the XPC.

Share and Enjoy

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

I was wondering — if I include the child process in my installer plugin, wouldn’t that allow an attacker to extract the executable using pkgutil and then run the child process manually with their own parameters?

Are you referring to using a root process, such as an SMJobBless Helper? If so, spawning it from the installer would also require root privileges, which isn’t ideal since I’d prefer not to prompt for elevated permissions twice — once during installation and again when launching the process.

then run the child process manually with their own parameters?

Yep. You might be able to prevent that using launch constraints.

Share and Enjoy

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

In this case, the parent process would be the installer, since the plugin runs under the host.

While this setup would prevent the process from being launched by any other source, an attacker could still create a malicious installer, embed my program within their plugin, and successfully carry out the attack — correct ?

Securely passing credentials from Installer plug-in to newly installed agent — how to authenticate the caller?
 
 
Q