From 81576e375723bb4f18d0d3d5aef2ae4689661c5f Mon Sep 17 00:00:00 2001 From: 0xGabey Date: Mon, 7 Sep 2026 21:04:28 +0700 Subject: [PATCH 1/2] fix(cli): create config dir before writing registry token `substreams registry login` failed with "no such file or directory" on machines where ~/.config/substreams did not exist yet. Token file is now 0600 since it holds a secret; existing 0644 files get tightened on re-login because WriteFile only applies mode on create. --- cmd/substreams/registry-login.go | 11 ++++++- cmd/substreams/registry-login_test.go | 42 +++++++++++++++++++++++++++ docs/release-notes/change-log.md | 4 +++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 cmd/substreams/registry-login_test.go diff --git a/cmd/substreams/registry-login.go b/cmd/substreams/registry-login.go index c94f1e0a3..b3b0852a8 100644 --- a/cmd/substreams/registry-login.go +++ b/cmd/substreams/registry-login.go @@ -64,7 +64,16 @@ func runRegistryLoginE(cmd *cobra.Command, args []string) error { } func writeRegistryToken(token string) error { - return os.WriteFile(registryTokenFilename, []byte(token), 0644) + if err := os.MkdirAll(filepath.Dir(registryTokenFilename), 0o700); err != nil { + return fmt.Errorf("creating registry token directory: %w", err) + } + + if err := os.WriteFile(registryTokenFilename, []byte(token), 0o600); err != nil { + return fmt.Errorf("writing registry token file: %w", err) + } + + // WriteFile only applies the mode on create; re-login must tighten an existing file. + return os.Chmod(registryTokenFilename, 0o600) } func checkFileExists(filePath string) bool { diff --git a/cmd/substreams/registry-login_test.go b/cmd/substreams/registry-login_test.go new file mode 100644 index 000000000..f9d43496b --- /dev/null +++ b/cmd/substreams/registry-login_test.go @@ -0,0 +1,42 @@ +package main + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestWriteRegistryTokenCreatesParentDir(t *testing.T) { + path := filepath.Join(t.TempDir(), ".config", "substreams", "registry-token") + prev := registryTokenFilename + registryTokenFilename = path + t.Cleanup(func() { registryTokenFilename = prev }) + + require.NoError(t, writeRegistryToken("tok")) + + info, err := os.Stat(path) + require.NoError(t, err) + assert.Equal(t, os.FileMode(0o600), info.Mode().Perm()) + + got, err := os.ReadFile(path) + require.NoError(t, err) + assert.Equal(t, "tok", string(got)) +} + +func TestWriteRegistryTokenChmodsExisting(t *testing.T) { + path := filepath.Join(t.TempDir(), "registry-token") + require.NoError(t, os.WriteFile(path, []byte("old"), 0o644)) + require.NoError(t, os.Chmod(path, 0o644)) + prev := registryTokenFilename + registryTokenFilename = path + t.Cleanup(func() { registryTokenFilename = prev }) + + require.NoError(t, writeRegistryToken("new")) + + info, err := os.Stat(path) + require.NoError(t, err) + assert.Equal(t, os.FileMode(0o600), info.Mode().Perm()) +} diff --git a/docs/release-notes/change-log.md b/docs/release-notes/change-log.md index 4f457f793..f95cbdfac 100644 --- a/docs/release-notes/change-log.md +++ b/docs/release-notes/change-log.md @@ -13,6 +13,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### CLI +- Fixed: `substreams registry login` failed with `no such file or directory` when `~/.config/substreams` + did not exist yet. The directory is now created before the token is written, and the token file is + written with mode `0600` instead of `0644` (an existing file is tightened on re-login). + - A manifest can now import `sf/substreams/sink/sql/schema/v1/schema.proto` without vendoring a copy of it. The file is a system protobuf, but `protoparse` needs the source on disk to honour its extensions, so an import previously failed with From ba5e450f049337836cd84c626d162e268d66964b Mon Sep 17 00:00:00 2001 From: 0xGabey Date: Fri, 11 Sep 2026 16:34:28 +0700 Subject: [PATCH 2/2] chore: bump grpc to v1.83.2 CVE-2026-84445 fails the Docker Scout gate on any PR branch. --- go.mod | 4 +--- go.sum | 4 ++-- tests_e2e/go.mod | 4 ++-- tests_e2e/go.sum | 8 ++++---- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 82b0784a3..de90a5570 100644 --- a/go.mod +++ b/go.mod @@ -103,7 +103,7 @@ require ( golang.org/x/mod v0.40.0 golang.org/x/net v0.58.0 golang.org/x/oauth2 v0.36.0 - google.golang.org/grpc v1.83.1 + google.golang.org/grpc v1.83.2 gopkg.in/yaml.v2 v2.4.0 ) @@ -267,7 +267,6 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.0 // indirect github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dlclark/regexp2 v1.11.5 // indirect github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect @@ -294,7 +293,6 @@ require ( github.com/olekukonko/tablewriter v1.1.4 github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/paulbellamy/ratecounter v0.2.0 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.70.1 // indirect github.com/prometheus/procfs v0.21.1 // indirect diff --git a/go.sum b/go.sum index b6d024af1..4ade6b608 100644 --- a/go.sum +++ b/go.sum @@ -999,8 +999,8 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.83.1 h1:HIO0+BEtBP6soyqvqC8sNUjZ7bTs+0hFQuFF+RAy++Y= -google.golang.org/grpc v1.83.1/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/tests_e2e/go.mod b/tests_e2e/go.mod index 5581f51bd..f42bd915f 100644 --- a/tests_e2e/go.mod +++ b/tests_e2e/go.mod @@ -12,7 +12,7 @@ require ( github.com/stretchr/testify v1.12.0 github.com/testcontainers/testcontainers-go v0.44.0 go.uber.org/zap v1.28.0 - google.golang.org/grpc v1.83.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.12 ) @@ -220,7 +220,7 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.55.0 // indirect + golang.org/x/crypto v0.56.0 // indirect golang.org/x/mod v0.40.0 // indirect golang.org/x/net v0.58.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect diff --git a/tests_e2e/go.sum b/tests_e2e/go.sum index 95fcdac75..b60a5958c 100644 --- a/tests_e2e/go.sum +++ b/tests_e2e/go.sum @@ -622,8 +622,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= -golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= +golang.org/x/crypto v0.56.0 h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y= +golang.org/x/crypto v0.56.0/go.mod h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 h1:SbTAbRFnd5kjQXbczszQ0hdk3ctwYf3qBNH9jIsGclE= @@ -776,8 +776,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.83.1 h1:HIO0+BEtBP6soyqvqC8sNUjZ7bTs+0hFQuFF+RAy++Y= -google.golang.org/grpc v1.83.1/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=