Secret does the best to avoid leaking information in memory and in the code BUT an attack is possible and I don't give any certainties or guarantees about security using this class, you use it at your own risk. Code is open source, you can check the implementation and take your decision consciously. I'll do my best to improve the security and documentation of this class.
Obfuscation
The value is obfuscated when creating the Secret instance using an implicit Obfuserwhich, by default, transform the value into a xor-ed ByteBuffer witch store bytes outside the JVM using direct memory access.
The obfuscated value is de-obfuscated using an implicit DeObfuser instance every time the method use is invoked which returns the original value converting bytes back to T re-apply the xor.
API and Type safety
While obfuscating the value prevents or at least makes it harder to read the value from memory, Secret class API is designed to avoid leaking information in other ways. Preventing developers to improperly use the secret value ( logging, etc...).
Example
val secretString: Secret[String] = Secret("my_password")
val database: F[Database] = secretString.use(password => initDb(password))
Destroy the secret value by filling the obfuscated value with '\0'.
Destroy the secret value by filling the obfuscated value with '\0'.
This method is idempotent.
Once the secret is destroyed it can't be used anymore. If you try to use it using use, useAndDestroy, evalUse, evalUseAndDestroy and other methods, it will raise a NoLongerValidSecret exception.
Apply f with the de-obfuscated value WITHOUT destroying it.
Apply f with the de-obfuscated value WITHOUT destroying it.
If the secret is destroyed it will raise a NoLongerValidSecret exception.
Once the secret is destroyed it can't be used anymore. If you try to use it using use, useAndDestroy, evalUse, evalUseAndDestroy and other methods, it will raise a NoLongerValidSecret exception.
Apply f with the de-obfuscated value and then destroy the secret value by invoking destroy method.
Apply f with the de-obfuscated value and then destroy the secret value by invoking destroy method.
Once the secret is destroyed it can't be used anymore. If you try to use it using use, useAndDestroy, evalUse, evalUseAndDestroy and other methods, it will raise a NoLongerValidSecret exception.
Avoid this method if possible. Unsafely apply f with the de-obfuscated value WITHOUT destroying it.
Avoid this method if possible. Unsafely apply f with the de-obfuscated value WITHOUT destroying it.
If the secret is destroyed it will raise a NoLongerValidSecret exception.
Throws SecretNoLongerValid if the secret is destroyed
Attributes
final def use[F[_] : ([F] =>> MonadError[F, _ >: SecretNoLongerValid]), U](f: T => U)(implicit evidence$5: MonadSecretError[F], deObfuser: DeObfuser[T]): F[U]
Apply f with the de-obfuscated value WITHOUT destroying it.
Apply f with the de-obfuscated value WITHOUT destroying it.
If the secret is destroyed it will raise a NoLongerValidSecret exception.
Once the secret is destroyed it can't be used anymore. If you try to use it using use, useAndDestroy, evalUse, evalUseAndDestroy and other methods, it will raise a NoLongerValidSecret exception.
Attributes
final def useAndDestroy[F[_] : ([F] =>> MonadError[F, _ >: SecretNoLongerValid]), U](f: T => U)(implicit evidence$6: MonadSecretError[F], deObfuser: DeObfuser[T]): F[U]
Apply f with the de-obfuscated value and then destroy the secret value by invoking destroy method.
Apply f with the de-obfuscated value and then destroy the secret value by invoking destroy method.
Once the secret is destroyed it can't be used anymore. If you try to use it using use, useAndDestroy, evalUse, evalUseAndDestroy and other methods, it will raise a NoLongerValidSecret exception.