smimesign signs Git commits with the S/MIME certificate already in your OS keychain
An S/MIME signing utility for use with Git
At a glance
- What is it?
- smimesign is a Go utility that plugs into Git's signing hooks and signs commits and tags with X.509 certificates held in the macOS Keychain or the Windows Certificate Store. It exists for organizations whose trust model is a certificate authority rather than a web of trust, and it still carries a pre-1.0 warning label.
- Who is it for?
- smimesign fits teams that already issue S/MIME certificates through a corporate CA and want Git signatures verifiable without installing GnuPG keyrings on every workstation. It does not fit developers who want an offline key workflow, and it is not yet documented for Linux, where the project carries a compiler error stub rather than a build path.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 44 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why a certificate authority beats a web of trust for large organizations
Git's built-in signing story is GnuPG, and GnuPG's trust model is distributed. A verifier either knows the signer's public key directly, or knows someone who vouches for it, and those layers of vouching build a web of trust. That model suits an unstructured environment.
Corporate environments tend to run the opposite way. A centralized certificate authority issues signed certificates that identify subjects such as people or computers, and the certificate carries the identity's public key inside it. Anyone who trusts the authority can then verify a signature from that identity without any keyring distribution. S/MIME is the protocol that applies this PKI approach to signing data, originally standardized for email but equally applicable to a Git object.
smimesign is the bridge. It is an S/MIME signing utility for macOS and Windows that is compatible with Git, so a developer signs commits and tags with an X.509 certificate issued by a public certificate authority or by their organization's internal authority. Nothing about the workflow changes except where the key comes from and how a verifier establishes trust.
The private key is not managed by the tool. smimesign uses keys and certificates already stored in the macOS Keychain or the Windows Certificate Store. That is the whole design: no keyring to create, no secret key file to copy, and for a company that has already issued smart cards, the certificate is already there.
The Git plumbing that makes signing work, and the version boundary at 2.19
Git does not know about S/MIME. It knows about a signing program, and smimesign takes the role of that program through Git's gpg configuration keys.
For Git 2.19 and newer, two keys are set. gpg.x509.program points at the smimesign binary, and gpg.format is set to x509 so Git speaks the X.509 variant of the interface rather than the OpenPGP one. The scope can be local to a repository or global for the machine.
Git 2.18 and older use a different key, gpg.program, with no format switch:
$ git config --local gpg.program smimesign$ git config --global gpg.program smimesignThat split is a real compatibility boundary rather than a wording nicety. On older Git the smimesign binary is simply the signing program; on newer Git you also have to declare the format, otherwise Git will try to parse an S/MIME signature as OpenPGP and fail. The project points out that the directives for changing signing tools changed in Git version 2.19, so a snippet written for one era will silently misconfigure the other.
The repository layout mirrors the same split. The top level holds command_sign.go and command_verify.go, the two verbs Git invokes, plus list_keys_command.go, parse_user_id.go, status.go, and utils.go. That naming is itself informative: the binary is expected to behave like a signing tool, not like an application with a rich interface.
Installing on macOS and Windows, and the gcc requirement for building from source
On macOS, Homebrew is the documented route:
brew install smimesignA prebuilt macOS binary can also be downloaded from the releases page and placed on your $PATH so Git can find it.
Windows uses scoop:
scoop install smimesignOr you can download a prebuilt Windows binary and put the appropriate binary on your %PATH%.
For building from source, the requirements are more demanding and one of them is easy to miss. You need the Go compiler, and the go.mod file declares Go 1.25.0. You also need a gcc compiler set up in your path to compile embedded c in go files, which is the step that trips people up on macOS where no C toolchain is present by default. You will probably want $GOPATH/bin on your $PATH so the built binary is discoverable, and the project gives the fetch command as go get github.com/github/smimesign.
Note the absence of a Linux path in this project. The tool is described as being for macOS and Windows, and the repository contains a compiler_error_linux.go file, which reads as an explicit refusal to build there rather than an oversight in the documentation.
Checking that your certificate is visible before you sign anything
smimesign needs no configuration file of its own. What it needs is a certificate and its private key, already present in the platform store, and ideally a certificate that includes your Git email address so the signed commit carries an identity a verifier can match to the author.
Finding the email that Git will use is a single command:
$ git config --get user.emailListing what the store actually holds is another:
$ smimesign --list-keysThat second command is the one to run first, and it is worth running on a machine that will actually sign. If your certificate does not appear there, no amount of Git configuration will help, because the problem is upstream in how the certificate was installed. Running this before wiring up Git turns a confusing signing failure into a one line diagnosis.
The certificate also needs the right content, not just the right presence. A certificate without your Git email address will sign fine but will not attribute the signature to your commit identity in a useful way. The project is direct about this: to sign Git commits or tags, it is best to have a certificate that includes your Git email address.
Smart cards work if the operating system can already see the certificate
Large organizations and government agencies often hand out certificates and keys on smart cards, so that the private key can sign without ever being exportable. The native certificate stores on Windows and macOS can talk to smart cards directly, although special drivers or middleware may be needed.
The test the project gives is practical: if you can find your certificate in the Keychain Access app on macOS, or in the Certificate Manager (certmgr) on Windows, it will probably work with smimesign. If you cannot find it, you need drivers or middleware.
For Yubikey specifically, many models support the PIV smart card interface, and getting the operating system to discover the certificate and key usually means installing the OpenSC middleware. There is a macOS specific trap here. The project says to avoid installing OpenSC using homebrew, because that route omits an important component, and instead to use the installer provided by OpenSC or the homebrew-cask formula. Missing the tokend component means the certificate never shows up in Keychain Access, and the symptom looks like a smimesign failure when it is actually a middleware install problem.
On macOS you also need the Yubikey PIV Manager (GUI) or the Yubikey PIV Tool (command line) to manage the certificates and keys on the device.
Reusable libraries, and a pre-1.0 warning label
The repository ships more than a command line tool. It contains reusable libraries in nested packages: certstore, fakeca, and ietf-cms, each with its own directory at the top level of the tree.
The names describe the layering. certstore is the interface to the platform certificate stores, the place where the Windows Certificate Store and the macOS Keychain are abstracted. ietf-cms points at the CMS, the Cryptographic Message Syntax standard that S/MIME signatures are built on, so that package likely carries the encoding and parsing of the signed object. fakeca is a test facility: a fake certificate authority, so that signing and verification can be exercised without provisioning real certificates. The main package also carries main_test.go, command_sign_test.go, and the testify dependency in go.mod, which is consistent with a test suite that uses those pieces to sign and verify synthetic data.
That library split is what makes the project more than a wrapper. A team that wants S/MIME signing inside its own tooling, in another language or a different signing flow, can depend on the pieces rather than shelling out to the binary.
The caveat sits at the top of the description: the project is pre-1.0, meaning that APIs and functionality may change without warning. For anyone embedding certstore or ietf-cms in a product, that sentence is the upgrade cost to plan around. The licence is MIT, which is permissive and uncomplicated for both the command line use and the library use.
Where smimesign is the wrong tool, and who maintains it
Two boundaries are clear from what the project describes.
The first is platform scope. The tool targets macOS and Windows and reads keys from their native stores. Linux users, and anyone whose keys live in a GnuPG keyring or a password manager, get nothing here. The go.mod file lists golang.org/x/crypto among its direct dependencies, but there is no described Linux build path and the presence of a compiler error stub for Linux suggests one is deliberately absent.
The second is the trust model itself. If your verification model is a web of trust, or if you need signatures that survive outside your organization, an S/MIME signature chained to an internal CA may not be what the consuming side expects. smimesign does not change what a signature proves, only which authority stands behind it.
Maintenance is the less certain part. The last push to the repository was on 2026-09-10, which is recent, but the tagged releases are much older: v0.2.0 and v0.2.0-rc1 both date from 2021-10-04, and v0.1.2 from 2021-09-28. So the code has been touched recently without a new tagged release in about five years. The repository also carries MAINTAINING.md and CONTRIBUTING.md, and the contributing notes ask for help because different organizations do PKI differently and the maintainers could not test everyone's setup. That is the honest picture: a small tool, an MIT licence, active commits, and a release tag that has not moved since 2021.
Editorial conclusion
smimesign fits teams that already issue S/MIME certificates through a corporate CA and want Git signatures verifiable without installing GnuPG keyrings on every workstation. It does not fit developers who want an offline key workflow, and it is not yet documented for Linux, where the project carries a compiler error stub rather than a build path. Before adopting it, run smimesign --list-keys on a machine with a smart card to confirm your certificate is visible to the OS store, since that check decides whether the setup works at all.
Frequently asked questions
How do I install smimesign on macOS and Windows?
On macOS you can run brew install smimesign, and on Windows you can run scoop install smimesign. Prebuilt binaries are also published on the releases page and need to be placed on $PATH or %PATH% so Git can find them.
How do I tell Git to sign commits with smimesign?
For Git 2.19 and newer, set gpg.x509.program to smimesign and gpg.format to x509, either with the --local or the --global flag. For Git 2.18 and older, set gpg.program to smimesign instead, since the format directive does not exist there.
Where does smimesign store its keys and certificates?
It uses keys and certificates already stored in the macOS Keychain or the Windows Certificate Store, so no separate keyring or key file is needed. You can list what is available with smimesign --list-keys.
Can I use smimesign with a Yubikey smart card?
Yes, if the operating system can see the certificate, which usually means installing the OpenSC middleware for PIV. On macOS, do not install OpenSC through homebrew since that omits an important component, and use the Yubikey PIV Manager to manage the certificates and keys.
Does smimesign work on Linux?
The project describes smimesign as a utility for macOS and Windows, and the repository contains a compiler error stub for Linux rather than a documented Linux build and installation path.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/github-smimesign)Was this useful?