Volt CLI: source-available under AGPSL v5.0

Complete infrastructure platform CLI:
- Container runtime (systemd-nspawn)
- VoltVisor VMs (Neutron Stardust / QEMU)
- Stellarium CAS (content-addressed storage)
- ORAS Registry
- GitOps integration
- Landlock LSM security
- Compose orchestration
- Mesh networking

Copyright (c) Armored Gates LLC. All rights reserved.
Licensed under AGPSL v5.0
This commit is contained in:
Karl Clinger
2026-03-21 00:30:23 -05:00
commit 81ad0b597c
106 changed files with 35984 additions and 0 deletions

69
pkg/validate/validate.go Normal file
View File

@@ -0,0 +1,69 @@
// Package validate provides shared input validation for all Volt components.
// Every CLI command and API endpoint should validate user input through these
// functions before using names in file paths, systemd units, or shell commands.
package validate
import (
"fmt"
"regexp"
"strings"
)
// nameRegex allows lowercase alphanumeric, hyphens, underscores, and dots.
// Must start with a letter or digit. Max 64 chars.
var nameRegex = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$`)
// WorkloadName validates a workload/container/VM name.
// Names are used in file paths, systemd unit names, and network identifiers,
// so they must be strictly validated to prevent path traversal, injection, etc.
//
// Rules:
// - 1-64 characters
// - Alphanumeric, hyphens, underscores, dots only
// - Must start with a letter or digit
// - No path separators (/, \)
// - No whitespace
// - No shell metacharacters
func WorkloadName(name string) error {
if name == "" {
return fmt.Errorf("name cannot be empty")
}
if len(name) > 64 {
return fmt.Errorf("name too long (%d chars, max 64)", len(name))
}
if !nameRegex.MatchString(name) {
return fmt.Errorf("invalid name %q: must be alphanumeric with hyphens, underscores, or dots, starting with a letter or digit", name)
}
// Extra safety: reject anything with path components
if strings.Contains(name, "/") || strings.Contains(name, "\\") || strings.Contains(name, "..") {
return fmt.Errorf("invalid name %q: path separators and '..' not allowed", name)
}
return nil
}
// BridgeName validates a network bridge name.
// Linux interface names are max 15 chars, alphanumeric + hyphens.
func BridgeName(name string) error {
if name == "" {
return fmt.Errorf("bridge name cannot be empty")
}
if len(name) > 15 {
return fmt.Errorf("bridge name too long (%d chars, max 15 for Linux interfaces)", len(name))
}
if !regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9-]*$`).MatchString(name) {
return fmt.Errorf("invalid bridge name %q: must start with a letter, alphanumeric and hyphens only", name)
}
return nil
}
// SafePath checks that a constructed path stays within the expected base directory.
// Use this after filepath.Join to prevent traversal.
func SafePath(base, constructed string) error {
// Clean both paths for comparison
cleanBase := strings.TrimRight(base, "/") + "/"
cleanPath := constructed + "/"
if !strings.HasPrefix(cleanPath, cleanBase) {
return fmt.Errorf("path %q escapes base directory %q", constructed, base)
}
return nil
}