How to always allow Mac keychain password only by specific app
How to always allow Mac keychain password only by specific app
Background
normally, we use the script below to fetch the password from keychain.
security find-generic-password -a "$account" -s "$service" -w
when we execute the code, Mac ask to input the password and if we don’t want to input the password every time, Mac ask us to allow ‘security’ to get the permission to access the password. but, any script can invoke the ‘security’ to access the password even the hacking script. so, the meaning to grant the permission to ‘security’ is that anyone can access the permission.
for preventing the security issue, we can do the 2 way below
- input the password whenever the password is required.
- allow only the granted app can access the password
this is about the option 2.
Why This Matters
The macOS Keychain is the primary credential storage system on Mac. It stores passwords, API keys, certificates, and other sensitive data. When you grant the security command-line tool “Always Allow” access, you are essentially opening that password to any process running on your Mac, because any script or program can invoke security find-generic-password.
This is a significant security risk, especially if you store:
- API keys for cloud services (AWS, GCP, etc.)
- Database credentials
- SSH keys or tokens
- Third-party service passwords
By creating a dedicated app with restricted permissions, you add an additional layer of security that prevents unauthorized access.
Method
1. Create new app
as anyone can access the ‘security’ app. I suggest to create the new Mac app by building commandline tool with Xcode with the source code
Here is how to build it:
- Open Xcode and create a new project
- Select “macOS” > “Command Line Tool”
- Name it
keychain_reader - Replace the contents of
main.swiftwith the source code from the link above - Build the project (Cmd+B)
- Find the compiled binary in the Products folder (right-click > Show in Finder)
The source code uses the macOS Security framework to directly access the Keychain, bypassing the generic security command. This means when you grant access in Keychain, it will be specifically tied to your compiled binary.
2. change the permission
the app checks if it’s invoked with root permission or not. but, as the hacker can modify the app, change the permission for the app by the below. for doing it, you need root permission.
sudo chmod 700 keychain_reader
sudo chown root keychain_reader
This does two important things:
chmod 700: Only the owner (root) can read, write, or execute the file. No other user or group can access it.chown root: Changes the file owner to root, so only root-privileged processes can execute it.
Even if a malicious script knows the path to keychain_reader, it cannot execute it without root privileges.
3. allow the keychain_reader to access the password
invoke the below, and allow the keychain_reader to access the password always. now, only the person or service who have root permission can access the password
sudo ./keychain_reader <account_name> <service_name>
When you run this for the first time, macOS will show a Keychain access prompt. Click “Always Allow” to grant permanent access to the keychain_reader binary. Since the binary is owned by root with 700 permissions, this “Always Allow” is now restricted to root-only execution.
Using in Scripts
Once set up, you can use the keychain reader in your automation scripts:
#!/bin/bash
# Example: Fetch an API key securely
API_KEY=$(sudo /path/to/keychain_reader my-account my-service)
curl -H "Authorization: Bearer $API_KEY" https://api.example.com/data
Verifying Access Control
You can verify the access control settings in Keychain Access app:
- Open Keychain Access (Applications > Utilities)
- Find your password entry
- Right-click > Get Info > Access Control tab
- You should see
keychain_readerlisted under “Always allow access by these applications” - The
securitycommand should NOT be listed
Alternative Approaches
If building a custom app feels too complex, there are other ways to improve Keychain security:
- Always require password: Never click “Always Allow” for the
securitycommand. This is the simplest but most inconvenient option. - Use separate Keychains: Create a separate Keychain for sensitive credentials and lock it separately from the login Keychain.
- Environment variables: For less sensitive data, consider using environment variables stored in a restricted file instead of Keychain.
The custom app approach described in this guide offers the best balance of security and convenience.
Comments