{
	"id": "854b744f-e643-47ca-8691-23d23aa76085",
	"created_at": "2026-04-06T00:13:08.90039Z",
	"updated_at": "2026-04-10T03:24:29.915025Z",
	"deleted_at": null,
	"sha1_hash": "d380228008a024d9e428986e6e223dd2d00d3fbe",
	"title": "Using the OS X Keychain to store and retrieve passwords",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 261159,
	"plain_text": "Using the OS X Keychain to store and retrieve passwords\r\nArchived: 2026-04-05 22:42:00 UTC\r\nNovember 5th, 2015\r\nThis document describes how to use the Mac OS X Keychain to store and retrieve passwords or other secrets from the command-line.\r\nThis may be a reasonable solution for you to manage per-user secrets on your laptop or desktop, for example. Please consult with your\r\nfriendly neighborhood paranoid.\r\nPlease see this page for a related discussion around passing passwords to different tools.\r\nLet's assume that a 'playground' service requires a password to be available in your shell's PLAYGROUND\r\nenvironment variable. Placing the password into your ~/.bashrc would accomplish this:\r\nexport PLAYGROUND=\"monkeybars\"\r\nUnfortunately, even with suitable permissions on ~/.bashrc, this is not a good solution, since dot files like this\r\nhave a tendency to accidentally be committed to github.com or copied to other places such that even though it\r\nmight be reasonable to store such a password on your laptop in a plain text file protected by Unix permissions\r\n(e.g. 0400), doing so would lead to an increased risk of exposure.\r\nInstead, we'd like a method to retrieve the password non-interactively from a safe password store, thus only\r\nmaking it available in the environment, but not in a file.\r\nA note about password managers\r\nFor common per-user passwords for use with HTTPS, such as used to log into common web services, please do\r\nuse a password manager. Your password manager may also be suitable to store any generic secrets.\r\nHowever, in some cases you may have a need to access such secrets on the command-line, and many password\r\nmanagers do not have trivial or convenient access tools to accomplish this.\r\nIn those cases, using the approach outlined here may be preferable.\r\nAdvantages of using the keychain\r\nUsing the OS X keychain means that you have easily accessible and usable encrypted storage of your secret.\r\nWhen a keychain is unlocked (such as most commonly the default \"login\" keychain at, well, login time), you can\r\nget the values of the items stored in it via the command-line or its GUI application.\r\nThis means you do not have to worry about remembering which file you may have stored a secret in, if the file is\r\nsuitably protected using permissions or can be accessed by other users on the system.\r\nhttps://www.netmeister.org/blog/keychain-passwords.html\r\nPage 1 of 6\n\nDisadvantages of using the keychain\r\nUsing the OS X keychain also means that anybody with access to the keychain may have access to the secret.\r\nMost notably, your default login keychain is often unlocked when you're using your OS X system, so any process\r\nrunning with your privileges (or the super-user privileges, of course) may be able to access the secrets.\r\nIndividually encrypted storage such as by way of a password manager may be preferable, depending on your use\r\ncase.\r\nAdding a secret to your keychain\r\nTo add a secret to your keychain, you can either use the graphical application (\"Keychain Access\") or the\r\ncommand-line utility security(1).\r\nIn the following example, we will create a password for an application called \"playground\":\r\nKeychain Access\r\nopen /Applications/Utitlies/Keychain\\ Access.app\r\nSelect File-\u003eNew Password Item (cmd+N)\r\nUse the Password Assistant to have it generate a new random password for you:\r\nhttps://www.netmeister.org/blog/keychain-passwords.html\r\nPage 2 of 6\n\nAfter clicking 'Add', your new password is now available in the login keychain.\r\nSelect 'All Items' and search for 'playground' to find it:\r\nhttps://www.netmeister.org/blog/keychain-passwords.html\r\nPage 3 of 6\n\nVia the command-line\r\nFirst, we need to generate a new password. Don't try to be clever and think of one yourself -- no matter what\r\nyou're friends tell you, you're not very random.\r\nLet's create a quick little script to generate a reasonably random complex password:\r\n$ cat \u003e ~/bin/pwgen \u003c\u003c\"EOF\"\r\n#! /bin/sh\r\nnum=32\r\nif [ x\"${1}\" = x\"-n\" ]; then\r\n num=$2\r\nfi\r\nLANG=C tr -dc '[:print:]' \u003c/dev/urandom | head -c ${num}\r\nEOF\r\n$ chmod 755 ~/bin/pwgen\r\n$\r\n(Note: you could add a trailing \"| xargs\" to get a trailing \\n, but then you'd need to exclude a few characters\r\nfrom the character set to avoid errors due to unterminated quotes etc. Similarly, you may wish to exclude spaces\r\nfrom your password charset. In other words: season the args to tr(1) to your liking.)\r\nNow that we have a command to spit out a reasonably random, complex password, we can proceed to add it our\r\nkeychain using the security(1) command:\r\n$ security add-generic-password -a ${USER} -s playground -w $(pwgen)\r\nA few things to note here:\r\nhttps://www.netmeister.org/blog/keychain-passwords.html\r\nPage 4 of 6\n\nThe command will fail if you already have a \"service\" by the name of \"playground\" such as if you followed the\r\nGUI example above. You can delete the previously created password in the keychain using the command:\r\n$ security delete-generic-password -a ${USER} -s playground\r\nSecondly, we are necessarily leaking the newly generated password into the process table as the shell expands the\r\nsubshell (more details here). Sadly, the security(1) utility has no other method of non-interactively accepting a\r\npassword but on the command-line[1]. For this reason, it may be preferable to create the secret using the GUI\r\napplication.\r\nRetrieving the password from the command-line\r\nIn order to retrieve the password from the command-line, you can run the security(1) command as follows:\r\n$ security find-generic-password -a ${USER} -s playground -w\r\nl8e4ALKC[gBz[0u@VfHr__ZPkO2;Mj:\r\n$\r\nUsing this approach, we can then place a password into the shell environment without leaking it into a file:\r\n$ cat \u003e\u003e ~/.bashrc \u003c\u003c\"EOF\"\r\nexport PLAYGROUND=$(security find-generic-password -a ${USER} -s playground -w)\r\nEOF\r\n$\r\nFinal notes\r\nManaging secrets appropriately requires a full understanding of what the secret is used to protect, who has access\r\nto the resources in question, and the circumstances of using the tools involved. No one solution fits all needs, and\r\nan approach that works for some situations may not be suitable for others.\r\nThe use case described here is specifically intended for ease of use while retaining storage safety of the secrets,\r\nbut does not protect against an attacker with super-user- or same-user-level privileges on the same system.\r\nWhen in doubt, please consult with your friendly neighborhood paranoid.\r\nNovember 5th, 2015\r\n1:\r\nThe security(1) utility offers the -i flag to enter interactive mode, allowing you to provide the password without leaking it into the\r\nprocess table, but that does not allow shell expansion within the interactive prompt:\r\n$ security -i\r\nsecurity\u003e add-generic-password -a jschauma -s playground -w gVmMQgEEF[bc'S15_=zD*]sHQ[IkOVY_\r\nhttps://www.netmeister.org/blog/keychain-passwords.html\r\nPage 5 of 6\n\nsecurity\u003e ^D\r\n$\r\nAlternatively, you can also let security(1) prompt you interactively for the password, by leaving out the last argument to the '-w' flag:\r\n$ security add-generic-password -a ${USER} -s playground -w\r\npassword data for new item:\r\nretype password for new item:\r\n$\r\nSource: https://www.netmeister.org/blog/keychain-passwords.html\r\nhttps://www.netmeister.org/blog/keychain-passwords.html\r\nPage 6 of 6",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://www.netmeister.org/blog/keychain-passwords.html"
	],
	"report_names": [
		"keychain-passwords.html"
	],
	"threat_actors": [
		{
			"id": "d90307b6-14a9-4d0b-9156-89e453d6eb13",
			"created_at": "2022-10-25T16:07:23.773944Z",
			"updated_at": "2026-04-10T02:00:04.746188Z",
			"deleted_at": null,
			"main_name": "Lead",
			"aliases": [
				"Casper",
				"TG-3279"
			],
			"source_name": "ETDA:Lead",
			"tools": [
				"Agentemis",
				"BleDoor",
				"Cobalt Strike",
				"CobaltStrike",
				"RbDoor",
				"RibDoor",
				"Winnti",
				"cobeacon"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "aa73cd6a-868c-4ae4-a5b2-7cb2c5ad1e9d",
			"created_at": "2022-10-25T16:07:24.139848Z",
			"updated_at": "2026-04-10T02:00:04.878798Z",
			"deleted_at": null,
			"main_name": "Safe",
			"aliases": [],
			"source_name": "ETDA:Safe",
			"tools": [
				"DebugView",
				"LZ77",
				"OpenDoc",
				"SafeDisk",
				"TypeConfig",
				"UPXShell",
				"UsbDoc",
				"UsbExe"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434388,
	"ts_updated_at": 1775791469,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/d380228008a024d9e428986e6e223dd2d00d3fbe.pdf",
		"text": "https://archive.orkl.eu/d380228008a024d9e428986e6e223dd2d00d3fbe.txt",
		"img": "https://archive.orkl.eu/d380228008a024d9e428986e6e223dd2d00d3fbe.jpg"
	}
}