- Add API server with WebSocket support and REST endpoints - Implement authentication system with API keys and permissions - Add task queue system with Redis backend and error handling - Include storage layer with database migrations and schemas - Add comprehensive logging, metrics, and telemetry - Implement security middleware and network utilities - Add experiment management and container orchestration - Include configuration management with smart defaults
122 lines
3.6 KiB
Go
122 lines
3.6 KiB
Go
package auth
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// AuthFlags holds authentication-related command line flags
|
|
type AuthFlags struct {
|
|
APIKey string
|
|
APIKeyFile string
|
|
ConfigFile string
|
|
EnableAuth bool
|
|
ShowHelp bool
|
|
}
|
|
|
|
// ParseAuthFlags parses authentication command line flags
|
|
func ParseAuthFlags() *AuthFlags {
|
|
flags := &AuthFlags{}
|
|
|
|
flag.StringVar(&flags.APIKey, "api-key", "", "API key for authentication")
|
|
flag.StringVar(&flags.APIKeyFile, "api-key-file", "", "Path to file containing API key")
|
|
flag.StringVar(&flags.ConfigFile, "config", "", "Configuration file path")
|
|
flag.BoolVar(&flags.EnableAuth, "enable-auth", false, "Enable authentication")
|
|
flag.BoolVar(&flags.ShowHelp, "auth-help", false, "Show authentication help")
|
|
|
|
// Custom help flag that doesn't exit
|
|
flag.Usage = func() {}
|
|
|
|
flag.Parse()
|
|
|
|
return flags
|
|
}
|
|
|
|
// GetAPIKeyFromSources gets API key from multiple sources in priority order
|
|
func GetAPIKeyFromSources(flags *AuthFlags) string {
|
|
// 1. Command line flag (highest priority)
|
|
if flags.APIKey != "" {
|
|
return flags.APIKey
|
|
}
|
|
|
|
// 2. Explicit file flag
|
|
if flags.APIKeyFile != "" {
|
|
contents, readErr := os.ReadFile(flags.APIKeyFile)
|
|
if readErr == nil {
|
|
return strings.TrimSpace(string(contents))
|
|
}
|
|
log.Printf("Warning: Could not read API key file %s: %v", flags.APIKeyFile, readErr)
|
|
}
|
|
|
|
// 3. Environment variable
|
|
if envKey := os.Getenv("FETCH_ML_API_KEY"); envKey != "" {
|
|
return envKey
|
|
}
|
|
|
|
// 4. File-based key (for automated scripts)
|
|
if fileKey := os.Getenv("FETCH_ML_API_KEY_FILE"); fileKey != "" {
|
|
content, err := os.ReadFile(fileKey)
|
|
if err == nil {
|
|
return strings.TrimSpace(string(content))
|
|
}
|
|
log.Printf("Warning: Could not read API key file %s: %v", fileKey, err)
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
// ValidateAuthFlags validates parsed authentication flags
|
|
func ValidateAuthFlags(flags *AuthFlags) error {
|
|
if flags.ShowHelp {
|
|
PrintAuthHelp()
|
|
os.Exit(0)
|
|
}
|
|
|
|
if flags.APIKeyFile != "" {
|
|
if _, err := os.Stat(flags.APIKeyFile); err != nil {
|
|
return fmt.Errorf("api key file not found: %s", flags.APIKeyFile)
|
|
}
|
|
if err := CheckConfigFilePermissions(flags.APIKeyFile); err != nil {
|
|
log.Printf("Warning: %v", err)
|
|
}
|
|
}
|
|
|
|
// If config file is specified, check if it exists
|
|
if flags.ConfigFile != "" {
|
|
if _, err := os.Stat(flags.ConfigFile); err != nil {
|
|
return fmt.Errorf("config file not found: %s", flags.ConfigFile)
|
|
}
|
|
|
|
// Check file permissions
|
|
if err := CheckConfigFilePermissions(flags.ConfigFile); err != nil {
|
|
log.Printf("Warning: %v", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// PrintAuthHelp prints authentication-specific help
|
|
func PrintAuthHelp() {
|
|
fmt.Println("Authentication Options:")
|
|
fmt.Println(" --api-key <key> API key for authentication")
|
|
fmt.Println(" --api-key-file <path> Read API key from file")
|
|
fmt.Println(" --config <file> Configuration file path")
|
|
fmt.Println(" --enable-auth Enable authentication (if disabled)")
|
|
fmt.Println(" --auth-help Show this help")
|
|
fmt.Println()
|
|
fmt.Println("Environment Variables:")
|
|
fmt.Println(" FETCH_ML_API_KEY API key for authentication")
|
|
fmt.Println(" FETCH_ML_API_KEY_FILE File containing API key")
|
|
fmt.Println(" FETCH_ML_ENV Environment (development/production)")
|
|
fmt.Println(" FETCH_ML_ALLOW_INSECURE_AUTH Allow insecure auth (dev only)")
|
|
fmt.Println()
|
|
fmt.Println("Security Notes:")
|
|
fmt.Println(" - API keys in command line may be visible in process lists")
|
|
fmt.Println(" - Environment variables are preferred for automated scripts")
|
|
fmt.Println(" - File-based keys should have restricted permissions (600)")
|
|
fmt.Println(" - Authentication is mandatory in production environments")
|
|
}
|