git_crypt/lib.rs
1//! # git-crypt
2//!
3//! A Rust implementation of git-crypt for transparent encryption of files in a git repository.
4//!
5//! ## Features
6//!
7//! - **Transparent Encryption**: Files are automatically encrypted when committed and decrypted when checked out
8//! - **AES-256-GCM Encryption**: Strong, authenticated encryption with built-in tamper detection
9//! - **Git Filter Integration**: Uses git's clean/smudge filters for seamless operation
10//! - **Key Management**: Export and import symmetric keys for secure sharing
11//! - **GPG Support**: Optional GPG integration for team key distribution
12//! - **Simple CLI**: Easy-to-use command-line interface
13//!
14//! ## Quick Start
15//!
16//! ### Installation
17//!
18//! Install from GitHub:
19//! ```bash
20//! cargo install --git https://github.com/AprilNEA/git-crypt-rs
21//! ```
22//!
23//! Or build from source:
24//! ```bash
25//! cargo build --release
26//! # Binary will be at target/release/git-crypt
27//! ```
28//!
29//! ### Basic Usage
30//!
31//! ```bash
32//! # Initialize in your git repository
33//! git-crypt init
34//!
35//! # Configure which files to encrypt in .gitattributes
36//! echo "*.secret filter=git-crypt diff=git-crypt" >> .gitattributes
37//! git add .gitattributes
38//! git commit -m "Configure git-crypt"
39//!
40//! # Add encrypted files (automatically encrypted)
41//! echo "my secret data" > test.secret
42//! git add test.secret
43//! git commit -m "Add encrypted file"
44//!
45//! # Export key for sharing
46//! git-crypt export-key git-crypt-key.bin
47//! ```
48//!
49//! ## How It Works
50//!
51//! git-crypt uses git's filter system to transparently encrypt and decrypt files:
52//!
53//! 1. **Clean filter** (encryption): When you `git add` a file, the clean filter encrypts it before storing in the repository
54//! 2. **Smudge filter** (decryption): When you `git checkout`, the smudge filter decrypts it in your working directory
55//! 3. **Diff filter**: When you `git diff`, it shows that the file is encrypted rather than binary gibberish
56//!
57//! The encryption key is stored in `.git/git-crypt/keys/default` and is never committed to the repository.
58//!
59//! ### Data Flow
60//!
61//! **Encryption (git add):**
62//! ```text
63//! File content → git add → clean filter → encrypt → store in .git
64//! ```
65//!
66//! **Decryption (git checkout):**
67//! ```text
68//! Encrypted data in .git → smudge filter → decrypt → working directory
69//! ```
70//!
71//! ## Module Overview
72//!
73//! - [`crypto`] - Core AES-256-GCM encryption/decryption operations
74//! - [`key`] - Key management, storage, export/import
75//! - [`git`] - Git filter integration and repository operations
76//! - [`gpg`] - Optional GPG support for key sharing (requires `gpg` feature)
77//! - [`error`] - Error types and unified error handling
78//!
79//! ## Commands
80//!
81//! - `init` - Initialize git-crypt in the current repository
82//! - `lock` - Lock the repository (remove filters, show encrypted content)
83//! - `unlock [--key-file PATH]` - Unlock the repository
84//! - `export-key OUTPUT` - Export the symmetric key to a file
85//! - `import-key INPUT` - Import a symmetric key from a file
86//! - `add-gpg-user GPG_ID` - Grant access to a GPG user (requires `gpg` feature)
87//! - `status` - Show status of encrypted files (not yet implemented)
88//!
89//! ## Examples
90//!
91//! ### Complete Workflow
92//!
93//! ```bash
94//! # 1. Initialize a git repository
95//! git init my-secure-repo
96//! cd my-secure-repo
97//!
98//! # 2. Initialize git-crypt
99//! git-crypt init
100//!
101//! # 3. Configure encryption patterns in .gitattributes
102//! cat > .gitattributes << 'EOF'
103//! # Encrypt all files in the secrets/ directory
104//! secrets/** filter=git-crypt diff=git-crypt
105//!
106//! # Encrypt specific file types
107//! *.key filter=git-crypt diff=git-crypt
108//! *.secret filter=git-crypt diff=git-crypt
109//!
110//! # Encrypt specific config files
111//! config/database.yml filter=git-crypt diff=git-crypt
112//! .env.production filter=git-crypt diff=git-crypt
113//! EOF
114//!
115//! git add .gitattributes
116//! git commit -m "Configure git-crypt"
117//!
118//! # 4. Add encrypted files
119//! mkdir -p secrets
120//! echo "AWS_SECRET_KEY=secret123" > secrets/api_keys.txt
121//! git add secrets/
122//! git commit -m "Add encrypted secrets"
123//!
124//! # 5. Share access with team members
125//! git-crypt export-key team-key.bin
126//! # Share team-key.bin securely (password manager, secure channel, etc.)
127//! ```
128//!
129//! ### Unlocking on Another Machine
130//!
131//! ```bash
132//! # Clone the repository
133//! git clone <repository-url>
134//! cd <repository>
135//!
136//! # At this point, encrypted files show as encrypted data
137//!
138//! # Unlock with the shared key
139//! git-crypt unlock --key-file team-key.bin
140//!
141//! # Refresh working directory
142//! git checkout HEAD -- .
143//!
144//! # Now files are decrypted
145//! cat secrets/api_keys.txt
146//! ```
147//!
148//! ### Lock/Unlock
149//!
150//! ```bash
151//! # Lock repository (useful before sharing working directory)
152//! git-crypt lock
153//! # Now all encrypted files show their encrypted content
154//!
155//! # Unlock again
156//! git-crypt unlock
157//! git checkout HEAD -- .
158//! ```
159//!
160//! ## Security Considerations
161//!
162//! ### Threat Model
163//!
164//! **Protected against:**
165//! - Unauthorized access to repository content
166//! - Accidental exposure of secrets in public repositories
167//! - Historical secret leakage in git history
168//!
169//! **Not protected against:**
170//! - Attacks on the working directory (files are plaintext there)
171//! - Compromised git client or filters
172//! - Key extraction from `.git` directory
173//! - Side-channel attacks
174//!
175//! ### Best Practices
176//!
177//! 1. Keep `.git/git-crypt/` directory secure
178//! 2. Use restrictive file permissions (automatic on Unix)
179//! 3. Never commit key files to the repository
180//! 4. Use GPG for team key distribution when possible
181//! 5. Rotate keys if compromised
182//! 6. Consider full-disk encryption for additional security
183//! 7. Share exported keys through secure channels only
184//!
185//! ## Cryptography Details
186//!
187//! - **Algorithm**: AES-256-GCM (Galois/Counter Mode)
188//! - **Key size**: 256 bits (32 bytes)
189//! - **Nonce size**: 96 bits (12 bytes), randomly generated per encryption
190//! - **Authentication**: Built into GCM mode (16-byte tag)
191//!
192//! ### Encrypted File Format
193//!
194//! ```text
195//! [GITCRYPT][12-byte nonce][variable-length ciphertext + 16-byte GCM tag]
196//! ```
197//!
198//! The magic header ensures reliable detection of encrypted data and provides
199//! versioning capability for future format changes.
200//!
201//! ## GPG Support (Optional)
202//!
203//! To enable GPG support, install system dependencies and build with the `gpg` feature:
204//!
205//! **macOS:**
206//! ```bash
207//! brew install nettle gmp
208//! cargo install --git https://github.com/AprilNEA/git-crypt-rs --features gpg
209//! ```
210//!
211//! **Ubuntu/Debian:**
212//! ```bash
213//! sudo apt-get install libnettle-dev libgmp-dev
214//! cargo install --git https://github.com/AprilNEA/git-crypt-rs --features gpg
215//! ```
216//!
217//! Then use GPG for key sharing:
218//! ```bash
219//! git-crypt add-gpg-user user@example.com
220//! ```
221//!
222//! ## Compatibility
223//!
224//! **Not compatible with original git-crypt:**
225//! - Different file format (magic header + nonce prepended)
226//! - Different key storage location
227//! - Different filter commands
228//!
229//! This is a complete reimplementation focusing on:
230//! - Memory safety (Rust)
231//! - Modern cryptography practices
232//! - Simplicity and maintainability
233//! - Optional features (GPG)
234//!
235//! ## Testing
236//!
237//! The project has a comprehensive test suite with **63 tests** covering:
238//!
239//! ### Unit Tests (29 tests)
240//!
241//! Run all unit tests:
242//! ```bash
243//! cargo test --lib
244//! ```
245//!
246//! - **Crypto module** ([`crypto`]): Encryption correctness, authentication, edge cases
247//! - **Key management** ([`key`]): File operations, permissions, key lifecycle
248//!
249//! ### Integration Tests (16 tests)
250//!
251//! Run all integration tests:
252//! ```bash
253//! cargo test --test integration_test
254//! ```
255//!
256//! Tests complete workflows: initialization, lock/unlock, key export/import, multi-repo isolation.
257//!
258//! ### Filter Tests (6 tests)
259//!
260//! Run filter tests:
261//! ```bash
262//! cargo test --test filter_test
263//! ```
264//!
265//! Tests git filter operations: clean (encrypt), smudge (decrypt), diff.
266//!
267//! ### Edge Case Tests (12 tests)
268//!
269//! Run edge case tests:
270//! ```bash
271//! cargo test --test edge_cases_test
272//! ```
273//!
274//! Tests corner cases: large files (10MB), empty files, binary data, Unicode,
275//! corruption detection, concurrency, permissions.
276//!
277//! ## Running All Tests
278//!
279//! ```bash
280//! # Run all tests
281//! cargo test
282//!
283//! # Run with output
284//! cargo test -- --nocapture
285//!
286//! # Run with backtrace
287//! RUST_BACKTRACE=1 cargo test
288//!
289//! # Run specific test
290//! cargo test test_encrypt_decrypt
291//! ```
292//!
293//! ## Test Coverage
294//!
295//! Generate coverage report (requires cargo-tarpaulin):
296//! ```bash
297//! cargo install cargo-tarpaulin
298//! cargo tarpaulin --out Html
299//! ```
300//!
301//! ## Security Testing
302//!
303//! Tests verify security properties:
304//! - ✅ Authentication (wrong key fails decryption)
305//! - ✅ Tamper detection (corrupted data rejected)
306//! - ✅ File permissions (0600 on Unix)
307//! - ✅ Key isolation (different repos use different keys)
308//! - ✅ Nonce uniqueness (no nonce reuse)
309
310// Library exports for testing
311pub mod crypto;
312pub mod error;
313pub mod git;
314pub mod gpg;
315pub mod key;
316
317// Re-export commonly used types
318pub use crypto::CryptoKey;
319pub use error::{GitCryptError, Result};
320pub use git::GitRepo;
321pub use key::KeyManager;