package config import ( "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "os" "strings" ) const ( PackageComponentRun = "run" PackageComponentClientManager = "client-manager" PackageConfigEnv = "RUN_PACKAGE_CONFIG" ) type PackageConfig struct { Kind string `json:"kind"` ServerInstanceID string `json:"serverInstanceId"` PluginID string `json:"pluginId"` RunEndpointID string `json:"runEndpointId,omitempty"` ProfileKey string `json:"profileKey,omitempty"` TargetOS string `json:"targetOs"` TargetArch string `json:"targetArch"` SecretRef string `json:"secretRef"` KeyGeneration int `json:"keyGeneration"` AuthKey string `json:"authKey"` } type PackageIdentity struct { Kind string `json:"kind"` ServerInstanceID string `json:"serverInstanceId"` PluginID string `json:"pluginId"` RunEndpointID string `json:"runEndpointId,omitempty"` ProfileKey string `json:"profileKey,omitempty"` TargetOS string `json:"targetOs"` TargetArch string `json:"targetArch"` SecretRef string `json:"secretRef"` KeyGeneration int `json:"keyGeneration"` KeyFingerprint string `json:"keyFingerprint"` } type ComponentAuthResult struct { ServerInstanceID string Kind string ProfileKey string KeyGeneration int Allowed bool Reason string } func LoadPackageConfig(path string) (PackageConfig, error) { body, err := os.ReadFile(path) if err != nil { return PackageConfig{}, fmt.Errorf("read run package config: %w", err) } var cfg PackageConfig if err := json.Unmarshal(body, &cfg); err != nil { return PackageConfig{}, fmt.Errorf("decode run package config: %w", err) } if err := ValidatePackageConfig(cfg); err != nil { return PackageConfig{}, err } return cfg, nil } func LoadPackageConfigFromEnv() (PackageConfig, bool, error) { path := strings.TrimSpace(os.Getenv(PackageConfigEnv)) if path == "" { return PackageConfig{}, false, nil } cfg, err := LoadPackageConfig(path) return cfg, true, err } func ValidatePackageConfig(cfg PackageConfig) error { var violations []string if cfg.Kind != PackageComponentRun && cfg.Kind != PackageComponentClientManager { violations = append(violations, "kind is invalid") } if !safeIdentifier(cfg.ServerInstanceID) { violations = append(violations, "serverInstanceId is invalid") } if !safePluginID(cfg.PluginID) { violations = append(violations, "pluginId is invalid") } if cfg.RunEndpointID != "" && !safeIdentifier(cfg.RunEndpointID) { violations = append(violations, "runEndpointId is invalid") } if cfg.ProfileKey != "" && !safeLogicalKey(cfg.ProfileKey) { violations = append(violations, "profileKey is invalid") } if cfg.Kind == PackageComponentClientManager && cfg.ProfileKey == "" { violations = append(violations, "profileKey is required for client-manager packages") } if !safeRuntimeTarget(cfg.TargetOS, cfg.TargetArch) { violations = append(violations, "target platform is invalid") } if !strings.HasPrefix(cfg.SecretRef, "secret://runtime-keys/") || containsUnsafeDiagnosticText(cfg.SecretRef) { violations = append(violations, "secretRef is invalid") } if cfg.KeyGeneration <= 0 { violations = append(violations, "keyGeneration must be positive") } if strings.TrimSpace(cfg.AuthKey) == "" { violations = append(violations, "authKey is required") } if containsUnsafeDiagnosticText(cfg.AuthKey) { violations = append(violations, "authKey contains unsafe content") } if len(violations) > 0 { return fmt.Errorf("invalid run package config: %s", strings.Join(violations, "; ")) } return nil } func ApplyPackageConfig(base Config, pkg PackageConfig) Config { base.RegistrationToken = pkg.AuthKey base.ServerInstanceID = pkg.ServerInstanceID base.PluginID = pkg.PluginID base.ComponentKind = pkg.Kind base.ComponentKey = pkg.ProfileKey base.KeyGeneration = pkg.KeyGeneration base.SecretRef = pkg.SecretRef if pkg.RunEndpointID != "" { base.RunEndpointID = pkg.RunEndpointID } if base.DisplayName == "" || base.DisplayName == DefaultDisplayName { base.DisplayName = "Run " + pkg.ServerInstanceID } return base } func (cfg PackageConfig) Identity() PackageIdentity { return PackageIdentity{ Kind: cfg.Kind, ServerInstanceID: cfg.ServerInstanceID, PluginID: cfg.PluginID, RunEndpointID: cfg.RunEndpointID, ProfileKey: cfg.ProfileKey, TargetOS: cfg.TargetOS, TargetArch: cfg.TargetArch, SecretRef: cfg.SecretRef, KeyGeneration: cfg.KeyGeneration, KeyFingerprint: fingerprint(cfg.AuthKey), } } func (cfg PackageConfig) RedactedDiagnostics() map[string]string { identity := cfg.Identity() return map[string]string{ "kind": identity.Kind, "serverInstanceId": identity.ServerInstanceID, "pluginId": identity.PluginID, "runEndpointId": identity.RunEndpointID, "profileKey": identity.ProfileKey, "target": identity.TargetOS + "/" + identity.TargetArch, "secretRef": identity.SecretRef, "keyGeneration": fmt.Sprintf("%d", identity.KeyGeneration), "keyFingerprint": identity.KeyFingerprint, } } func AuthenticatePackageGeneration(pkg PackageConfig, auth ComponentAuthResult) error { if err := ValidatePackageConfig(pkg); err != nil { return err } if auth.ServerInstanceID != pkg.ServerInstanceID || auth.Kind != pkg.Kind || auth.ProfileKey != pkg.ProfileKey { return fmt.Errorf("component authentication scope does not match package") } if !auth.Allowed { return fmt.Errorf("component authentication rejected: %s", redactedReason(auth.Reason)) } if auth.KeyGeneration != pkg.KeyGeneration { return fmt.Errorf("component key generation is no longer current") } return nil } func fingerprint(value string) string { sum := sha256.Sum256([]byte(value)) return hex.EncodeToString(sum[:])[:12] } func safeIdentifier(value string) bool { value = strings.TrimSpace(value) if value == "" || len(value) > 120 || containsUnsafeDiagnosticText(value) { return false } for _, char := range value { if (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9') || char == '_' || char == '-' || char == '.' { continue } return false } return true } func safePluginID(value string) bool { return strings.HasPrefix(value, "game.") && safeIdentifier(value) } func safeLogicalKey(value string) bool { value = strings.TrimSpace(value) if value == "" || len(value) > 120 || strings.HasPrefix(value, "/") || strings.Contains(value, "..") || strings.Contains(value, `\`) || containsUnsafeDiagnosticText(value) { return false } for _, char := range value { if (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9') || char == '_' || char == '-' || char == '.' || char == '/' { continue } return false } return true } func safeRuntimeTarget(osName string, arch string) bool { switch osName { case "windows", "linux", "darwin": default: return false } switch arch { case "amd64", "arm64": return true default: return false } } func containsUnsafeDiagnosticText(value string) bool { normalized := strings.ToLower(value) for _, marker := range []string{"/users/", "/.ssh/", "password=", "apikey", "api_key", "bearer ", "sk-", "unix://", "tcp://", "mysql://", "sqlite://"} { if strings.Contains(normalized, marker) { return true } } return false } func redactedReason(value string) string { if containsUnsafeDiagnosticText(value) { return "[redacted]" } return value }