namespace Robotico.Nexus.Client; /// /// Per-connection TLS/mTLS material for a Nexus machine credential. Uses the same environment /// variable names as Mishima.Nexus.Wire.Clients.WireTlsMaterial (POLA) without depending on /// that assembly — see docs/adr/0001-nexus-client-monolith.adoc. /// public sealed class NexusTlsMaterial { /// Creates material with required PEM paths. public NexusTlsMaterial(string caCertificateFile, string clientCertificateFile, string clientKeyFile, bool useHttps = true) { ArgumentException.ThrowIfNullOrWhiteSpace(caCertificateFile); ArgumentException.ThrowIfNullOrWhiteSpace(clientCertificateFile); ArgumentException.ThrowIfNullOrWhiteSpace(clientKeyFile); CaCertificateFile = Path.GetFullPath(caCertificateFile.Trim()); ClientCertificateFile = Path.GetFullPath(clientCertificateFile.Trim()); ClientKeyFile = Path.GetFullPath(clientKeyFile.Trim()); UseHttps = useHttps; } /// CA PEM used to trust the Nexus server certificate. public string CaCertificateFile { get; } /// Client certificate PEM (machine credential). public string ClientCertificateFile { get; } /// Client private key PEM. public string ClientKeyFile { get; } /// When true, dial https:// gRPC. public bool UseHttps { get; } /// /// Loads material from process env: NEXUS_TLS_CA_FILE, NEXUS_TLS_CLIENT_CERT_FILE, /// NEXUS_TLS_CLIENT_KEY_FILE, optional NEXUS_TLS_MODE (defaults to https). /// Returns when the required files are absent (insecure/dev connection). /// public static NexusTlsMaterial? TryFromEnvironment() { string? ca = Environment.GetEnvironmentVariable("NEXUS_TLS_CA_FILE"); string? cert = Environment.GetEnvironmentVariable("NEXUS_TLS_CLIENT_CERT_FILE"); string? key = Environment.GetEnvironmentVariable("NEXUS_TLS_CLIENT_KEY_FILE"); string mode = Environment.GetEnvironmentVariable("NEXUS_TLS_MODE") ?? string.Empty; bool https = string.IsNullOrWhiteSpace(mode) || string.Equals(mode, "https", StringComparison.OrdinalIgnoreCase); if (string.IsNullOrWhiteSpace(ca) || string.IsNullOrWhiteSpace(cert) || string.IsNullOrWhiteSpace(key) || !File.Exists(ca) || !File.Exists(cert) || !File.Exists(key)) { return null; } return new NexusTlsMaterial(ca, cert, key, https); } /// Validates that all files exist. public void EnsureFilesExist() { if (!File.Exists(CaCertificateFile)) { throw new InvalidOperationException($"CA file not found: {CaCertificateFile}"); } if (!File.Exists(ClientCertificateFile)) { throw new InvalidOperationException($"Client cert not found: {ClientCertificateFile}"); } if (!File.Exists(ClientKeyFile)) { throw new InvalidOperationException($"Client key not found: {ClientKeyFile}"); } } }