envcrypt 0.2.0

Encrypt environment variables at compile-time and decrypt them at runtime.
Documentation

envcrypt

envcrypt on crates.io envcrypt on docs.rs envcrypt on deps.rs

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 envcrypt::envc;

let my_super_secret_key: String = envc!("SECRET_KEY");
// ...do stuff with your secret key

As a replacement for option_env!

use envcrypt::option_envc;

if let Some(optional_value) = option_envc!("OPTIONAL_SECRET_KEY") {
  // ...do stuff
}

With dotenvy:

.env:

CLIENT_SECRET="my_client_secret"
SOME_TOKEN="some_token"

build.rs:

use dotenvy::dotenv_iter;

fn main(){
 println!("cargo:rerun-if-changed=.env");

 for item in dotenv_iter().unwrap() {
   let (key, value) = item.unwrap();
   println!("cargo:rustc-env=${key}=${value}");
 }

}

main.rs:

use envcrypt::envc;

let client_secret: String = envc!("CLIENT_SECRET");

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.