{"id":28962018,"url":"https://github.com/paraphraser/set-gpg-pinentry-program","last_synced_at":"2026-05-06T11:32:04.017Z","repository":{"id":299758456,"uuid":"1004090423","full_name":"Paraphraser/set-gpg-pinentry-program","owner":"Paraphraser","description":"switch between gpg pinentry programs on Linux and macOS ","archived":false,"fork":false,"pushed_at":"2025-06-18T05:42:15.000Z","size":184,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-19T09:10:49.026Z","etag":null,"topics":["bash-script","gnupg","gpg","gpg-agent","gpg-configuration","launchagent","macos","pgp"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Paraphraser.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-18T05:29:55.000Z","updated_at":"2025-06-18T05:42:19.000Z","dependencies_parsed_at":"2025-06-18T06:37:27.725Z","dependency_job_id":null,"html_url":"https://github.com/Paraphraser/set-gpg-pinentry-program","commit_stats":null,"previous_names":["paraphraser/set-gpg-pinentry-program"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Paraphraser/set-gpg-pinentry-program","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Paraphraser%2Fset-gpg-pinentry-program","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Paraphraser%2Fset-gpg-pinentry-program/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Paraphraser%2Fset-gpg-pinentry-program/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Paraphraser%2Fset-gpg-pinentry-program/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Paraphraser","download_url":"https://codeload.github.com/Paraphraser/set-gpg-pinentry-program/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Paraphraser%2Fset-gpg-pinentry-program/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32691721,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T08:33:17.875Z","status":"ssl_error","status_checked_at":"2026-05-06T08:33:17.221Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash-script","gnupg","gpg","gpg-agent","gpg-configuration","launchagent","macos","pgp"],"created_at":"2025-06-24T02:33:27.349Z","updated_at":"2026-05-06T11:32:04.005Z","avatar_url":"https://github.com/Paraphraser.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# set-gpg-pinentry-program\n\nThis repository presents a single script which is intended to aid in setting the pin entry program correctly on both Linux and macOS.\n\nThe idea for this script was stimulated by the discussion at [Dr Duh YubiKey-Guide: Issue 504](https://github.com/drduh/YubiKey-Guide/issues/504).\n\nIf the script is running on macOS **and** the user selects the `pinentry-mac` program, the script also installs both a *run-at-load* [LaunchAgent](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html) and a complementary *delegate* (shell script) which performs basic error checking **before** taking any possibly destructive actions. The *delegate* also maintains a log of its activities so that the user has somewhere to start if it detects problems.\n\nThe launch agent and delegate replace the functionality of the pair of launch agents described at:\n\n* [Dr Duh YubiKey-Guide: SSH](https://github.com/drduh/YubiKey-Guide?tab=readme-ov-file#ssh)\n\n## installation\n\n1. Clone this repository from GitHub:\n\n\t``` console\n\t$ git clone https://github.com/Paraphraser/set-gpg-pinentry-program.git\n\t```\n\n2. Make the clone your working directory\n\n\t``` console\n\t$ cd set-gpg-pinentry-program\n\t```\n\n## usage\n\nWhen you run the script *without* any arguments, it displays a list of pinentry programs that are available on your system. Example:\n\n``` console\n$ ./set-gpg-pinentry-program.sh \nUsage: set-gpg-pinentry-program.sh { curses | gnome3 | mac | tty | x11 }\n```\n\nWhen you run the script *with* a valid target, it activates the associated `pinentry-` program. Example:\n\n``` console\n$ ./set-gpg-pinentry-program.sh curses\nActivated pinentry-program /usr/bin/pinentry-curses\n```\n\n## script internals\n\n### on both Linux and macOS\n\nThe script edits `~/.gnupg/gpg-agent.conf` as follows:\n\n1. Disables (comments-out) any pre-existing `pinentry-program` directives which were active; then\n2. Searches for and activates any inactive (ie commented-out) form of the `pinentry-program` you wish to activate; but\n3. If step 2 was unsuccessful (ie the search failed because `gpg-agent.conf` did not contain an inactive form), appends an appropriate `pinentry-program` directive to the file.\n\nChanges to `~/.gnupg/gpg-agent.conf` are propagated by invoking:\n\n``` console\n$ gpgconf --reload gpg-agent\n``` \n\n\u003e Testing suggests this is more reliable than `gpg-connect-agent reloadagent /bye`.\n\nYou can use `grep` to confirm the active choice. For example:\n\n``` console\n$ grep '^pinentry-program' ~/.gnupg/gpg-agent.conf\npinentry-program /usr/bin/pinentry-curses\n```\n\n### additional behaviour on macOS\n\nWhen running on macOS:\n\n1. The script checks whether the following \"launch agents\" are installed:\n\n\t```\n\t~/Library/LaunchAgents/gnupg.gpg-agent.plist\n\t~/Library/LaunchAgents/gnupg.gpg-agent-symlink.plist\n\t```\n\n\tIf found, the agents are deactivated and removed.\n\n\t\u003e Those property lists are mentioned at [SSH](https://github.com/drduh/YubiKey-Guide#ssh) in the [Dr Duh YubiKey-Guide](https://github.com/drduh/YubiKey-Guide). \n\n2. If `pinentry-mac` is being made active, the script:\n\n\t1. Installs a \"delegate\" (shell script) at the path:\n\t\n\t\t```\n\t\t~/.gnupg/gnupg.gpg-agent-pinentry-mac-delegate.sh\n\t\t```\n\n\t2. Installs a \"launch agent\" (property list) at the path:\n\t\n\t\t```\n\t\t~/Library/LaunchAgents/gnupg.gpg-agent-pinentry-mac.plist\n\t\t```\n\t\n\tThe launch agent runs each time you login to your macOS desktop (ie not via SSH). The *agent* executes the *delegate* which performs some sanity-checking, after which it creates the \"glue\" so that the `pinentry-mac` program can run successfully.\n\n\tThe combination of *launch agent* and *delegate* has the same overall effect as the older launch agent pairing of `gnupg.gpg-agent.plist` with `gnupg.gpg-agent-symlink.plist` but is generally safer and more robust.\n\n## delegate error-logging\n\nIf the *delegate* encounters any problems, it writes log entries to the path:\n\n```\n~/.gnupg/gnupg.gpg-agent-pinentry-mac-delegate.sh.log\n```\n\nYou should check that log if `pinentry-mac` does not seem to be working. The possible messages are:\n\n* `SSH_AUTH_SOCK is undefined (symbolic link can't be created)`\n\n\tDuring a reboot, the environment variable `SSH_AUTH_SOCK` is normally initialised with a value like the following, which is a path to a socket:\n\n\t```\n\t/private/tmp/com.apple.launchd.«randomValue»/Listeners\n\t```\n\n\tIf something prevents that socket from being created, `SSH_AUTH_SOCK` will be undefined and, accordingly, it will not be available to the *delegate*. Restarting your Mac should cure this problem.\n\n\tNote:\n\n\t- You can check `SSH_AUTH_SOCK` yourself like this:\n\n\t\t``` console\n\t\t$ echo \"SSH_AUTH_SOCK=$SSH_AUTH_SOCK\"\n\t\t```\n\n\t\tThis command must be executed in a Terminal session running directly on the Mac. You can't run this command remotely via SSH (you will always get a null answer).\n\n* `/Users/«user»/.gnupg/S.gpg-agent.ssh exists but is not a socket`\n\n\tThe file `~/.gnupg/S.gpg-agent.ssh` is expected to exist and be a socket when the *delegate* runs. This error indicates that the file exists but is not of the expected type. You can confirm this by running:\n\n\t``` console\n\t$ ls -l ~/.gnupg/S.gpg-agent.ssh\n\tsrwx------  1 moi  staff  0 Jun 12 11:44 ~/.gnupg/S.gpg-agent.ssh\n\t```\n\n\tThe leading `s` in `srwx` indicates that a file is a socket. It is an error if that first character is anything other than `s`, such as `-` (regular file) or `l` (symbolic link). Although the error message refers to a single file, it is often indicative of a wider problem. It is better to re-initialise the sub-system by removing all sockets and then re-run the *delegate* by hand, like this:\n\n\t``` console\n\t$ cd ~/.gnupg/\n\t$ rm S.gpg-agent*\n\t$ ./gnupg.gpg-agent-pinentry-mac-delegate.sh\n\t$\n\t```\n\n\tIn this situation, the *delegate* writes errors to the console rather than the log file so \"silence\" means \"success\".\n\n* `/Users/«user»/.gnupg/S.gpg-agent.ssh does not exist`\n\n\tThe most likely cause of this problem is that one of the *other* socket files exists but is not actually a socket. An error with any one of the sockets seems to prevent the creation of the full cohort of sockets. The solution here is the same as for the previous error: remove all the socket files and re-run the *delegate*. A system restart may also be helpful.\n\n## delegate code-signing\n\nAlthough it is not strictly necessary the *delegate* is code-signed. You can think of this as \"future proofing\" against the day when GateKeeper becomes even more restrictive about what you can run on your own Mac.\n\nThe default is to use a so-called \"ad-hoc\" signature, which means it will be marked as \"from an unidentified developer\" in:\n\n* *System Settings » General » Login Items \u0026 Extensions » Allow in the Background*\n\n\t![background item from unidentified developer](./images/allow-in-background-item.png)\n\nIf you have the necessary certificate in your keychain, you can use your own code-signing identity instead. To see if you have any valid identities, run:\n\n``` console\n$ security find-identity -v -p codesigning\n```\n\nIdentities are displayed as a list with a `«sequence») «hexID» \"«name»\"` format, like this:\n\n```\n  1) 0123456789ABCDEF0123456789ABCDEF01234567 \"certificate 1 name\"\n  2) 76543210FEDCBA9876543210FEDCBA9876543210 \"certificate 2 name\"\n  ...\n```\n\nYou can use any of those fields to indicate which identity to use. In the following example, all three commands refer to the **same** certificate:\n\n``` console\n$ CODESIGN=\"1\" ./set-gpg-pinentry-program.sh mac\n$ CODESIGN=\"0123456789ABCDEF0123456789ABCDEF01234567\" ./set-gpg-pinentry-program.sh mac\n$ CODESIGN=\"certificate 1 name\" ./set-gpg-pinentry-program.sh mac\n```\n\nWhen signed with your own certificate, *System Settings* groups the *delegate* together with any other items signed by the same certificate.\n\n## pinentry-program user-interface variants\n\n| Command Line Interface            | Graphical User Interface          |\n|:---------------------------------:|:---------------------------------:|\n| *pinentry-tty*                    | *pinentry-mac*                    |\n| ![](./images/pinentry-tty.png)    | ![](./images/pinentry-mac.png)    |\n| *pinentry-curses*                 | *pinentry-gnome3*                 |\n| ![](./images/pinentry-curses.png) | ![](./images/pinentry-gnome3.png) |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparaphraser%2Fset-gpg-pinentry-program","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparaphraser%2Fset-gpg-pinentry-program","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparaphraser%2Fset-gpg-pinentry-program/lists"}