cli: do not fall through to ~/.config from a non-default HERMES_HOME

A restricted profile shares the Unix user with the fleet. If its
$HERMES_HOME/sift/client.toml is missing, returning ~/.config/sift
would silently use the fleet key. Non-default HERMES_HOME now pins
the profile path so loadClient errors instead.
This commit is contained in:
2026-09-23 12:39:17 -07:00
parent 429f6b207e
commit 8ca3adec9e
2 changed files with 39 additions and 2 deletions
+19
View File
@@ -25,6 +25,9 @@ func clientConfigPath() string {
} }
if h := os.Getenv("HERMES_HOME"); h != "" { if h := os.Getenv("HERMES_HOME"); h != "" {
p := filepath.Join(h, "sift", "client.toml") p := filepath.Join(h, "sift", "client.toml")
if !hermesHomeIsDefault(h) {
return p
}
if _, err := os.Stat(p); err == nil { if _, err := os.Stat(p); err == nil {
return p return p
} }
@@ -36,6 +39,22 @@ func clientConfigPath() string {
return filepath.Join(home, ".config", "sift", "client.toml") return filepath.Join(home, ".config", "sift", "client.toml")
} }
func hermesHomeIsDefault(h string) bool {
home, err := os.UserHomeDir()
if err != nil {
return false
}
def, err := filepath.Abs(filepath.Join(home, ".hermes"))
if err != nil {
return false
}
got, err := filepath.Abs(h)
if err != nil {
return false
}
return got == def
}
func loadClient() (base, key string, err error) { func loadClient() (base, key string, err error) {
home, err := os.UserHomeDir() home, err := os.UserHomeDir()
if err != nil { if err != nil {
+20 -2
View File
@@ -58,9 +58,27 @@ func TestClientConfigPathHermesHome(t *testing.T) {
} }
} }
func TestClientConfigPathHermesHomeMissingFallsThrough(t *testing.T) { func TestClientConfigPathNonDefaultHermesHomeMissingDoesNotFallThrough(t *testing.T) {
t.Setenv("SIFT_CLIENT", "") t.Setenv("SIFT_CLIENT", "")
t.Setenv("HERMES_HOME", t.TempDir()) dir := t.TempDir()
t.Setenv("HERMES_HOME", dir)
got := clientConfigPath()
want := filepath.Join(dir, "sift", "client.toml")
if got != want {
t.Fatalf("got %q want %q", got, want)
}
if strings.Contains(got, filepath.Join(".config", "sift")) {
t.Fatal("fell through to ~/.config")
}
}
func TestClientConfigPathDefaultHermesHomeMissingFallsThrough(t *testing.T) {
home, err := os.UserHomeDir()
if err != nil {
t.Fatal(err)
}
t.Setenv("SIFT_CLIENT", "")
t.Setenv("HERMES_HOME", filepath.Join(home, ".hermes"))
got := clientConfigPath() got := clientConfigPath()
if !strings.HasSuffix(got, filepath.Join(".config", "sift", "client.toml")) { if !strings.HasSuffix(got, filepath.Join(".config", "sift", "client.toml")) {
t.Fatalf("got %q", got) t.Fatalf("got %q", got)