Transparent encryption of secrets within files using XChaCha20-Poly1305, with multi-user key management and git integration.
- Marker-based encryption -- wrap secrets with
β{secret}oro+{secret}; sss seals them in-place - Multi-user architecture -- hybrid X25519 + XChaCha20-Poly1305 encryption; each user holds their own keypair
- Git integration -- pre-commit, post-merge, and post-checkout hooks maintain sealed state automatically
- Key derivation -- Argon2id with configurable security levels (sensitive / moderate / interactive)
- Post-quantum hybrid suite -- opt-in hybrid KEM (X448 + sntrup761 via trelis); file ciphertexts are byte-identical across suites; trelis is experimental and unaudited
- Deterministic nonces -- BLAKE2b-derived nonces produce clean git diffs
- Marker inference -- intelligent marker preservation when editing rendered files
- Secrets files -- interpolation from
.secretsfiles with YAML-style multi-line values - System keyring -- native OS credential storage (macOS Keychain, Windows Credential Manager, Linux Secret Service)
- Emacs integration --
sss-modeprovides transparent decrypt-on-open and re-seal-on-save - FUSE filesystem -- mount a project with transparent rendering (Linux/macOS, optional)
- WinFSP filesystem -- mount a project with transparent rendering (Windows, optional)
- 9P server -- network-transparent file access (optional)
- Agent daemon -- key caching with policy-based access control (experimental)
- Password strength analysis -- real-time feedback during key generation with pattern detection
- Ignore patterns -- gitignore-style pattern matching for project-wide operations
- Secrets interpolation -- reference named secrets from external files with
β²{name}syntax - Editor integration --
sssesymlink provides transparent edit-in-place from any editor
git clone <repository-url>
cd sss
cargo build --release
# Binaries are in target/release/Build with FUSE support (Linux/macOS):
# Debian/Ubuntu
sudo apt-get install libfuse3-dev fuse3
# Fedora/RHEL
sudo dnf install fuse3-devel fuse3
# macOS: install macFUSE from https://osxfuse.github.io/
cargo build --features fuse --releaseBuild with WinFSP support (Windows):
# Install WinFSP from https://winfsp.dev/
cargo build --features winfsp --releaseBuild with 9P server support:
cargo build --features ninep --releaseBuild with all optional features (Linux/macOS):
cargo build --features fuse,ninep --releasePre-built packages are available via build scripts:
- Debian/Ubuntu --
debian/build-deb.sh - RHEL/CentOS --
rpm-build/build-rpm.sh - Alpine/musl --
Dockerfile.alpine
See docs/INSTALLATION.md for platform-specific instructions including macOS cross-compilation and development environment setup.
-
Generate a keypair
sss keys generate
You will be prompted for a passphrase to protect your private key. A password strength indicator provides real-time feedback.
-
Initialise a project
sss init alice
This creates
.sss.tomlin the current directory and adds you as the first user. -
Mark secrets in a file
echo "password=β{my-secret-password}" > config.txt
-
Seal the file
sss seal -x config.txt # config.txt now contains: password=β {base64-ciphertext} -
Open the file
sss open config.txt # Outputs: password=β{my-secret-password}
| Marker | Type | Description |
|---|---|---|
β{content} |
Plaintext | UTF-8 marker (U+2295) |
o+{content} |
Plaintext | ASCII alternative |
β {content} |
Ciphertext | Sealed form (U+22A0), always UTF-8 |
β²{name} |
Interpolation | Reference a named secret from a secrets file (U+22B2) |
The β and o+ forms are interchangeable on input. After sealing, all markers become β {...}.
See docs/marker-format.md for the complete syntax reference including BNF grammar and ciphertext payload layout.
These flags can be used with any command:
sss --confdir <DIR> ... # Override config directory location
sss --non-interactive ... # Fail if passphrase not in SSS_PASSPHRASE env var
sss --kdf-level <LEVEL> ... # KDF security level: sensitive (default), moderate, interactivesss seal <file> # Seal plaintext markers (output to stdout)
sss seal -x <file> # Seal in-place
sss seal --project # Seal all files in project
sss open <file> # Unseal to plaintext markers (output to stdout)
sss open -x <file> # Unseal in-place
sss open --project # Unseal all files (requires project permission)
sss render <file> # Unseal and strip markers (bare secret values)
sss render -x <file> # Render in-place
sss render --project # Render all files (requires project permission)
sss edit <file> # Unseal, open in $EDITOR, re-seal on save
sss status # Show project root pathAll file commands accept - to read from stdin.
sss keys generate # Generate new keypair (classic, default)
sss keys generate --suite hybrid # Generate hybrid (X448+sntrup761) keypair
sss keys generate --suite both # Generate both classic and hybrid keypairs atomically
sss keys generate --no-password # Generate keypair without passphrase
sss keys list # List private keys
sss keys pubkey # Show your public key
sss keys pubkey --fingerprint # Show key fingerprint only
sss keys pubkey --user <name> # Show another user's public key
sss keys current # Show which key is active
sss keys current <key-id> # Set active key by ID or partial ID
sss keys delete <key-id> # Delete a keypair
sss keys set-passphrase <key-id> # Set or change passphrase on a key
sss keys remove-passphrase <key-id> # Remove passphrase protection from a key
sss keys rotate # Rotate project key (re-encrypts all files)
sss keys rotate --force # Skip confirmation prompt
sss keys rotate --dry-run # Preview what would be changed
sss keys rotate --no-backup # Skip creating backup copiesUsers can be managed via sss users or sss project users (equivalent):
sss users list # List project users
sss users add <user> <pubkey> # Add user (file or base64 public key)
sss users remove <user> # Remove user (triggers key rotation)
sss users info <user> # Show information about a usersss migrate # Migrate repo from classic (v1.0) to hybrid (v2.0)
sss migrate --dry-run # Preview migration plan without touching disk
sss users add-hybrid-key <user> <pubkey> # Record a user's hybrid public key before migrationsss init [username] # Initialise project
sss init [username] --crypto hybrid # Initialise a v2.0 hybrid project
sss project show # Show settings for current project
sss project list # List all configured projects
sss project enable <feature> # Enable render or open for project-wide ops
sss project disable <feature> # Disable render or open
sss project remove [path] # Remove project from settingsIgnore patterns (control which files are processed by --project operations):
sss project ignore list # Show all ignore patterns
sss project ignore add <pattern> # Add a glob pattern (e.g., '*.log', 'build/**')
sss project ignore remove <pattern> # Remove a patternSecrets file configuration:
sss project secrets-file show # Show configured secrets filename
sss project secrets-file set <name> # Set custom secrets filename
sss project secrets-file clear # Revert to default ("secrets")sss settings show # Show current settings
sss settings location # Show config file locations
sss settings set --username <name> # Set default username
sss settings set --editor <editor> # Set preferred editor
sss settings set --coloured <bool> # Enable/disable coloured output
sss settings set --kdf-level <level> # Set KDF security level for new keys
sss settings set --use-keyring <bool> # Enable/disable system keyring
sss settings set --secrets-filename <name> # Set default secrets filename
sss settings set --secrets-suffix <suffix> # Set default secrets file suffix
sss settings reset --confirm # Reset all settings to defaultssss hooks install # Install hooks into current repo
sss hooks install --multiplex # Use multiplexed hook structure (.d/ directories)
sss hooks install --template # Install to git template directory
sss hooks list # List available hooks
sss hooks show <hook> # Show contents of a specific hook
sss hooks export # Export hooks to ~/.config/sss/hooks/See docs/usage-guide.md for complete workflow documentation.
- Each user generates their own keypair with
sss keys generate - Each user shares their public key:
sss keys pubkey > username.pub - The project owner adds each user:
sss users add <username> <pubkey-file>
All users can then seal and open files independently using their own private key. When a user is removed, key rotation is automatically triggered -- the project key is regenerated and all sealed files are re-encrypted so the removed user can no longer decrypt anything.
See docs/usage-guide.md for the full team collaboration workflow.
WARNING: The hybrid suite depends on
trelis(X448 + sntrup761), which is experimental and has not been audited. The classic suite (libsodium, v1.0) remains the recommended default for production use. Use hybrid only if you need post-quantum key-wrapping resistance and accept the experimental status of trelis.
sss v2.0 introduces an opt-in hybrid post-quantum KEM for repository-key wrapping. The
in-file ciphertexts (β {...} markers) are byte-identical between classic and hybrid repos;
only the per-user sealed_key entries in .sss.toml differ.
Suite selection is controlled by the version field in .sss.toml:
| version | Suite | Wrapping |
|---|---|---|
"1.0" |
Classic (default) | libsodium crypto_box_seal (X25519) |
"2.0" |
Hybrid (opt-in) | trelis KEM (X448 + sntrup761) β BLAKE3 β XChaCha20-Poly1305 |
# Requires: sss built with --features hybrid
sss keys generate --suite both # generate classic + hybrid keypairs
sss init --crypto hybrid alice # create v2.0 project# Step 1: every user generates a hybrid keypair
sss keys generate --suite hybrid
# Step 2: every user exports their hybrid public key and shares it
sss keys pubkey --suite hybrid > alice-hybrid.pub
# Step 3: the project owner records each user's hybrid key
sss users add-hybrid-key alice "$(cat alice-hybrid.pub)"
# Step 4: preview the migration plan (no disk writes)
sss migrate --dry-run
# Step 5: perform the migration (rewrites .sss.toml only, never file content)
sss migrateAfter sss migrate, .sss.toml carries version = "2.0". All sealed files are unchanged.
cargo build --features hybrid --releaseThe default build does not include trelis. Binary packages that ship hybrid support will be labelled accordingly.
Secrets files hold named values that can be interpolated into sealed files using the β²{name} syntax:
# .secrets file
database_password: hunter2
api_token: sk-abcdef1234567890
# Multi-line value (YAML-style pipe)
ssh_private_key: |
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAA...
-----END OPENSSH PRIVATE KEY-----
Reference a secret by name in any file:
DATABASE_URL=postgres://admin:β²{database_password}@localhost/app
See docs/SECRETS_FILE_FORMAT.md for the format specification and docs/SECRETS_PARSING_GUIDE.md for integration guidance.
| Variable | Purpose |
|---|---|
SSS_PASSPHRASE |
Non-interactive passphrase entry (automation, CI/CD) |
SSS_KDF_LEVEL |
Override KDF security level (sensitive/moderate/interactive) |
SSS_USE_KEYRING |
Enable system keyring for key storage (true/false) |
SSS_USER |
Override username for project operations |
SSS_PROJECT_OPEN |
Bypass project-wide open permission check (true/1) |
SSS_PROJECT_RENDER |
Bypass project-wide render permission check (true/1) |
SSS_DEVEL_MODE |
Enable experimental features (agent daemon) |
EDITOR / VISUAL |
Preferred editor for sss edit |
See docs/configuration.md for the full configuration reference.
Cryptographic primitives:
| Purpose | Algorithm |
|---|---|
| Authenticated encryption | XChaCha20-Poly1305 (via libsodium) |
| Key derivation | Argon2id |
| Key exchange | X25519 (crypto_box_seal) |
| Key exchange (hybrid, opt-in) | X448 + sntrup761 KEM (trelis, experimental) |
| Identity | Ed25519 |
| Nonce derivation | BLAKE2b keyed hash |
What is encrypted: the content inside β{...} / o+{...} markers only. File structure, key names, and surrounding text are not encrypted.
Nonce design: nonces are derived deterministically from the plaintext and key, which produces clean git diffs but reveals when a secret value changes.
Memory protection: decrypted key material is zeroised on drop via the zeroize crate.
Rate limiting: authentication attempts are rate-limited to mitigate brute-force attacks.
See docs/security-model.md for the full security model including Argon2id parameter levels, threat model, and key hierarchy. See docs/CRYPTOGRAPHY.md for detailed cryptographic implementation notes.
v2.0 note: The hybrid suite adds post-quantum key-wrapping (opt-in). trelis is experimental and unaudited. See docs/security-model.md and docs/CRYPTOGRAPHY.md for full details.
emacs/sss-mode.el (v1.1) is a single-file Emacs package providing transparent encryption for sss-sealed files.
Core behaviour (unchanged from v1.0):
- Sealed files (
β {...}) are automatically decrypted on open -- plaintextβ{...}markers are visible for editing - Re-sealed on save -- plaintext never touches disk
- Font-lock highlighting for open and sealed marker forms
- Mode-line indicator (
SSS[open]/SSS[sealed])
New in v1.1:
- Region encrypt/decrypt:
C-c C-e/C-c C-d - Toggle marker state at point:
C-c C-t - Preview decrypted secret at point (transient overlay):
C-c C-v - Overlay mode for visual marker highlighting (
sss-toggle-overlay-mode) - Auth-source integration -- passphrase cached via
~/.authinfo(no repeated prompts) - Transient command menu with
completing-readfallback:C-c C-m
Evil integration (when evil is loaded, sss-mode buffers only):
ge/gd/gt-- encrypt / decrypt / toggle operators (compose with any motion)is/as-- inner / outer SSS text objects (use withv,d,c, etc.)
Doom Emacs (when Doom is detected):
SPC e-- global leader prefix for encryption commands, e-- localleader prefix for sss-mode buffers
Installation (vanilla Emacs):
(add-to-list 'load-path "/path/to/sss/emacs/")
(require 'sss-mode)Doom Emacs setup: Copy emacs/sss-mode.el to ~/.config/doom/lisp/, then add to config.el:
(load! "lisp/sss-mode")See docs/sss-mode-guide.md for full installation options, daemon-mode configuration, key binding reference, and troubleshooting.
Mount a project directory with transparent rendering -- all files appear as plain text, git operations see the sealed originals.
sss mount <source-dir> <mountpoint>
sss mount --in-place # Overlay mount on current directory
sss mount --foreground <src> <mnt> # Run in foreground (don't daemonise)
sss mount --read-only <src> <mnt> # Read-only mountUse sss git from within a FUSE mount to run git commands against the underlying (sealed) directory:
sss git status
sss git commit -m "Update secrets"On Windows with WinFSP installed, the mount command provides the same transparent rendering:
sss mount <source-dir> <mountpoint>Build with cargo build --features winfsp --release.
Serve a project over a 9P network socket for cross-platform access.
sss serve9p tcp:0.0.0.0:564
sss serve9p unix:/tmp/sss-9p.sock
sss serve9p tcp:localhost:5640 -d /path/to/project -u aliceFile access modes via the 9P server:
| Path | View |
|---|---|
file |
Rendered (fully decrypted, markers stripped) |
file.open |
Opened (with β{...} markers) |
file.sealed |
Sealed (with β {...} markers, raw) |
sss-agent caches decrypted keys in memory with policy-based access control. Requires SSS_DEVEL_MODE=1.
export SSS_DEVEL_MODE=1
sss agent start # Start the agent daemon
sss agent start --foreground # Run in foreground
sss agent start --key-id <id> # Load a specific key
sss agent status # Check agent status
sss agent lock # Lock agent (deny all requests)
sss agent unlock # Unlock agent
sss agent stop # Stop the agent daemonPolicy management:
sss agent policies list # List all policies
sss agent policies add <hostname> # Allow a host
sss agent policies add <host> --project <path> # Restrict to a project
sss agent policies remove <hostname> # Remove a host
sss agent policies clear # Clear all policiesSymlink or copy the sss binary as ssse to get a transparent edit command. When invoked as ssse <file>, it automatically opens the file, launches your editor, and re-seals on save -- equivalent to sss edit <file>.
ln -s /path/to/sss /usr/local/bin/ssse
ssse config.txtRequirements: Rust 2024 edition (1.85+), libsodium (linked automatically by libsodium-sys)
cargo test # Run all tests
cargo test --lib # Unit tests only
cargo clippy -- -D warnings # LintingBinaries produced:
| Binary | Description |
|---|---|
sss |
Main CLI tool |
sss-agent |
Key management daemon (Unix) |
sss-askpass-tty |
TTY confirmation helper for agent |
sss-askpass-gui |
GUI confirmation helper for agent |
| Path | Description |
|---|---|
src/main.rs |
CLI definition and command routing |
src/lib.rs |
Library root |
src/crypto.rs |
Core cryptographic operations (libsodium bindings) |
src/processor/ |
Marker detection and transformation pipeline |
src/marker_inference/ |
Intelligent marker preservation for edited files |
src/commands/ |
CLI command handlers |
src/config.rs |
Project configuration (.sss.toml) |
src/config_manager.rs |
User settings management |
src/keystore.rs |
Local encrypted key storage |
src/keyring_support.rs |
System keyring integration |
src/secrets.rs |
Secrets file parsing and interpolation |
src/scanner.rs |
Project directory scanner with ignore patterns |
src/rotation.rs |
Key rotation and file re-encryption |
src/merge.rs |
Smart merge algorithm for marker inference |
src/validation.rs |
Input validation and DoS protection |
src/secure_memory.rs |
Memory protection and zeroisation |
src/editor.rs |
Editor integration for sss edit |
src/fuse_fs.rs |
FUSE filesystem implementation |
src/winfsp_fs.rs |
WinFSP filesystem implementation |
src/ninep_fs.rs |
9P server implementation |
src/agent.rs |
Agent daemon core |
src/agent_protocol.rs |
Agent wire protocol |
src/agent_policy.rs |
Agent policy engine |
src/audit_log.rs |
Agent audit logging |
src/rate_limiter.rs |
Authentication rate limiting |
src/kdf.rs |
Key derivation function parameters |
emacs/sss-mode.el |
Emacs integration package |
| Document | Description |
|---|---|
| docs/usage-guide.md | Common workflows: setup, seal/open/edit/render, key management, team collaboration, git hooks |
| docs/configuration.md | Configuration reference: .sss.toml, settings.toml, environment variables |
| docs/security-model.md | Security model: algorithms, key hierarchy, threat model including v2.0 hybrid suite |
| docs/marker-format.md | Marker syntax reference: BNF grammar, ciphertext payload format |
| docs/architecture.md | Technical architecture: processor pipeline, marker inference, FUSE, 9P |
| docs/sss-mode-guide.md | Emacs sss-mode installation and usage |
| docs/INSTALLATION.md | Detailed installation and development environment guide |
| docs/CRYPTOGRAPHY.md | Cryptographic implementation details |
| docs/KEY_MANAGEMENT.md | Key management guide |
| docs/SECRETS_FILE_FORMAT.md | Secrets file specification |
| docs/SECRETS_PARSING_GUIDE.md | Secrets file parsing and integration guide |
| docs/IGNORE_PATTERNS.md | Ignore pattern syntax and behaviour |
| ARCHITECTURE.md | Protocol specification |
| SECURITY.md | Security policy and vulnerability disclosure |
| CONTRIBUTING.md | Contribution guidelines |
| CHANGELOG.md | Version history |
| LICENCE | ISC licence |
Step-by-step guides for common scenarios:
| Tutorial | Description |
|---|---|
| docs/tutorials/01-getting-started.md | First-time setup and basic seal/open workflow |
| docs/tutorials/02-team-collaboration.md | Adding team members and sharing secrets |
| docs/tutorials/03-git-integration.md | Git hooks and version control workflow |
| docs/tutorials/04-editor-workflow.md | Editor integration (Emacs, ssse, $EDITOR) |
| docs/tutorials/05-fuse-mounting.md | FUSE filesystem transparent rendering |
| docs/tutorials/06-project-configuration.md | Project settings, ignore patterns, secrets files |
ISC -- see the LICENCE file for details.
- Built with libsodium for cryptographic operations
- FUSE support via fuser
- WinFSP support via winfsp-rs
- 9P server via pfpacket/rust-9p
- Diff algorithm via similar
- Multi-pattern matching via aho-corasick