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}");
}
}
}