envcrypt
Drop-in replacements for env!
and option_env!
that encrypt your variables at compile-time and decrypt them at runtime.
While it's still possible to reverse-engineer the values, envcrypt
prevents
strings <my-binary>
from trivially finding embedded secrets.
Since the secret must be decrypted at runtime,
envc!
returns an owned String
instead of &'static str
. Its API otherwise mirrors env!
and option_env!
.
Usage
The envc!
and option_envc!
macros can be used as drop-in replacements for env!
and option_env!
, respectively.
As a replacement for env!
use envc;
let my_super_secret_key: String = envc!;
// ...do stuff with your secret key
As a replacement for option_env!
use option_envc;
if let Some = option_envc!
With dotenvy
:
.env
:
CLIENT_SECRET="my_client_secret"
SOME_TOKEN="some_token"
build.rs
:
use dotenv_iter;
main.rs
:
use envc;
let client_secret: String = envc!;
Details
Encryption is powered by magic_crypt
using AES-256 encryption. envcrypt
encrypts an environment variable, and then embeds the encrypted variable along with the encryption key and initialization vector in your binary at runtime.
You can check for yourself that your secrets are not visible in the binary by running strings
on the compiled output:
$ cat envcrypt-test/src/main.rs
use envcrypt::envc;
fn main() {
println!("{}", envc!("ENCRYPTED_KEY"));
println!("{}", env!("NAKED_KEY"));
}
$ cat envcrypt-test/build.rs
fn main() {
println!("cargo:rustc-env=ENCRYPTED_KEY=ENCRYPTED_VALUE");
println!("cargo:rustc-env=NAKED_KEY=NAKED_VALUE");
}
$ cargo build -p envcrypt-test
Compiling envcrypt v0.2.0 (path/to/envcrypt)
Compiling envcrypt-test v0.0.0 (path/to/envcrypt/envcrypt-test)
Finished dev [unoptimized + debuginfo] target(s) in 1.73s
$ strings - target/debug/envcrypt-test | rg VALUE
NAKED_VALUE
Here are instructions for running strings
yourself on MacOS, Linux, and Windows.
Inspired by litcrypt
, which I would have used except I want to open-source my code.
Dual-Licensed under MIT or APACHE-2.0.