Remove the keychain and Secure Enclave unlockers (closes #132)
check / check (push) Failing after 5s

Neither unlocker works without macOS code signing and entitlements, which
secret does not have, so both were research and leave the build.
`secret unlocker add` takes only passphrase and pgp on every platform;
keychain and secure-enclave fail as unknown types and are gone from
--help and shell completion. internal/macse, their files in
internal/secret with their tests, and their branches in internal/vault
and internal/cli are deleted; github.com/keybase/go-keychain leaves
go.mod and go.sum. README and Dockerfile comments no longer mention
them. The research stays at ef0ae90, tagged v1.0.0-rc1.

Judgement call: derivation_index_test.go goes with getLongTermPrivateKey,
its only subject, which only these two unlockers used.
Unverified: not built or run on a Mac; only the GOOS=darwin vet and lint ran.

Model: opus-5-5
This commit was merged in pull request #134.
This commit is contained in:
2026-10-13 00:39:35 +02:00
parent ef0ae90768
commit 2d6675a452
34 changed files with 66 additions and 3087 deletions
+4 -102
View File
@@ -10,7 +10,6 @@ import (
"os"
"os/exec"
"path/filepath"
"runtime"
"slices"
"strings"
"time"
@@ -21,14 +20,10 @@ import (
"sneak.berlin/go/secret/internal/vault"
)
// Unlocker type names and platform identifiers shared across the CLI
// Unlocker type names shared across the CLI
const (
unlockerTypePassphrase = "passphrase"
unlockerTypeKeychain = "keychain"
unlockerTypePGP = "pgp"
unlockerTypeSecureEnclave = "secure-enclave"
platformDarwin = "darwin"
unlockerTypePassphrase = "passphrase"
unlockerTypePGP = "pgp"
cmdUseList = "list"
)
@@ -143,9 +138,8 @@ func newUnlockerListCmd() *cobra.Command {
}
// unlockerAddHelp returns the supported unlocker types list and their
// descriptions for the current platform
// descriptions
func unlockerAddHelp() (string, string) {
// Build the supported types list based on platform
supportedTypes := "passphrase, pgp"
typeDescriptions := "Available unlocker types:\n" +
"\n" +
@@ -162,43 +156,6 @@ func unlockerAddHelp() (string, string) {
" Use --keyid to specify a particular key, " +
"otherwise uses your default GPG key."
if runtime.GOOS == platformDarwin {
supportedTypes = "passphrase, keychain, pgp, secure-enclave"
typeDescriptions = "Available unlocker types:\n" +
"\n" +
" passphrase - Traditional password-based encryption\n" +
" Prompts for a passphrase that will be " +
"used to encrypt/decrypt the vault's master key.\n" +
" The passphrase is never stored in " +
"plaintext.\n" +
"\n" +
" keychain - macOS Keychain integration (macOS only)\n" +
" Stores the vault's master key in the " +
"macOS Keychain, protected by your login password.\n" +
" Automatically unlocks when your Keychain " +
"is unlocked (e.g., after login).\n" +
" Provides seamless integration with macOS " +
"security features like Touch ID.\n" +
"\n" +
" pgp - GNU Privacy Guard (GPG) key-based " +
"encryption\n" +
" Uses your existing GPG key to " +
"encrypt/decrypt the vault's master key.\n" +
" Requires gpg to be installed and " +
"configured with at least one secret key.\n" +
" Use --keyid to specify a particular key, " +
"otherwise uses your default GPG key.\n" +
"\n" +
" secure-enclave - Apple Secure Enclave hardware protection " +
"(macOS only)\n" +
" Stores the vault's master key encrypted " +
"by a non-exportable P-256 key\n" +
" held in the Secure Enclave. The key " +
"never leaves the hardware.\n" +
" Uses ECIES encryption; decryption is " +
"performed inside the SE."
}
return supportedTypes, typeDescriptions
}
@@ -420,18 +377,10 @@ func (cli *Instance) UnlockersAdd(unlockerType string, cmd *cobra.Command) error
switch unlockerType {
case unlockerTypePassphrase:
return cli.addPassphraseUnlocker(cmd)
case unlockerTypeKeychain:
return cli.addKeychainUnlocker(cmd)
case unlockerTypeSecureEnclave:
return cli.addSecureEnclaveUnlocker(cmd)
case unlockerTypePGP:
return cli.addPGPUnlocker(cmd)
default:
// Build the supported types list based on platform
supportedTypes := "passphrase, pgp"
if runtime.GOOS == platformDarwin {
supportedTypes = "passphrase, keychain, pgp, secure-enclave"
}
return fmt.Errorf("%w: %s (supported: %s)",
errInvalidUnlockerType, unlockerType, supportedTypes)
@@ -487,53 +436,6 @@ func (cli *Instance) addPassphraseUnlocker(cmd *cobra.Command) error {
return nil
}
// addKeychainUnlocker creates a macOS Keychain unlocker in the current vault
func (cli *Instance) addKeychainUnlocker(cmd *cobra.Command) error {
keychainUnlocker, err := secret.CreateKeychainUnlocker(
cli.fs, cli.stateDir, cli.Mnemonic, cli.UnlockPassphrase)
if err != nil {
return fmt.Errorf("failed to create macOS Keychain unlocker: %w", err)
}
cmd.Printf("Created macOS Keychain unlocker: %s\n", keychainUnlocker.GetID())
keyName, err := keychainUnlocker.GetKeychainItemName()
if err == nil {
cmd.Printf("Keychain Item Name: %s\n", keyName)
}
// Auto-select the newly created unlocker
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {
return fmt.Errorf("failed to get current vault: %w", err)
}
autoSelectUnlocker(cmd, vlt, keychainUnlocker.GetID())
return nil
}
// addSecureEnclaveUnlocker creates a Secure Enclave unlocker in the
// current vault
func (cli *Instance) addSecureEnclaveUnlocker(cmd *cobra.Command) error {
seUnlocker, err := secret.CreateSecureEnclaveUnlocker(
cli.fs, cli.stateDir, cli.Mnemonic, cli.UnlockPassphrase)
if err != nil {
return fmt.Errorf("failed to create Secure Enclave unlocker: %w", err)
}
cmd.Printf("Created Secure Enclave unlocker: %s\n", seUnlocker.GetID())
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {
return fmt.Errorf("failed to get current vault: %w", err)
}
autoSelectUnlocker(cmd, vlt, seUnlocker.GetID())
return nil
}
// addPGPUnlocker creates a PGP unlocker in the current vault
func (cli *Instance) addPGPUnlocker(cmd *cobra.Command) error {
// Get GPG key ID from flag, environment, or default key