Live video on the AT Protocol
at eli/nonfatal-errors 52 lines 1.4 kB view raw
1package statedb 2 3import ( 4 "context" 5 "crypto/rand" 6 "encoding/json" 7 "fmt" 8 9 "github.com/lestrrat-go/jwx/v2/jwk" 10 "stream.place/streamplace/pkg/log" 11) 12 13// EnsureServiceAuthKey ensures a shared symmetric key exists in the config table 14// for intra-service JWT authentication. All nodes sharing the same database will 15// use the same key, enabling mutual authentication within a station. 16func (state *StatefulDB) EnsureServiceAuthKey(ctx context.Context) (jwk.Key, error) { 17 conf, err := state.GetConfig("service-auth-key") 18 if err != nil { 19 return nil, fmt.Errorf("failed to get service auth key: %w", err) 20 } 21 22 if conf != nil { 23 key, err := jwk.ParseKey(conf.Value) 24 if err != nil { 25 return nil, fmt.Errorf("failed to parse service auth key: %w", err) 26 } 27 return key, nil 28 } 29 30 log.Warn(ctx, "no service auth key found, generating new one") 31 32 secret := make([]byte, 32) 33 if _, err := rand.Read(secret); err != nil { 34 return nil, fmt.Errorf("failed to generate random bytes: %w", err) 35 } 36 37 key, err := jwk.FromRaw(secret) 38 if err != nil { 39 return nil, fmt.Errorf("failed to create symmetric key: %w", err) 40 } 41 42 b, err := json.Marshal(key) 43 if err != nil { 44 return nil, fmt.Errorf("failed to marshal service auth key: %w", err) 45 } 46 47 if err := state.PutConfig("service-auth-key", b); err != nil { 48 return nil, fmt.Errorf("failed to save service auth key: %w", err) 49 } 50 51 return key, nil 52}