package ingress import ( "bytes" "encoding/base64" "encoding/json" "errors" "io" "os" ) type keyDocument struct { Version int `json:"version"` Keys []struct { KeyID string `json:"key_id"` ProducerID string `json:"producer_id"` Secret string `json:"secret_base64url"` } `json:"keys"` } type Key struct { ProducerID string Secret []byte } func LoadKeys(path string) (map[string]Key, error) { raw, err := os.ReadFile(path) if err != nil { return nil, errors.New("read Bell event ingress key file") } var document keyDocument decoder := json.NewDecoder(bytes.NewReader(raw)) decoder.DisallowUnknownFields() if err := decoder.Decode(&document); err != nil || document.Version != 1 || len(document.Keys) == 0 { return nil, errors.New("invalid Bell event ingress key file") } var trailing any if err := decoder.Decode(&trailing); !errors.Is(err, io.EOF) { return nil, errors.New("invalid Bell event ingress key file") } values := make(map[string]Key, len(document.Keys)) for _, item := range document.Keys { secret, err := base64.RawURLEncoding.DecodeString(item.Secret) if err != nil || !keyIDPattern.MatchString(item.KeyID) || !producerIDPattern.MatchString(item.ProducerID) || len(secret) < 32 { return nil, errors.New("invalid Bell event ingress key") } if _, exists := values[item.KeyID]; exists { return nil, errors.New("duplicate Bell event ingress key ID") } values[item.KeyID] = Key{ProducerID: item.ProducerID, Secret: append([]byte(nil), secret...)} } return values, nil }