nats-io / nats.net.v1

The official C# Client for NATS
Apache License 2.0
646 stars 154 forks source link

Ability to create connection with string credentials instead of from a file #882

Closed schoetbi closed 5 months ago

schoetbi commented 5 months ago

Proposed change

The current implementation expects a file name for the credentials. This requires the file to be on disk, what makes it readable by others.

A workaround is the use of the handlers Options.UserJWTEventHandler and Options.UserSignatureEventHandler but this is not straightforward.

I propose that the credentials are transported as a SecureString so that it can be read e.g. from the Windows Data Protection API or directly from a key vault like Azure key vault.

So this is the method signature:

/// <param name="credentials">The content of the chained credentials file.</param>
public IConnection CreateConnection(string url, SecureString credentials, bool reconnectOnConnect = false)

Use case

I do not want to store the credentials unencrypted on disk

Contribution

No response

scottf commented 5 months ago

@schoetbi I can't do this because of the language level of the project. Any chance you have a greenfield project? If so I would suggest using the .NET v2. Everything else underneath is insecure, but I can offer these, that way you can use SecureString and present the credentials from memory as strings instead of need a file.

public IConnection CreateConnection(string url, string credentials, bool reconnectOnConnect = false)
public IConnection CreateConnection(string url, string userJwt, string nkeySeed, bool reconnectOnConnect = false)

WDYT?

schoetbi commented 5 months ago

@scottf Yes, I can use .NET v2 for my project. The main priority is that I want to avoid writing the credentials to disk. The use of SecureString is optional. So your suggestion with passing the credentials as string (not filename) is fine.

sixlettervariables commented 5 months ago

In general you should not use SecureString for new development, and even when available it does not adequately protect confidential information.

https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-security-securestring

schoetbi commented 5 months ago

@sixlettervariables Thanks for this interesting read. The use of SecureString might also be a little bit too much for my thread model. I only want to ensure that the credentials are not written to disk. So I will refrain from the use of SecureString.

scottf commented 5 months ago

Adding regular string version of the api here: https://github.com/nats-io/nats.net/pull/885