Skip to content

Instantly share code, notes, and snippets.

@vancluever
Last active November 6, 2024 09:02
Show Gist options
  • Save vancluever/de1c3985c8f9e2a3c4bdc42a057e075e to your computer and use it in GitHub Desktop.
Save vancluever/de1c3985c8f9e2a3c4bdc42a057e075e to your computer and use it in GitHub Desktop.
Run SSH Agent w/Modified Options (MacOS Big Sur, No Homebrew, No SIP Modification)

Run SSH Agent w/Modified Options (MacOS Big Sur, No Homebrew, No SIP Modification)

The following will show you how you can modify the startup options of the SSH agent supplied by MacOS in a non-invasive way. This can be useful for doing things like setting a key lifetime, which can then be used with AddKeysToAgent in your ~/.ssh/config to automate the timing out of saved keys. This ensures that your passphrase is re-asked for periodically without having to shutdown, re-log, or having it actually persisted in keychain, the latter being almost as bad as having no passphrase at all, given that simply being logged in is generally enough to then use the key.

This method does not modify the system-installed SSH agent service (com.openssh.ssh-agent), but rather duplicates its functionality into a user-installed launch agent where we can then modify the options. Modifying the system-installed service is becoming increasingly harder to do; SIP generally protects the files you need to modify, in addition to certain system volumes being mounted read-only now. This is generally a good thing for application and system security and should not be messed with if you don't have to. Additionally, the Homebrew openssh package has issues in that you possibly lose out in the modifications that Apple has made to allow the SSH agent to work seamlessly with socket activation - YMMV, but I have had issues getting it to work as it seems to expect to have access to create the socket, causing conflicts when attempting to start the agent.

The Steps

Copying the plist

mkdir ~/Library/LaunchAgents
cp /System/Library/LaunchAgents/com.openssh.ssh-agent.plist ~/Library/LaunchAgents/com.openssh.ssh-agent-local.plist

After you do this, open the file with your favorite text editor of choice and replace:

  • com.openssh.ssh-agent with com.openssh.ssh-agent-local
  • SSH_AUTH_SOCK with SSH_AUTH_SOCK_LOCAL

Then, add in some options you want for the local agent (as additional string tags in the ProgramArguments array). A good example is -t 14400 to time out loaded keys after 4 hours.

Here's a copy of the modified plist file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>com.openssh.ssh-agent-local</string>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/bin/ssh-agent</string>
		<string>-l</string>
		<string>-t</string>
		<string>14400</string>
	</array>
	<key>Sockets</key>
	<dict>
		<key>Listeners</key>
		<dict>
			<key>SecureSocketWithKey</key>
			<string>SSH_AUTH_SOCK_LOCAL</string>
		</dict>
	</dict>
	<key>EnableTransactions</key>
	<true/>
</dict>
</plist>

Shell Modifications

Next, add this to your shell profie (ie: .zprofile or .bash_profile):

if [ -n "${SSH_AUTH_SOCK_LOCAL}" ]; then
  export SSH_AUTH_SOCK="${SSH_AUTH_SOCK_LOCAL}"
fi

Finishing/Testing

Note

Make sure you have updated your SSH config before you do this by adding AddKeysToAgent yes to your ~/.ssh/config.

Finally, log out and back in (or reboot). launchd will load the service automatically - no need to use launchctl load, etc.

To test, simply run ssh-add -l. This will activate your locally registered com.openssh.ssh-agent-local without activating the system one as your shell will have detected and copied the socket listner location from SSH_AUTH_SOCK_LOCAL to SSH_AUTH_SOCK.

You can verify this by running ps aux | grep ssh-agent. The only running instance you should see is /usr/bin/ssh-agent -l -t 14400. Additionally, launchctl list | grep ssh-agent should show a PID for com.openssh.ssh-agent-local and not com.openssh.ssh-agent:

$ launchctl list | grep ssh-agent
-	0	com.openssh.ssh-agent
12345	0	com.openssh.ssh-agent-local
@begin29
Copy link

begin29 commented Aug 13, 2021

got hang of ssh-agent when try to use OpenSSH one installed via brew

@lutorm
Copy link

lutorm commented Jan 14, 2024

By far the easiest method I found, and worked like a charm.

@LukeCarrier
Copy link

This does not solve the problem for graphical applications unless they parse your shell configuration and read exported environment variables from there.

What we really need is a means of extending or replacing system-installed launch agents on a per-user basis.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment