Auto-login to system account from a Launch Daemon or any other service

Is there an API that would allow me to login user to their system account (knowing their password and username)? I'm currently working on an automated testing solution for software and we're considering this functionality on macOS (it's working on Windows already).

How would that work with FileVault and encrypted volume? Maybe it would be only possible after initial login and unlocking the disk?

I only found something like this https://apple.stackexchange.com/questions/386637/login-user-opposite-to-launchctl-bootout-user-id but it seems it's not possible on macOS. Would love a confirmation still so I can stop researching :)

There’s no specific API to start a GUI login session but it may be possible to achieve your goal by combining stuff in cunning ways. Can you walk me through the steps you’d like to take here? That is, if you had such an API, how would you use it in practice?

How would that work with FileVault and encrypted volume?

It almost certainly wouldn’t. The FileVault unlock UI runs in a pre-boot environment that doesn’t support third-party code [1].

Share and Enjoy

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

[1] Historically it was EFI; nowadays it’s a pre-boot macOS.

Basically we're making a test automation software in which one of the flows allows to auto-login to the system with provided username and password for the system account. After that the flow can start apps, send some commands to them etc. Therefore was wondering if the auto-login step (even after pre-boot login and logout without restarting the system) is even possible.

If this is for a test environment, what’s wrong with this:

  • Don’t enable FileVault

  • Set up auto login in System Preferences > Users & Groups > Login Items > Automatic login

Share and Enjoy

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

This is a last resort solution for us but we're still evaluating other options. Basically each system user may have a different environment setup and we would like to chose to which one to login.

Basically each system user may have a different environment setup and we would like to chose to which one to login.

I suspect it’ll be easier to have a single user and write code to switch that user’s environment. However, I see two other ways you might achieve your goal.


Screen Sharing works in the pre-login environment and you can configure it to support a standard protocol (VNC). You could write a VNC client that logs the user in that way.


You could implement an authorisation plug-in. At boot time the system acquires the system.login.console authorisation right, and it’s the mechanisms array in that right specific that drives the login process:

% security authorizationdb read system.login.console
…
<dict>
    <key>class</key>
    <string>evaluate-mechanisms</string>
    …
    <key>mechanisms</key>
    <array>
        <string>builtin:prelogin</string>
        <string>builtin:policy-banner</string>
        <string>loginwindow:login</string>
        <string>builtin:login-begin</string>
        <string>builtin:reset-password,privileged</string>
        <string>loginwindow:FDESupport,privileged</string>
        <string>builtin:forward-login,privileged</string>
        <string>builtin:auto-login,privileged</string>
        <string>builtin:authenticate,privileged</string>
        <string>PKINITMechanism:auth,privileged</string>
        <string>builtin:login-success</string>
        <string>loginwindow:success</string>
        <string>HomeDirMechanism:login,privileged</string>
        <string>HomeDirMechanism:status</string>
        <string>MCXMechanism:login</string>
        <string>CryptoTokenKit:login</string>
        <string>loginwindow:done</string>
    </array>
    …
</dict>
</plist>
YES (0)

The loginwindow:login mechanism actually displays the UI. You could replace that with your own mechanism that gets the user name and password from somewhere other than the user.

IMPORTANT Writing an authorisation plug-in is really challenging. If you decide to go down this path, ping me via email.

Share and Enjoy

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

Since the authorization plug-in runs in pre-boot stage it won't be able to communicate with my software. Will it be able to make at least an HTTPS call to the backend system? Also is installing of this plug-in and its configuration possible via a regular pkg installer with some script (assuming yes)? Or it requires manual configuration like changing the mechanisms array?

Since the authorization plug-in runs in pre-boot stage it won't be able to communicate with my software.

Authorisation plug-in do not run in the pre-boot environment. By the time your plug-in runs, macOS is already booted and running a wide range of code (most notably, loginwindow; launchd daemons, both Apple and third-party; and your auth plug-in). The standard model here is to install a launchd daemon and have your auth plug-in talk to it via XPC.

The pre-boot environment only matters if you have FileVault enabled. The authorisation UI shown by FileVault is run by the pre-boot environment and will not run authorisation plug-ins.

Will it be able to make at least an HTTPS call to the backend system?

Issuing an HTTPS request from the auth plug-in should work in this context [1].

Also is installing of this plug-in and its configuration possible via a regular pkg installer with some script … ?

Installing the plug-in using an installer package should be fine.

Or it requires manual configuration like changing the mechanisms array?

You can modify the authorisation database using the security tool or the authorisation database API (AuthorizationRightGet and AuthorizationRightSet).

Share and Enjoy

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

[1] Doing it in the screen saver context (system.login.screensaver) is another matter (r. 59800722).

Auto-login to system account from a Launch Daemon or any other service
 
 
Q