Complete platform management workflows

This commit is contained in:
npc0-hue
2026-07-14 16:39:37 +08:00
parent 7e05d0a4e7
commit 4f33f761a3
106 changed files with 11313 additions and 460 deletions
+6
View File
@@ -22,6 +22,12 @@ type Config struct {
DisplayName string
Version string
RegistrationToken string
ServerInstanceID string
PluginID string
ComponentKind string
ComponentKey string
KeyGeneration int
SecretRef string
WorkspaceRoot string
SpoolRoot string
MaxJobs int
+248
View File
@@ -0,0 +1,248 @@
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
}
+141
View File
@@ -0,0 +1,141 @@
package config
import (
"encoding/json"
"os"
"path/filepath"
"strings"
"testing"
)
func TestLoadPackageConfigAppliesServerScopedIdentity(t *testing.T) {
path := writePackageConfig(t, PackageConfig{
Kind: PackageComponentRun,
ServerInstanceID: "server-1",
PluginID: "game.minecraft",
RunEndpointID: "run-server-1",
TargetOS: "linux",
TargetArch: "amd64",
SecretRef: "secret://runtime-keys/server-1/run/current",
KeyGeneration: 3,
AuthKey: "opaque-runtime-key",
})
pkg, err := LoadPackageConfig(path)
if err != nil {
t.Fatalf("load package config: %v", err)
}
cfg := ApplyPackageConfig(Config{RunEndpointID: DefaultEndpointID, DisplayName: DefaultDisplayName}, pkg)
if cfg.RegistrationToken != "opaque-runtime-key" || cfg.RunEndpointID != "run-server-1" || cfg.ServerInstanceID != "server-1" || cfg.KeyGeneration != 3 {
t.Fatalf("expected package identity to be applied, got %+v", cfg)
}
diagnostics := pkg.RedactedDiagnostics()
for _, value := range diagnostics {
if strings.Contains(value, "opaque-runtime-key") || strings.Contains(value, "/Users/") || strings.Contains(value, "password=") {
t.Fatalf("diagnostics exposed sensitive value: %+v", diagnostics)
}
}
if diagnostics["keyFingerprint"] == "" || diagnostics["secretRef"] != "secret://runtime-keys/server-1/run/current" {
t.Fatalf("expected redacted key fingerprint and secret ref, got %+v", diagnostics)
}
}
func TestLoadPackageConfigRejectsUnsafeOrIncompletePackages(t *testing.T) {
valid := PackageConfig{
Kind: PackageComponentRun,
ServerInstanceID: "server-1",
PluginID: "game.scum",
TargetOS: "windows",
TargetArch: "amd64",
SecretRef: "secret://runtime-keys/server-1/run/current",
KeyGeneration: 1,
AuthKey: "opaque-runtime-key",
}
cases := map[string]func(PackageConfig) PackageConfig{
"old zero generation": func(cfg PackageConfig) PackageConfig { cfg.KeyGeneration = 0; return cfg },
"raw path": func(cfg PackageConfig) PackageConfig { cfg.ServerInstanceID = "/Users/tasia/server"; return cfg },
"socket": func(cfg PackageConfig) PackageConfig { cfg.SecretRef = "unix:///tmp/run.sock"; return cfg },
"secret auth": func(cfg PackageConfig) PackageConfig { cfg.AuthKey = "password=raw"; return cfg },
"client missing key": func(cfg PackageConfig) PackageConfig { cfg.Kind = PackageComponentClientManager; return cfg },
}
for name, mutate := range cases {
if err := ValidatePackageConfig(mutate(valid)); err == nil {
t.Fatalf("expected %s package to be rejected", name)
}
}
}
func TestAuthenticatePackageGenerationRejectsStalePackages(t *testing.T) {
pkg := PackageConfig{
Kind: PackageComponentRun,
ServerInstanceID: "server-1",
PluginID: "game.minecraft",
TargetOS: "linux",
TargetArch: "amd64",
SecretRef: "secret://runtime-keys/server-1/run/current",
KeyGeneration: 1,
AuthKey: "opaque-runtime-key",
}
err := AuthenticatePackageGeneration(pkg, ComponentAuthResult{
ServerInstanceID: "server-1",
Kind: PackageComponentRun,
KeyGeneration: 2,
Allowed: true,
Reason: "current key accepted",
})
if err == nil || !strings.Contains(err.Error(), "generation") {
t.Fatalf("expected stale generation rejection, got %v", err)
}
err = AuthenticatePackageGeneration(pkg, ComponentAuthResult{
ServerInstanceID: "server-1",
Kind: PackageComponentRun,
KeyGeneration: 1,
Allowed: true,
Reason: "current key accepted",
})
if err != nil {
t.Fatalf("expected current generation to authenticate: %v", err)
}
}
func TestLoadPackageConfigFromEnv(t *testing.T) {
path := writePackageConfig(t, PackageConfig{
Kind: PackageComponentClientManager,
ServerInstanceID: "server-1",
PluginID: "game.scum",
ProfileKey: "scum-client-manager",
TargetOS: "windows",
TargetArch: "amd64",
SecretRef: "secret://runtime-keys/server-1/client-manager/scum-client-manager/current",
KeyGeneration: 4,
AuthKey: "opaque-client-key",
})
t.Setenv(PackageConfigEnv, path)
cfg, ok, err := LoadPackageConfigFromEnv()
if err != nil || !ok {
t.Fatalf("expected env package config, ok=%v err=%v", ok, err)
}
if cfg.Kind != PackageComponentClientManager || cfg.ProfileKey != "scum-client-manager" {
t.Fatalf("unexpected package config: %+v", cfg)
}
t.Setenv(PackageConfigEnv, "")
_, ok, err = LoadPackageConfigFromEnv()
if err != nil || ok {
t.Fatalf("expected no env package config, ok=%v err=%v", ok, err)
}
}
func writePackageConfig(t *testing.T, cfg PackageConfig) string {
t.Helper()
body, err := json.Marshal(cfg)
if err != nil {
t.Fatalf("marshal package config: %v", err)
}
path := filepath.Join(t.TempDir(), "run-package.json")
if err := os.WriteFile(path, body, 0o600); err != nil {
t.Fatalf("write package config: %v", err)
}
return path
}