| Crates.io | confguard |
| lib.rs | confguard |
| version | 4.0.1 |
| created_at | 2025-07-03 21:23:14.890893+00 |
| updated_at | 2026-01-03 16:59:30.53559+00 |
| description | Guard your sensitive configuration files |
| homepage | |
| repository | https://github.com/sysid/confguard |
| max_upload_size | |
| id | 1737047 |
| size | 304,304 |
A highly opinionated configuration management tool for securing and managing sensitive environment files across different deployment stages.
ConfGuard helps manage sensitive configuration files by:
.envrc files to a managed locationWhen guarding a project, ConfGuard automatically creates multiple environment files:
| File | Purpose |
|---|---|
local.env |
Local development environment |
test.env |
Testing environment |
int.env |
Integration/staging environment |
prod.env |
Production environment |
Each file contains export RUN_ENV="<environment>" to identify the active environment.
┌─────────────────────────────────────────────────────────────────────────────┐
│ ConfGuard Architecture │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Your Project $CONFGUARD_BASE_DIR │
│ ├── .envrc ──────symlink────────────► ├── guarded/ │
│ └── ... │ └── <project-uuid>/ │
│ │ ├── dot.envrc │
│ │ └── environments/ │
│ │ ├── local.env │
│ │ ├── test.env │
│ │ ├── int.env │
│ │ └── prod.env │
│ └── confguard.toml │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
confguard/src/
├── main.rs # Entry point, CLI parsing, logging setup
├── lib.rs # Library exports
├── errors.rs # Error types with thiserror
├── cli/ # Command-line interface
│ ├── args.rs # Command definitions (clap)
│ └── commands.rs# Command execution logic
├── core/ # Core guarding functionality
│ ├── guard.rs # ConfGuard struct and operations
│ └── config.rs # Configuration management
├── sops/ # SOPS encryption integration
│ ├── manager.rs # Encryption workflow orchestration
│ ├── crypto.rs # SOPS binary invocation
│ └── gitignore.rs # Gitignore management
└── util/ # Utility functions
├── path/ # Path manipulation utilities
└── helper/ # General helpers
From source:
git clone https://github.com/sysid/rs-cg.git
cd rs-cg
make install
Or using cargo:
cd confguard
cargo install --path .
Verify installation:
confguard --info
Initialize SOPS configuration:
confguard sops-init
Guard an existing project:
confguard guard /path/to/your/project
Verify the guard:
confguard show /path/to/your/project
confguard [OPTIONS] [COMMAND]
| Option | Description |
|---|---|
-c, --config <FILE> |
Custom config file path |
-d, --debug |
Increase verbosity (-d=INFO, -dd=DEBUG, -ddd=TRACE) |
--generate <SHELL> |
Generate shell completions (bash, zsh, fish) |
--info |
Display version and base directory |
ConfGuard supports two linking modes controlled by the --absolute flag:
| Mode | Flag | Symlink Content | Example |
|---|---|---|---|
| Relative (default) | none | ../../../xxx/rs-cg/guarded/proj-uuid/dot.envrc |
Portable if both dirs move together |
| Absolute | --absolute |
/Users/you/xxx/rs-cg/guarded/proj-uuid/dot.envrc |
Works regardless of project location |
Relative linking (default) calculates the path from the symlink location to the target. Use this when your home directory might move or be mounted differently.
guard - Guard a Project DirectoryMoves .envrc to a secure location and creates a symlink in its place.
confguard guard <source_dir> [--absolute]
| Parameter | Required | Description |
|---|---|---|
source_dir |
Yes | Project directory containing .envrc |
--absolute |
No | Use absolute paths instead of relative (default: false) |
What it creates:
$CONFGUARD_BASE_DIR/guarded/{project-name}-{uuid}/dot.envrc (original .envrc content)environments/{local,test,int,prod}.env.envrc -> dot.envrc (relative or absolute based on flag).idea/runConfigurations/rsenv.shMetadata appended to dot.envrc:
#------------------------------- confguard start --------------------------------
# config.relative = true
# config.version = 3
# state.sentinel = 'myproject-a1b2c3d4'
# state.timestamp = '2026-01-03T...'
# state.sourceDir = '~/dev/myproject'
export SOPS_PATH=$HOME/xxx/rs-cg/guarded/myproject-a1b2c3d4
dotenv $SOPS_PATH/environments/local.env
#-------------------------------- confguard end ---------------------------------
Use case: Secure a project's environment configuration while maintaining seamless access via the original .envrc path. No sensitive information ends up in version control.
unguard - Remove Guarding from a ProjectRestores the original file structure by replacing the symlink with the actual content.
confguard unguard <source_dir>
| Parameter | Required | Description |
|---|---|---|
source_dir |
Yes | Project directory with guarded .envrc |
What gets restored:
.envrc symlink replaced with dot.envrc content.envrcWhat is NOT removed:
$CONFGUARD_BASE_DIR/guarded/{sentinel}/Use case: Permanently disconnect a project from ConfGuard management, e.g., before archiving or transferring the project.
guard-one - Guard a Single FileGuards an additional file within an already-guarded project.
confguard guard-one <source_dir> <source_path>
| Parameter | Required | Description |
|---|---|---|
source_dir |
Yes | Project directory (must already be guarded) |
source_path |
Yes | File to guard (must be within project) |
Validation:
source_dir (prevents guarding arbitrary system files)Behavior:
/project/config/secrets.env -> {sentinel}/config/secrets.envguard which defaults to relative)Use case: Add sensitive files (credentials, keys) to an existing guard setup without re-guarding the entire project.
relink - Recreate Symbolic LinkRecreates the .envrc symlink when it's been deleted or broken.
confguard relink <envrc_path>
| Parameter | Required | Description |
|---|---|---|
envrc_path |
Yes | Path to the dot.envrc file in the guarded location |
How it works:
state.sourceDir from the confguard section in dot.envrcconfig.relative settingUse cases:
.envrc was gitignoredreplace-link - Replace Symlink with TargetConverts a symlink into a regular file containing the target's content.
confguard replace-link <link>
| Parameter | Required | Description |
|---|---|---|
link |
Yes | Path to the symbolic link |
Behavior:
Use case: Inverse to replace-link, but works on ANY symlink, not just confguard-managed ones.
| Command | Operation |
|---|---|
| guard-one | file → sentinel dir, create symlink |
| replace-link | symlink → move target back, remove symlink |
replace-link vs unguard:
| Aspect | replace-link |
unguard |
|---|---|---|
| Scope | Single symlink | Entire project |
| Target | Any symlink you specify | Only guarded projects |
| Metadata | Untouched | Removes confguard section |
| Other symlinks | Untouched | Replaces ALL symlinks pointing to sentinel |
| Guard status | Project remains guarded | Project no longer guarded |
replace-link /path/to/symlink
unguard /path/to/project
init - Initialize Project with .envrcCreates a new .envrc file from a template.
confguard init <source_dir> [--template <path>]
| Parameter | Required | Description |
|---|---|---|
source_dir |
Yes | Directory to initialize |
--template |
No | Custom template file (default: embedded template) |
Validation:
.envrc already existsNote: This command does NOT guard the project. Run guard separately after initialization.
show - Display Guard StatusShows the current configuration of a guarded project.
confguard show <source_dir>
Output fields:
| Field | Description |
|---|---|
version |
Configuration version (currently 3) |
source_dir |
Absolute path to project |
is_relative |
Whether symlinks use relative paths |
confguard_base_dir |
Base directory for all ConfGuard data |
target_dir |
Path to this project's guarded files |
sentinel |
Unique identifier ({name}-{uuid}) |
settings - Display Global SettingsShows the current ConfGuard configuration.
confguard settings
Output:
Settings:
Base: /Users/you/xxx/rs-cg
Version: 3
fix-run-config - Update IDE ConfigurationRepairs or updates the IntelliJ run configuration script.
confguard fix-run-config <source_dir>
What it does:
.idea/runConfigurations/rsenv.shUse case: Restore IDE integration after the run configuration was deleted or after updating ConfGuard.
ConfGuard creates .idea/runConfigurations/rsenv.sh during the guard operation:
#!/usr/bin/env bash
[[ -f "$SOPS_PATH/environments/${RUN_ENV:-local}.env" ]] && rsenv build "$SOPS_PATH/environments/${RUN_ENV:-local}.env"
How it works with IntelliJ:
RUN_ENV to switch environments (local, test, int, prod)rsenv build to process the environment fileRequirements:
rsenv tool must be installedSOPS autodetects file formats, including binary files. Unknown extensions are automatically treated as binary data.
ConfGuard prevents accidental commits of plaintext secrets through automatic .gitignore management. When you run sops-enc, it:
.enc versions.gitignore → adds patterns to exclude plaintext filessops-clean → only encrypted files remainWhat gets added to .gitignore:
# ---------------------------------- confguard-start -----------------------------------
*.env # sops-managed 2024-01-15 10:30:45
*.envrc # sops-managed 2024-01-15 10:30:45
dot_pgpass # sops-managed 2024-01-15 10:30:45
dot_pypirc # sops-managed 2024-01-15 10:30:45
kube_config # sops-managed 2024-01-15 10:30:45
# ---------------------------------- confguard-end -----------------------------------
Patterns come from confguard.toml:
file_extensions_enc → *.{ext} patternsfile_names_enc → exact filename patternsThe confguard markers allow updates without destroying your existing .gitignore entries.
Typical workflow:
# 1. Create/edit plaintext secrets
vim secrets.env
# 2. Encrypt (also updates .gitignore)
confguard sops-enc
# 3. Remove plaintext (safe - gitignore already protects)
confguard sops-clean
# 4. Commit only encrypted files
git add secrets.env.enc .gitignore
git commit -m "Add encrypted secrets"
sops-init - Initialize SOPS Configurationconfguard sops-init [--dir <path>] [--template <path>]
| Option | Description |
|---|---|
--dir |
Target directory (default: $CONFGUARD_BASE_DIR) |
--template |
Custom template file |
Creates confguard.toml with encryption configuration.
sops-enc - Encrypt Filesconfguard sops-enc [--dir <path>]
Encrypts all files matching file_extensions_enc and file_names_enc patterns. Output files have
.enc suffix. Also updates .gitignore to exclude plaintext files from version control (see
Security Model above).
sops-dec - Decrypt Filesconfguard sops-dec [--dir <path>]
Decrypts all .enc files (or files matching file_extensions_dec/file_names_dec).
sops-clean - Remove Plaintext Filesconfguard sops-clean [--dir <path>]
Removes plaintext files that match encryption patterns (after encryption, to leave only .enc files).
| Variable | Description | Default |
|---|---|---|
CONFGUARD_BASE_DIR |
Base directory for confguard operations | $HOME/xxx/rs-cg |
CONFGUARD_VERSION |
Override configuration version | - |
RUST_LOG |
Logging level (DEBUG, INFO, WARN) | WARN |
When a project is guarded:
$CONFGUARD_BASE_DIR/
├── guarded/
│ └── <project-name-uuid>/
│ ├── dot.envrc # Original .envrc content
│ └── environments/
│ ├── local.env # export RUN_ENV="local"
│ ├── test.env # export RUN_ENV="test"
│ ├── int.env # export RUN_ENV="int"
│ └── prod.env # export RUN_ENV="prod"
└── confguard.toml # SOPS configuration
Create confguard.toml in your base directory:
gpg_key = "your-gpg-key-fingerprint"
# Extensions to encrypt
file_extensions_enc = [
"envrc",
"env",
"p12", # binary - PKCS#12 certificates
"keystore", # binary - Java keystores
]
# Specific filenames to encrypt
file_names_enc = [
"dot_pypirc",
"dot_pgpass",
"kube_config",
]
# Extensions to decrypt (encrypted files)
file_extensions_dec = ["enc"]
# Specific filenames to decrypt
file_names_dec = []
┌─────────────────────────────────────────────────────────────────────────────┐
│ ENCRYPTION FLOW │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ confguard.toml │
│ ├── file_extensions_enc: ["envrc", "env", "p12", ...] │
│ └── file_names_enc: [...] │
│ │ │
│ ▼ │
│ collect_files() │
│ └── Filter by extension OR filename │
│ │ │
│ ▼ │
│ encrypt_file() [8 parallel threads] │
│ └── sops -e --pgp <key> --output <out> <in> │
│ │ │
│ ▼ │
│ SOPS auto-detects file type │
│ ├── Known extension (.json, .yaml, .env) → structured format │
│ └── Unknown extension → binary format (autodetected) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
make build # Build release binary
make test # Run tests
make style # Format code (cargo fmt)
make lint # Run clippy
make doc # Generate documentation
make install # Install to ~/bin/
make uninstall # Remove installation
make init-env # Create test environment
make show-env # Show test environment structure
make bump-patch # Bump patch version (x.y.Z)
make bump-minor # Bump minor version (x.Y.z)
make bump-major # Bump major version (X.y.z)
Tests require special environment setup and must run single-threaded due to shared state:
# Run all tests
make test
# Or manually:
RUST_LOG=DEBUG cargo test -- --test-threads=1
# Run specific test module
cargo test core::guard -- --test-threads=1
confguard/tests/
├── cli/ # CLI integration tests
├── core/ # Core functionality tests
├── sops/ # SOPS integration tests
├── util/ # Utility function tests
└── resources/ # Test fixtures
Key dependencies:
| Crate | Purpose |
|---|---|
clap |
CLI argument parsing |
thiserror |
Error handling |
tracing |
Logging infrastructure |
serde / toml |
Configuration parsing |
uuid |
Unique sentinel identifiers |
walkdir |
Directory traversal |
rayon |
Parallel file processing |
BSD-3-Clause - See LICENSE for details.