This article was originally authored and posted by Ross Matsuda at sudoade.com.
One major limitation of leveraging scripts that include embedded passwords is the inherent security risk of sending sensitive credentials to your Macs in plaintext. These passwords may end up in logs on your devices, where they could be discovered and compromised. One great solution to this is leveraging a secrets manager like Hashicorp’s Vault. This is a mature, customizable solution.
If you’re not in a position to invest the time and energy required to spin up a Vault server (or pay to subscribe to Vault’s own hosting), there happens to be another solution to this issue that leverages Addigy’s existing infrastructure.
1 – Meet data_key_client
Addigy’s data_key_client binary is responsible for secure communications to devices and was originally designed to facilitate macOS user creation and management. Specifically, it is leveraged by Addigy to securely send strings (passwords) to Macs in a secure fashion. With a little work, admins can actually leverage this tool to store and recall strings to their Macs.
2 – Some disclaimers
This workflow is not officially supported by Addigy. There’s no guarantee that it will continue to function into the future as Addigy continues to iterate on their offerings and change how their binaries work.It appears that strings stored in data_key_client are instance-specific. This is great, as it means that if a bad actor got ahold of the raw code used in one of your scripts, unless the Mac they’re running the code on is enrolled in your Addigy instance, data_key_client will fail to retrieve the secure string.
As of this time, there’s no way to manage these secure strings – this means that if you need to change or rotate a secure string, you’ll need to store a new one, then track down all instances of the old one in your scripts and replace it.
One key requirement for the workflow as we’ve experimented with it – you’ll need access to a Mac or virtual machine running macOS 10.14 or earlier that is not yet FileVault encrypted.
3 – How to store a value
Let’s take a look at how this functions by storing a user password we’ll then use in custom software.
- Locate your enrolled Mac or VM running macOS 10.14 or earlier and begin a GoLive session with the device
- Go to the Security tab
- Locate the FileVault encryption section – click the “Enable” button
- Click the radio button for “I know the username and password for the user in this device” and fill out the fields
- Username: NULL
- Password: The string you want to store
- Click Enable
- Wait a moment and you’ll see two Addigy notifications, letting you know the command worked:
- “Enable FileVault command was sent to the device.”
- “Error getting fdesetup output: exit status 11: Authentication error.”
- Click on the Events tab, and look for your most recent failed command. It will look something like this:
/Library/Addigy/filevault-manager -enable -user='NULL' -password=$(/Library/Addigy/data_key_client -fileIdentifier='1289d3d5-da33-47b9-bdc4-d1b458be8612' | tr -d \")
- Inside the above command, copy the contents of the “password” variable. From the above example, it would be:
$(/Library/Addigy/data_key_client -fileIdentifier='1289d3d5-da33-47b9-bdc4-d1b458be8612' | tr -d \")
- This should be your encrypted password. You can verify it by going into Terminal and echoing the value:
echo $(/Library/Addigy/data_key_client -fileIdentifier='1289d3d5-da33-47b9-bdc4-d1b458be8612' | tr -d \")
Your output should be your stored password
4 – Recalling a value
You can now use this command to output the password you defined. All of your logs in Addigy that document the code being executed by a script or custom software will only show the above variable, not the results of running it. In practice, it could look something like this, where we test the accuracy of a password for a target account:
targetAccount="johndoe" targetAccountPW="$(/Library/Addigy/data_key_client -fileIdentifier='1289d3d5-da33-47b9-bdc4-d1b458be8612' | tr -d \")" # Desired password for account # 3 - Password validity outputTest=$(sudo dscl . authonly $targetAccount "$targetAccountPW") if [ "$outputTest" = "" ]; then targetAccountHasWorkingPassword="true" else targetAccountHasWorkingPassword="false" fi
By having access to data_key_client’s ability to store and output strings via this fileIdentifier method, you can now take advantage of many different types of scripts and actions that you couldn’t before, knowing that your passwords are not being transmitted in plaintext. We’ve used this extensively for managing FileVault and SecureToken, for rotating the passwords on deployed user accounts, or even authenticating Apple Silicon macOS upgrades. It’s not as powerful as a proper secrets manager, but it’s a part of the product today and you can use it immediately.