I have a struct containing general config data for a web application:
#[derive(Debug)]
pub struct AppConfig {
pub db_host: String,
pub timeout: Duration,
pub jwt_signing_key: String,
// more fields
}
jwt_signing_key
is a symmetric jwt secret, so much be kept confidential/
This works fine, but I would like to be able to log the contents of an AppConfig
for debugging purposes without the JWT secret appearing in logs. Ideally, it would return something along the lines of:
AppConfig {
db_host: "https://blah"
jwt_signing_key: "**********" // key obfuscated
}
One option is to create a thin wrapper:
pub struct AppConfig {
// ...
pub jwt_signing_key: JwtSigningKey,
}
pub struct JwtSigningKey(String);
// custom implementation of Debug
But this would require a large-ish refactor and adds an unnecessary (in my opinion) layer of indirection. (I'm not worried about the performance, but more the code noise)
AppConfig
is relatively large and maintaining a manual Debug
implementation is extra work I'd rather not have to do every time I want to add a field.
Is there an easier solution?
One option is to create a thin wrapper:
pub struct AppConfig { // ... pub jwt_signing_key: JwtSigningKey, } pub struct JwtSigningKey(String); // custom implementation of Debug
I think you should go with this option. The advantage it has is that no matter where in your application the value ends up, it will never be accidentally printed — or used in any other way — without explicitly unwrapping it, whereas replacing Debug
of the AppConfig
struct will only assist with that one particular case. It's robust against mistakes made while refactoring, too.
The type doesn't have to be so specific as JwtSigningKey
; it could be just pub struct Secret<T>(T);
and support any kind of secrets you end up working with. There are even libraries to provide such a type (see this thread for comments comparing two of them) which add more features like zeroing the memory when dropped (so that it's less likely that any accidental leak of memory contents might reveal a secret).