1
0
forked from sneak/secret

fix: use vault derivation index in getLongTermPrivateKey instead of hardcoded 0

Previously, getLongTermPrivateKey() always used derivation index 0 when
deriving the long-term key from a mnemonic. This caused wrong key
derivation for vaults with index > 0 (second+ vault from same mnemonic),
leading to silent data corruption in keychain unlocker creation.

Now reads the vault's actual DerivationIndex from vault-metadata.json.
This commit is contained in:
clawbot 2026-02-08 12:03:06 -08:00
parent 128c53a11d
commit 2a4ceb2045

View File

@ -251,8 +251,25 @@ func getLongTermPrivateKey(fs afero.Fs, vault VaultInterface) (*memguard.LockedB
// Check if mnemonic is available in environment variable // Check if mnemonic is available in environment variable
envMnemonic := os.Getenv(EnvMnemonic) envMnemonic := os.Getenv(EnvMnemonic)
if envMnemonic != "" { if envMnemonic != "" {
// Use mnemonic directly to derive long-term key // Read vault metadata to get the correct derivation index
ltIdentity, err := agehd.DeriveIdentity(envMnemonic, 0) vaultDir, err := vault.GetDirectory()
if err != nil {
return nil, fmt.Errorf("failed to get vault directory: %w", err)
}
metadataPath := filepath.Join(vaultDir, "vault-metadata.json")
metadataBytes, err := afero.ReadFile(fs, metadataPath)
if err != nil {
return nil, fmt.Errorf("failed to read vault metadata: %w", err)
}
var metadata VaultMetadata
if err := json.Unmarshal(metadataBytes, &metadata); err != nil {
return nil, fmt.Errorf("failed to parse vault metadata: %w", err)
}
// Use mnemonic with the vault's actual derivation index
ltIdentity, err := agehd.DeriveIdentity(envMnemonic, metadata.DerivationIndex)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to derive long-term key from mnemonic: %w", err) return nil, fmt.Errorf("failed to derive long-term key from mnemonic: %w", err)
} }