
enject: Nascondi i segreti .env dagli occhi indiscreti: i segreti risiedono in archivi crittografati locali (per progetto) e vengono iniettati direttamente nelle app in fase di esecuzione, senza mai toccare il disco come testo in chiaro.
Nascondi i segreti del tuo .env dagli occhi delle AI.
(Nota: questo progetto in precedenza si chiamava enveil ed è stato rinominato in enject)
Strumenti di AI per la scrittura di codice come Claude Code, Copilot, Cursor e altri possono leggere i file nella directory del tuo progetto, il che significa che un file .env in chiaro è un dump di segreti accidentale in attesa di accadere. Non è teorico. È un problema noto che mi è successo diverse volte (anche dopo aver detto esplicitamente a Claude di non sbirciare nel file settings.json di Claude Code). enject risolve a questo garantendo che i segreti in chiaro non esistano mai su disco. Il tuo file .env contiene solo riferimenti simbolici; i valori reali risiedono in un archivio locale crittografato e vengono iniettati direttamente nel tuo sottoprocesso all'avvio.
Questo progetto è ispirato alla soluzione / articolo del blog di Filip Hric, che utilizza un concetto simile basato su 1Password. Volevo una soluzione autonoma che non dipendesse da servizi di terze parti, da cui è nata questa soluzione. E sì, questo progetto è stato costruito quasi interamente con Claude Code con un sacco di verifica manuale e test.
Questo progetto è progettato principalmente per mitigare il problema noto degli strumenti AI/LLM che leggono accidentalmente i segreti del tuo .env. Vantaggi aggiuntivi includono la prevenzione della fuga di segreti se un .env viene accidentalmente committato in un repository, la possibilità di condividere file .env contenenti riferimenti invece di segreti in chiaro, e l'opzione di condividere l'archivio crittografato stesso.
Questo progetto non è un proiettile d'argento per impedire a un agente AI di ottenere i tuoi segreti. Ad esempio, un agente può comunque scrivere codice (per errore o tramite injection di prompt) che esfiltra segreti nell'output del terminale o in un file in fase di esecuzione. Sconsigliamo vivamente di fare affidamento su questo strumento, o sui file .env in generale, per memorizzare segreti di produzione.
Il tuo file .env appare così:
DATABASE_URL=en://database_url
STRIPE_KEY=en://stripe_key
PORT=3000
Tecnicamente è sicuro da committare (anche se forse è meglio non farlo), e soprattutto: sicuro per qualsiasi strumento AI che accidentalmente (o forse non così accidentalmente) vi sbirci dentro.
Quando esegui enject run -- npm start, questo:
en:// nella mappa decrittografataIl file dell'archivio è un blob binario. Senza la password principale, è indistinguibile da rumore casuale. Il nonce viene generato fresco a ogni scrittura, quindi il riutilizzo del nonce AES-GCM è impossibile. Qualsiasi modifica al testo cifrato — anche un singolo bit capovolto — causa il fallimento dell'autenticazione e la decrittografia viene rifiutata.
Questa versione è ancora in alpha, quindi richiede di aggiungere la versione più recente all'installazione quando si chiama cargo install
cargo install enject --version 0.2.0-alpha
Richiede Rust 1.70+.
git clone https://github.com/greatscott/enject
cd enject
cargo build --release
Il binario compilato si trova in target/release/enject. Installalo una volta in una posizione nel tuo PATH in modo da poterlo eseguire da qualsiasi progetto:
macOS / Linux (bash o zsh)
# Opzione A: ~/.local/bin (non richiede sudo, comune su Linux)
mkdir -p ~/.local/bin
cp target/release/enject ~/.local/bin/
# Opzione B: /usr/local/bin (richiede sudo, disponibile a livello di sistema)
sudo cp target/release/enject /usr/local/bin/
# Opzione C: ~/.cargo/bin (già nel PATH se hai usato rustup)
cp target/release/enject ~/.cargo/bin/
Se hai usato l'opzione A e ~/.local/bin non è già nel tuo PATH, aggiungi questa riga alla configurazione della tua shell (~/.zshrc, ~/.bashrc o ~/.bash_profile):
export PATH="$HOME/.local/bin:$PATH"
Poi ricaricala:
source ~/.zshrc # o ~/.bashrc
Verifica che funzioni:
enject --version
Il binario è installato globalmente — non devi mai reinstallarlo. Ma ogni progetto ha il proprio archivio crittografato:
cd your-project
enject init
Questo crea .enject/ nella directory corrente con la configurazione del progetto e l'archivio crittografato. Aggiungilo a .gitignore — non dovrebbe mai essere committato.
Esegui questo una volta per progetto, nella root del progetto:
enject init
Questo genera un sale casuale di 32 byte, scrive .enject/config.toml, crea un archivio crittografato vuoto in .enject/store e ti chiede di impostare una password principale. Aggiungi .enject/ al tuo .gitignore — l'archivio non dovrebbe mai essere committato.
enject set some_database_url
# richiede: Valore per 'database_url': (nascosto)
enject set some_api_key
I valori vengono sempre inseriti in modo interattivo. Non c'è modo di passare un valore come argomento della riga di comando — questo impedisce ai segreti di apparire nella cronologia della shell o nell'output di ps.
.envDATABASE_URL=en://some_database_url
MY_API_KEY=en://stripe_key
PORT=3000
Le righe CHIAVE=VALORE semplici vengono passate invariate. Solo i riferimenti en:// vengono risolti.
enject run -- npm start
enject run -- python manage.py runserver
enject run -- cargo run
Tutto ciò che viene dopo -- viene passato letteralmente al sistema operativo. Il sottoprocesso eredita il tuo ambiente shell completo (quindi PATH, HOME, ecc. sono presenti) con i valori di .env sovrapposti.
enject list # stampa i nomi delle chiavi memorizzate (mai i valori)
enject delete <key> # rimuove un segreto
enject import <file> # crittografa tutti i valori in un .env in chiaro, lo riscrive come template en://
enject rotate # ricrittografa l'archivio con una nuova password principale
Non esiste get né export. Stampare un valore segreto su stdout crea un vettore di fuga leggibile dall'AI — l'intero scopo di enject è mantenere i valori fuori dal disco e da qualsiasi flusso di output leggibile.
Ogni invariante di sicurezza ha un corrispondente test automatizzato e un percorso di ispezione manuale.
cargo test
31 test, tutti che coprono le affermazioni seguenti.
Automatizzato: store::password::tests::test_encrypt_decrypt_roundtrip
Salva un segreto, persiste l'archivio, lo ricarica dal disco, lo decrittografa e verifica che il valore sia corretto. Funziona solo se i byte su disco sono testo cifrato valido — il testo in chiaro fallirebbe la decrittografia.
cargo test store::password::tests::test_encrypt_decrypt_roundtrip
Ispezione manuale:
enject init # password: test123
enject set mykey # valore: my-super-secret
xxd .enject/store | head -5
strings .enject/store