package hub import ( "encoding/base64" "fmt" "strings" "github.com/henrygd/beszel/internal/hub/utils" "golang.org/x/crypto/ssh" ) // GetSSHKeyFromEnv loads the hub SSH private key from environment variables. // SSH_PRIVATE_KEY_B64 should contain a base64-encoded PEM private key. // SSH_PRIVATE_KEY may contain the raw PEM text for platforms that support // multiline secrets. func (h *Hub) GetSSHKeyFromEnv() (ssh.Signer, bool, error) { raw, exists := utils.GetEnv("SSH_PRIVATE_KEY_B64") if exists && strings.TrimSpace(raw) != "" { decoded, err := base64.StdEncoding.DecodeString(strings.TrimSpace(raw)) if err != nil { return nil, true, fmt.Errorf("failed to decode SSH_PRIVATE_KEY_B64: %w", err) } return h.setSSHPrivateKey(decoded) } raw, exists = utils.GetEnv("SSH_PRIVATE_KEY") if !exists || strings.TrimSpace(raw) == "" { return nil, false, nil } return h.setSSHPrivateKey([]byte(raw)) } func (h *Hub) setSSHPrivateKey(privateKey []byte) (ssh.Signer, bool, error) { signer, err := ssh.ParsePrivateKey(privateKey) if err != nil { return nil, true, fmt.Errorf("failed to parse configured hub SSH private key: %w", err) } pubKeyBytes := ssh.MarshalAuthorizedKey(signer.PublicKey()) h.signer = signer h.pubKey = strings.TrimSuffix(string(pubKeyBytes), "\n") h.Logger().Info("hub SSH key loaded from environment") return signer, true, nil }