Winix.Protect
0.4.0
Prefix Reserved
dotnet tool install --global Winix.Protect --version 0.4.0
dotnet new tool-manifest
dotnet tool install --local Winix.Protect --version 0.4.0
#tool dotnet:?package=Winix.Protect&version=0.4.0
nuke :add-package Winix.Protect --version 0.4.0
protect
Cross-platform encrypt-at-rest CLI using native OS key-storage primitives. DPAPI on Windows, AES-256-GCM with Keychain on macOS, AES-256-GCM with libsecret on Linux. Single AOT native binary. Zero key management — the OS provides the key.
Why
Files are encrypted at rest, scoped to the current user (or machine, on Windows and macOS). Moving encrypted files between machines or users fails by design — the OS key is tied to your identity. Perfect for storing sensitive config files, API keys, or database passwords where the threat model is "secure, offline, no key rotation."
Compose with digest for encrypted HMAC keys, with clip for clipboard automation, with pipes for streaming.
Install
Scoop (Windows)
scoop bucket add winix https://github.com/Yortw/winix
scoop install protect
.NET global tool (any platform with .NET 10+)
dotnet tool install --global Winix.Protect
Native binary (GitHub Releases)
Download the platform-appropriate archive from releases and place protect on your PATH.
Usage
protect file.json # encrypts to file.json.prot
protect file.json -o secure.prot # explicit output path
protect file.json --in-place # encrypt over the file (atomic)
protect file.json --rm # delete source after verify
protect --scope machine config.xml # machine-scoped (Windows/macOS only)
protect < input.bin > output.prot # streaming (pure piping)
cat api.key | protect -o api.key.prot # stdin streaming
Options
| Flag | Default | Description |
|---|---|---|
-o PATH / --output PATH |
FILE.prot for files, stdout for stdin |
Explicit output path. |
--in-place |
off | Encrypt/decrypt over the input file (atomic via temp + rename). |
--rm / --remove-source |
off | Delete source after successful round-trip verification. |
--scope {user,machine} |
user |
Key-derivation scope. Windows: DPAPI CurrentUser/LocalMachine. macOS: login/System Keychain. Linux: user only (machine unsupported). |
--no-verify |
off | Skip round-trip verification (faster, less safe). |
-f / --force |
off | Overwrite an existing destination file. By default the tool refuses to clobber existing data and exits 125. The overwrite is symlink-safe — if the destination is a symlink, the symlink itself is removed (the target file is untouched) before an exclusive create. |
--color, --no-color |
— | Respect NO_COLOR. |
--describe |
— | Emit tool metadata as JSON. |
--help, --version |
— | Standard introspection. |
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success. |
| 125 | Usage error — bad flags, path collision, unsupported scope on Linux. |
| 126 | Runtime error — encryption failure, key store unavailable, round-trip verify failed. |
How It Works
Each OS provides a secure key-derivation function:
- Windows: DPAPI (
ProtectedData.Protect) — keys are user/machine credentials stored in the kernel. - macOS: AES-256-GCM with a key stored in the login/System Keychain. Key is auto-generated on first use, never exposed to the user.
- Linux: AES-256-GCM with a key stored in libsecret. Same auto-generate-on-first-use pattern.
Files are chunked (64 KB per chunk) and each chunk is encrypted with AEAD (AES-256-GCM) or DPAPI. Every chunk is bound to its specific file via a 16-byte random FileId stored in the header — chunk reorder, cross-file substitution, and truncation are all detected. Round-trip verification (encrypt → decrypt → hash comparison) is included by default; disable with --no-verify for speed.
Integrity Model
Each chunk is authenticated with both its position (chunk index, isFinal flag) and the file's per-file FileId. This prevents:
- Truncation — silent removal of chunks (final-chunk flag).
- Reorder — swapping chunks within a file (chunk index in AAD).
- Cross-file substitution — splicing a chunk from a different
.protfile into this one (FileId in AAD).
Threat model boundary. The protections above defend against an attacker with write access to your .prot file but no key access — for example, untrusted backup software, cloud sync services, or shared NAS storage. If the attacker has both filesystem write AND access to your OS keystore (same OS user, or LocalMachine scope on a shared host), they can decrypt directly — splice protections are not the relevant defense.
Platform Notes
- Windows: Both user and machine scopes are supported. Machine scope requires the process to have DPAPI LocalMachine access (typically as admin or via SYSTEM account).
- macOS: User scope uses the login Keychain. Machine scope uses the System Keychain and requires
sudoor admin privileges. - Linux: Only user scope is supported. The tool requires
libsecret-toolsto be installed (sudo apt install libsecret-toolson Debian/Ubuntu, etc.).
Non-Portability by Design
Files encrypted with protect are not portable between:
- Machines (keys are tied to your device)
- Users (keys are tied to your OS user account)
- Scopes (machine scope cannot decrypt user scope and vice versa)
If you need portable encryption, use age or gpg. protect trades portability for zero-key-management convenience.
Composition
# Encrypt an HMAC key; decrypt and use it
protect api.key --rm
unprotect < api.key.prot | digest --hmac sha256 --key-stdin "payload"
# Encrypt a config, pass to another tool
protect config.json -o .config.prot
unprotect < .config.prot | app --config -
Related Tools
unprotect— companion; decrypts .prot filesdigest— hash and HMAC files (pairs with encrypted keys)clip— clipboard bridge for credentials
See Also
man protect(afterwinix install man)protect --describefor JSON metadata
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
## [0.3.0] - 2026-05-10
- Initial release.
See full changelog at https://github.com/Yortw/winix/blob/main/src/protect/CHANGELOG.md