| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Secure secrets management with age encryption.
Seclusor is a library-first Rust project that lets developers, DevSecOps engineers, and integrators encrypt secrets with age. It provides a full CLI, secure runtime injection via seclusor run, and first-class bindings for Rust, Go, and TypeScript.
Important: While armored secrets can be stored in git, this is not always advisable. See App Note 01: Git Storage of Armored Secrets for the risk continuum and guidance by sensitivity level.
Lifecycle Phase: alpha | Current version: v0.2.2 (hidden terminal secret entry; drop-in for scripts) | See VERSION, CHANGELOG.md, and v0.2.2 notes
Secrets don't belong in plaintext, but they often need to live near the code that uses them. Common alternatives include:
Seclusor fills the gap for teams that want local-first, library-native, git-compatible secret management with strong defaults.
For guidance on storing armored files in git, see App Note 01. For runtime patterns see App Note 02.
After each GitHub release is published, package-manager formulas are updated.
First install:
# Homebrew
brew install 3leaps/tap/seclusor
# Scoop
scoop bucket add 3leaps https://github.com/3leaps/scoop-bucket
scoop install seclusorAlready installed:
brew upgrade seclusor
scoop update seclusorPlatform binaries, checksums, and detached signatures are published on the GitHub Releases page. Prefer verifying release assets with an expected public key or fingerprint (seclusor assets verify). See v0.2.2 announcement for the current-release one-pager.
[dependencies]
seclusor-crypto = "0.2" # encrypt/decrypt with age
seclusor-keyring = "0.2" # identity generation, recipient management
seclusor-core = "0.2" # domain types, validation
# Optional: add Ed25519 primitive sign/verify
seclusor-crypto = { version = "0.2", features = ["signing"] }
# Optional: add asset signature envelope support
seclusor-sign = "0.2"use seclusor_crypto::{encrypt, decrypt, load_identity_file};
// Encrypt a secret for one or more age recipients
let ciphertext = encrypt(b"example-secret-value-12345", &recipients)?;
// Decrypt using an identity file
let identities = load_identity_file("~/.config/seclusor/identity.txt")?;
let plaintext = decrypt(&ciphertext, &identities)?;Ed25519 primitive signing (requires features = ["signing"]):
use seclusor_crypto::{generate_signing_keypair, sign, verify};
let keypair = generate_signing_keypair()?;
let sig = sign(keypair.secret_key(), b"payload")?;
verify(keypair.public_key(), b"payload", &sig)?;
// Keys stored encrypted at rest — serialize the seed and encrypt with age
let seed_bytes = seclusor_crypto::signing_secret_key_to_bytes(keypair.secret_key());
let encrypted_key = encrypt(&seed_bytes, &recipients)?;Asset signing from the CLI:
seclusor keys signing generate \
--output ~/.config/seclusor/release-signing.key.age \
--recipient age1...
seclusor assets sign \
--input dist/seclusor.tar.gz \
--signing-key ~/.config/seclusor/release-signing.key.age \
--identity-file ~/.config/seclusor/identity.txt \
--signer-label release-signing \
--claimed-at 2026-05-17T12:00:00Z
seclusor assets verify \
--input dist/seclusor.tar.gz \
--public-key <base64url-public-key>Create a secrets file and run a command with injected environment variables (no secrets in shell history or process list):
# 1. Create identity (once)
seclusor keys age identity generate --output ~/.config/seclusor/identity.txt
# 2. Create and armor a simple secrets file
seclusor secrets init --output secrets.json --project myapp
# Prefer non-argv value channels so secrets stay out of shell history.
# Interactive: omit the pipe, type at the hidden Value: prompt, press Enter.
printf '%s' 'example-db-password-9xK7mP2qR8vT' | seclusor secrets set \
--file secrets.json \
--project myapp \
--key DB_PASSWORD \
--value-stdin \
--description "primary application database password"
seclusor secrets bundle encrypt --file secrets.json --output secrets.age --recipient age1...yourrecipient...
# 3. Run with injected secrets (contrived example)
seclusor secrets run \
--file secrets.age \
--identity-file ~/.config/seclusor/identity.txt \
--project myapp \
--allow 'DB_*' \
-- env | grep DB_Other access methods are supported: exporting to .env files, library calls, or building a simple secret server.
See the App Notes for detailed guidance.
| Code | Name | When |
|---|---|---|
| 0 | Success | Command completed successfully |
| 1 | Failure | Generic failure |
| 30 | ConfigInvalid | Configuration or document validation fail |
| 50 | FileNotFound | Required file not found |
Seclusor is a Rust workspace with seven crates. Library crates are the architecture — CLI and FFI are thin consumers.
seclusor/
├── crates/
│ ├── seclusor-core/ # Domain types, validation, env export/import
│ ├── seclusor-crypto/ # age encryption (X25519 + scrypt), Ed25519 signing (feature-gated)
│ ├── seclusor-sign/ # Detached asset signature envelopes
│ ├── seclusor-codec/ # Bundle + inline codecs, format conversion
│ ├── seclusor-keyring/ # Key generation, recipient discovery, rekey
│ ├── seclusor-ffi/ # C-ABI exports (cdylib + staticlib)
│ └── seclusor/ # CLI binary (thin adapter)
├── bindings/
│ ├── go/seclusor/ # Go CGo wrapper
│ └── typescript/ # TypeScript NAPI-RS addon
├── schemas/
│ └── seclusor/ # Versioned JSON Schemas (v1.0.0 and v1.1.0)
└── docs/
└── decisions/ # ADRs, SDRs, DDRs
seclusor-core ← leaf, no internal deps
↑
seclusor-crypto ← depends on core
↑
seclusor-sign ← depends on crypto
↑
seclusor-codec ← depends on core, crypto
seclusor-keyring ← depends on core, crypto
↑
seclusor-ffi ← depends on all library crates
seclusor (CLI) ← depends on all library crates
Bundle — Whole-file age encryption. The entire secrets document is a single opaque .age ciphertext. Best for: distribution, archival, environments where you want zero plaintext structure visible.
Inline — Per-field encryption with sec:age:v1:<base64> markers. The document structure (keys, project slugs) remains readable; only values are encrypted. Best for: git diffs, code review, config files where you need to see what's there without decrypting.
Convert between them freely:
seclusor secrets convert --input secrets.age --output secrets-inline.json --from bundle --to inline --identity-file ./identity.txt --recipient age1...
seclusor secrets convert --input secrets-inline.json --output secrets.age --from inline --to bundle --identity-file ./identity.txt --recipient age1...The Go bindings (bindings/go/seclusor) use CGo over the seclusor-ffi static library. Prebuilt static libraries for all supported platforms are committed to the repo and resolved at build time.
Current Go surface: plaintext and encrypted document loading, read-side secret document operations (List, Get, ExportEnv), bundle encrypt/decrypt, keyring management, and Ed25519 primitives. Encrypted mutation and asset-signing envelopes remain Rust/CLI surfaces in v0.2.0.
import "github.com/3leaps/seclusor/bindings/go/seclusor"
handle, err := seclusor.LoadSecretsJSON(string(jsonBytes))
if err != nil {
log.Fatal(err)
}
defer handle.Close()
keys, err := handle.List("")
env, err := handle.ExportEnv("", "", false)TypeScript bindings via NAPI-RS are in development.
The seclusor-ffi crate exposes a C-ABI surface using:
The FFI surface established in v0.1.0 is treated as stable for the v0.1.x line. Ed25519 signing was intentionally excluded from the first v0.1.1 FFI pass, then added in v0.1.2 after the Rust-side signing contract was reviewed. See ADR-0008 and ADR-0011 for the full contract and rationale.
Seclusor uses age (ADR-0002):
seclusor-sign adds detached asset signatures using the seclusor.signature.v1 envelope from DDR-0004:
The seclusor-crypto/signing feature provides the lower-level Ed25519 primitives (added in v0.1.1):
See ADR-0011, DDR-0002, and DDR-0004 for the full signing contracts.
See SDR-0002 for the secret input channel policy.
| Platform | Target | Status |
|---|---|---|
| Linux x64 (glibc) | x86_64-unknown-linux-gnu | Primary |
| Linux arm64 (glibc) | aarch64-unknown-linux-gnu | Primary |
| Linux x64 (musl) | x86_64-unknown-linux-musl | Supported |
| Linux arm64 (musl) | aarch64-unknown-linux-musl | Supported |
| macOS arm64 | aarch64-apple-darwin | Supported |
| Windows x64 | x86_64-pc-windows-msvc | Supported |
| Windows arm64 | aarch64-pc-windows-msvc | Supported |
# Build
cargo build
# Test
cargo test
# Final local PR gate
make pr-finalcargo deny check licenses
cargo auditSeclusor is part of the 3leaps platform library family:
| Library | Scope | Purpose |
|---|---|---|
| seclusor | Secrets management | Age encryption, secure runner, and cross-language library |
| ipcprims | Inter-process communication | Framed, multiplexed IPC primitives |
| sysprims | System operations | Process control and system interaction primitives |
Seclusor is a key dependency for the Lanyte secure agent platform, which uses seclusor-crypto and seclusor-keyring directly for session attestation and glassbreak credential handling.
Licensed under either of:
at your option.
Subject to 3 Leaps OSS policies.
See MAINTAINERS.md for governance and AGENTS.md for AI contributor protocols.
Built by the 3 Leaps team
Part of the Fulmen Ecosystem
| Back | FazBrowse Home | New Git URL |