Proposed change
Currently when using ConnectOptions::with_credentials_file, the passed credentials file will only be loaded once - during the with_credentials_file call - and then never again.
This means when credentials eventually become invalid (e.g. when exp claim in JWT was set), the client not be able to recover.
It is possible to workaround this problem via auth_callback, but it requires pulling a lot of extra dependencies and duplicating code that is already inside the crate:
static USER_CONFIG_RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"\s*(?:(?:[-]{3,}.*[-]{3,}\r?\n)([\w\-.=]+)(?:\r?\n[-]{3,}.*[-]{3,}\r?\n))")
.unwrap()
});
fn extract_jwt_and_nkey_from_creds(contents: &str) -> Option<(&str, &str)> {
let mut matches = USER_CONFIG_RE.captures_iter(contents);
let jwt_capture = matches.next()?;
let nkey_capture = matches.next()?;
Some((jwt_capture.get(1)?.as_str(), nkey_capture.get(1)?.as_str()))
}
async fn dynamic_credentials_file_auth(
creds_path: impl AsRef<Path>,
nonce: Vec<u8>,
) -> std::result::Result<Auth, AuthError> {
let contents = read_to_string(creds_path).await.map_err(AuthError::new)?;
let (jwt, nkey) = extract_jwt_and_nkey_from_creds(&contents)
.ok_or_else(|| AuthError::new("creds file not in a valid format"))?;
let kp = KeyPair::from_seed(nkey).map_err(AuthError::new)?;
let signed_nonce = kp.sign(&nonce).map_err(AuthError::new)?;
let mut auth = Auth::new();
auth.jwt = Some(jwt.to_owned());
auth.signature = Some(signed_nonce);
Ok(auth)
}
pub async fn connect_to_nats_refresh() -> Client {
let opts = ConnectOptions::with_auth_callback(move |nonce| {
async move { dynamic_credentials_file_auth("/tmp/nats.creds", nonce).await }
});
opts.connect("nats://localhost:4222").await.unwrap()
}
Use case
Allow credential rotation without requiring full application restart.
This is fully supported in other NATS SDKs (at least with the ones I tested: Go, NodeJS, Java and the old non-async Rust crate).
Contribution
No response
Proposed change
Currently when using
ConnectOptions::with_credentials_file, the passed credentials file will only be loaded once - during thewith_credentials_filecall - and then never again.This means when credentials eventually become invalid (e.g. when
expclaim in JWT was set), the client not be able to recover.It is possible to workaround this problem via
auth_callback, but it requires pulling a lot of extra dependencies and duplicating code that is already inside the crate:Use case
Allow credential rotation without requiring full application restart.
This is fully supported in other NATS SDKs (at least with the ones I tested: Go, NodeJS, Java and the old non-async Rust crate).
Contribution
No response