diff --git a/node/identity.go b/node/identity.go index 5b650a5..cb80513 100644 --- a/node/identity.go +++ b/node/identity.go @@ -8,6 +8,7 @@ import ( "crypto/sha256" "encoding/hex" "encoding/json" + "os" "path/filepath" "sync" "time" @@ -208,10 +209,13 @@ func (n *NodeManager) savePrivateKey() error { return coreerr.E("NodeManager.savePrivateKey", "failed to create key directory", err) } - // Write private key + // Write private key and then tighten permissions explicitly. if err := coreio.Local.Write(n.keyPath, string(n.privateKey)); err != nil { return coreerr.E("NodeManager.savePrivateKey", "failed to write private key", err) } + if err := os.Chmod(n.keyPath, 0600); err != nil { + return coreerr.E("NodeManager.savePrivateKey", "failed to set private key permissions", err) + } return nil } diff --git a/node/identity_test.go b/node/identity_test.go index e2af1fb..ac892df 100644 --- a/node/identity_test.go +++ b/node/identity_test.go @@ -74,6 +74,25 @@ func TestNodeIdentity(t *testing.T) { } }) + t.Run("PrivateKeyPermissions", func(t *testing.T) { + nm, cleanup := setupTestNodeManager(t) + defer cleanup() + + err := nm.GenerateIdentity("permission-test", RoleDual) + if err != nil { + t.Fatalf("failed to generate identity: %v", err) + } + + info, err := os.Stat(nm.keyPath) + if err != nil { + t.Fatalf("failed to stat private key: %v", err) + } + + if got := info.Mode().Perm(); got != 0600 { + t.Fatalf("expected private key permissions 0600, got %04o", got) + } + }) + t.Run("LoadExistingIdentity", func(t *testing.T) { tmpDir, err := os.MkdirTemp("", "node-load-test") if err != nil {