I tend to overlook this frequently, so as a note to self, it’s possible to store arbitrary passwords or secrets in the macOS keychain, so as to use them from, say, Shell scripts.

From the command line I add an item named myk01 which will contain generic password with

$ security add-generic-password -a jpm -s myk01 -j 'this is for the program xyz' -w
password data for new item:
retype password for new item:

The secret is in the keychain, as this command tells me:

$ security find-generic-password -a jpm -s myk01
keychain: "/Users/jpm/Library/Keychains/login.keychain-db"
version: 512
class: "genp"
    0x00000007 <blob>="myk01"
    0x00000008 <blob>=<NULL>
    "cdat"<timedate>=0x32303231303431383039313632375A00  "20210418091627Z\000"
    "icmt"<blob>="this is for the program xyz"
    "mdat"<timedate>=0x32303231303431383039313632375A00  "20210418091627Z\000"

macOS keychain

And I can obtain just the password by adding a -w to the command:

$ security find-generic-password -a jpm -s myk01 -w

And that latter format is what I will use to obtain a password for this particular command:


export PASS=$(security find-generic-password -a $(whoami) -s myk01 -w)


Useful on occasion.


I want to access such a generic password from a Go program, which I do with go-keychain. I test with a “personalized” example from the README:

package main

import (

func main() {
	q := keychain.NewItem()


	res, err := keychain.QueryItem(q)
	if err != nil {
	} else if len(res) != 1 {
		fmt.Println("Not found")
	} else {
		password := string(res[0].Data)
		fmt.Printf("Password is: %T: %v\n", password, password)
{map[acct:jpm class:140735646167104 m_Limit:140735646169888 r_Data:true svce:myk01]}
Password is: string: sekr1t

Further reading

  • Roberto points us to a bit more high-level method using envchain, with support for macOS keychain or with D-Bus secret service.

shell and macos :: 18 Apr 2021 :: e-mail