Ditch the plain-text credentials. Learn how to securely route your terminal secrets through macOS Keychain.

Image Generated by Gemini
Image Generated by Gemini
Here’s something that’ll make you cringe: most Mac tutorials tell you to dump plain-text API keys straight into your dotfiles. Yeah, those hidden configuration files? They’re basically an open book to any local script or suspicious dependency that wants a peek. If you crack open your shell config right now, odds are you’ll spot active tokens, database passwords, or cloud credentials just sitting there in the open. Not great.
The good news? We can patch this security hole by routing environment variables through macOS Keychain instead. This keeps your credentials encrypted, off your hard drive in plaintext, and safely handled by your operating system. Let me walk you through exactly how to do this on your machine — and how to bail out of your old, insecure setup.

Step 1: Clean Out Your Old Plain-Text Variables

First things first: you’ve got to remove the evidence before moving forward.
Open your ~/.zshrc file in whatever editor you prefer. Hunt for lines that look like this:
Delete them. Save the file. Close the editor.
Got active terminal sessions running? Your variables will stay in memory until you close them, but at least you’ve stopped them from loading going forward.

Step 2: Stash Your Secret in Keychain

Forget the text file approach. Instead, we’ll use macOS’s built-in security command to inject your secret straight into Keychain.
Head to your terminal and run this:
Swap out my_secret_token with something descriptive for your credential, and replace that final string with your actual secret.
Using $USER for the -a (account) flag is smart—it automatically ties the record to your macOS login. The -s flag? That's your service name, the unique lookup key.

Step 3: Double-Check the Keychain Entry

Let’s make sure the operating system actually stored it right and will spit back just the secret without extra fluff.
Run this lookup command with the -w flag to get only the raw secret:
See your secret printed on the next line? You’re golden. Error message instead? Make sure your service name matches exactly what you used in Step 2.

Step 4: Wire Up Keychain Into Your Shell Config

Now comes the fun part: set up your shell to grab that secret every time you open a new terminal window.
Pop open your ~/.zshrc again and stick this line where your old plain-text export lived:
This uses command substitution. When Zsh boots up, it runs that security command behind the scenes, pulls the password from your encrypted database, and assigns it to MY_SECRET_API_KEY.

Step 5: Fire It Up and Test

To load these changes into your current terminal without restarting, source the config:
The first time you do this — or when you open a fresh terminal — macOS will throw up a dialog asking whether zsh can access your Keychain. Hit Always Allow. Your shell gets persistent background access, so you won't see that prompt nagging you every time.
Now verify the goods:

One Thing You Should Know: The Boot-Time Wrinkle

Here’s where things get tricky. This whole setup depends on macOS’s graphical security layer, and that matters during startup.
When your Mac boots and you haven’t yet logged in at the keyboard with the GUI, the login Keychain stays locked. If some automated script, cron job, or background daemon tries to load your ~/.zshrc before you've physically authenticated, the security command hits a wall. It can't throw up a graphical prompt to an unauthenticated session, times out, returns an error, and your environment variable initializes as empty.
Keep this approach for interactive work only. Need secrets for headless operations or daemons spinning up right after boot? Look into dedicated machine-to-machine secrets managers or specialized launch daemons instead of the user login Keychain.

Handy Tricks and Shortcuts

Refreshing an Expired Token: Your token expires, you need to update it? The add-generic-password command will complain that the item already exists. Just tack on the -U flag to overwrite instead of creating a duplicate:
Removing a Secret You No Longer Need: Don’t just delete the line from your ~/.zshrc. Wipe the underlying data from your system entirely:
Checking Who Can Access What: Want a visual breakdown? Fire up the Keychain Access app on your Mac and search for your service name. Double-click the entry. Head to the Access Control tab and you’ll see exactly which apps have permission to read the token. Revoke access whenever you want.

The Wrap-Up

Moving your keys out of dotfiles takes maybe five minutes and kills one of the most common security blind spots on development machines today. Dig through your config files, yank those plain-text values out, and stick them in Keychain where they belong.
Share this article

Join the newsletter

Join thousands of satisfied readers.