| Crates.io | whiteout-cli |
| lib.rs | whiteout-cli |
| version | 1.0.0 |
| created_at | 2025-09-12 21:48:54.749291+00 |
| updated_at | 2025-09-12 21:48:54.749291+00 |
| description | Keep secrets out of Git while maintaining them locally |
| homepage | https://github.com/bytware/whiteout |
| repository | https://github.com/bytware/whiteout |
| max_upload_size | |
| id | 1836894 |
| size | 172,421 |
Keep Your Secrets Secret
A Git filter tool that keeps sensitive code local while committing safe alternatives to your repository.
Features โข Installation โข Quick Start โข Usage โข How It Works โข Contributing
Ever accidentally committed an API key? Hardcoded a password for testing? Left debug code in production?
Whiteout solves this by letting you maintain local-only code that never reaches your Git repository, while preserving safe alternatives in commits.
// What you see locally:
const apiKey = "process.env.API_KEY"; // @whiteout: "sk-proj-SUPER-SECRET-KEY-123"
// What gets committed:
const apiKey = "process.env.API_KEY";
//, #, -- comment stylesbrew tap bytware/tap
brew install whiteout
cargo install whiteout-cli
# Clone the repository
git clone https://github.com/bytware/whiteout.git
cd whiteout
# Build and install
cargo build --release
sudo cp target/release/whiteout /usr/local/bin/
# Verify installation
whiteout --version
# Using yay
yay -S whiteout-git
# Using paru
paru -S whiteout-git
cd your-project
whiteout init
This automatically:
.whiteout/ directory for local storage.gitattributes entriesChoose from multiple decoration styles that work with any comment format:
Works with any comment style (//, #, --):
// JavaScript
const apiKey = "sk-12345"; // @whiteout: "process.env.API_KEY"
# Python
api_key = "sk-12345" # @whiteout: "os.environ['API_KEY']"
-- SQL
SELECT * FROM users WHERE key = 'sk-12345'; -- @whiteout: 'REDACTED'
Hide entire code blocks between markers:
// @whiteout-start
const DEBUG = true;
const SECRET_ENDPOINT = "http://localhost:3000";
console.log("Debug mode active");
// @whiteout-end
const DEBUG = false; // This line stays in commits
For markdown or documentation, hide content after a marker:
# Public Documentation
This content is committed.
\@whiteout
This content stays local only.
It won't appear in commits.
Back to public content.
For configuration values within strings:
const url = "https://[[localhost:3000||api.example.com]]/v1";
// Locally: uses localhost:3000
// Committed: uses api.example.com
# Edit your files with secrets
vim config.js
# Commit as usual - secrets are automatically removed
git add .
git commit -m "Add configuration"
# Your local files keep the secrets
cat config.js # Still shows your secret values
Syntax: <code> // @whiteout: <replacement>
Note: When documenting examples, escape the @ with backslash: \@whiteout
# Local version:
password = "getpass.getpass()" # @whiteout: "admin123"
# Committed version:
password = "getpass.getpass()"
Syntax: @whiteout-start ... @whiteout-end
# @whiteout-start
debug_mode: true
verbose_logging: true
test_endpoints:
- localhost:8080
# @whiteout-end
production_mode: true # This stays in commits
Syntax: @whiteout (hides everything until blank line)
Normal content here.
\@whiteout
Secret information.
More secrets.
Public content resumes.
Syntax: [[local||committed]]
[database]
host = "[[localhost||db.production.com]]"
port = [[5432||3306]]
When writing documentation about Whiteout (like this README), use backslash to escape decorators:
# To show the literal text in docs:
\@whiteout # Shows as @whiteout
\@whiteout-start # Shows as @whiteout-start
\@whiteout-end # Shows as @whiteout-end
# These are treated as actual decorators:
@whiteout # Would hide content (without backslash)
whiteout init [--path <dir>]
# Apply clean filter (remove secrets)
whiteout clean < file.txt
# Apply smudge filter (restore secrets)
whiteout smudge < file.txt
Whiteout uses Git's clean/smudge filter mechanism:
graph LR
A[Working Directory<br/>with secrets] -->|git add<br/>clean filter| B[Staging Area<br/>secrets removed]
B -->|git commit| C[Repository<br/>safe version]
C -->|git checkout<br/>smudge filter| A
Local values are stored in .whiteout/local.toml (gitignored) and restored automatically.
Both Whiteout and .env files solve secret management, but with different approaches:
| Aspect | Whiteout | .env Files |
|---|---|---|
| Where secrets live | Inline with code | Separate file |
| What you can hide | Values, code blocks, files | Environment variables |
| Git safety | Automatic via filters | Manual via .gitignore |
| Use case | Development & debugging | Configuration management |
Use each tool for what it does best:
// Production config from .env
const dbHost = process.env.DB_HOST;
// Development secrets inline with Whiteout
const apiKey = "process.env.API_KEY"; // @whiteout: "sk-dev-12345"
// Debug code that stays local
// @whiteout-start
console.log("Debug mode: connecting to local services");
const DEBUG = true;
// @whiteout-end
.whiteout/ directory (ensure it's in .gitignore).whiteout/local.toml# Run all tests
cargo test
# Run specific test
cargo test test_inline_parser
# Run with output
cargo test -- --nocapture
# Run integration tests
./tests/git_integration_test.sh
@whiteout markers are removed during the clean operation, the smudge filter cannot currently restore the hidden content when checking out files. This is a planned feature for a future release.Contributions are welcome!
# Build
cargo build
# Test
cargo test
# Format code
cargo fmt
# Lint
cargo clippy
MIT License - see LICENSE for details.