# Secret - Hierarchical Secret Manager Secret is a modern, secure command-line secret manager that implements a hierarchical key architecture for storing and managing sensitive data. It supports multiple vaults, various unlock mechanisms, and provides secure storage using the Age encryption library. ## Core Architecture ### Three-Layer Key Hierarchy Secret implements a sophisticated three-layer key architecture: 1. **Long-term Keys**: Derived from BIP39 mnemonic phrases, these provide the foundation for all encryption 2. **Unlock Keys**: Short-term keys that encrypt the long-term keys, supporting multiple authentication methods 3. **Secret-specific Keys**: Per-secret keys that encrypt individual secret values ### Vault System Vaults provide logical separation of secrets, each with its own long-term key and unlock key set. This allows for complete isolation between different contexts (work, personal, projects). ## Installation Build from source: ```bash git clone cd secret make build ``` ## Quick Start 1. **Initialize the secret manager**: ```bash secret init ``` This creates the default vault and prompts for a BIP39 mnemonic phrase. 2. **Generate a mnemonic** (if needed): ```bash secret generate mnemonic ``` 3. **Add a secret**: ```bash echo "my-password" | secret add myservice/password ``` 4. **Retrieve a secret**: ```bash secret get myservice/password ``` ## Commands Reference ### Initialization #### `secret init` Initializes the secret manager with a default vault. Prompts for a BIP39 mnemonic phrase and creates the initial directory structure. **Environment Variables:** - `SB_SECRET_MNEMONIC`: Pre-set mnemonic phrase - `SB_UNLOCK_PASSPHRASE`: Pre-set unlock passphrase ### Vault Management #### `secret vault list [--json]` Lists all available vaults. #### `secret vault create ` Creates a new vault with the specified name. #### `secret vault select ` Switches to the specified vault for subsequent operations. ### Secret Management #### `secret add [--force]` Adds a secret to the current vault. Reads the secret value from stdin. - `--force, -f`: Overwrite existing secret **Secret Name Format:** `[a-z0-9\.\-\_\/]+` - Forward slashes (`/`) are converted to percent signs (`%`) for storage - Examples: `database/password`, `api.key`, `ssh_private_key` #### `secret get ` Retrieves and outputs a secret value to stdout. #### `secret list [filter] [--json]` / `secret ls` Lists all secrets in the current vault. Optional filter for substring matching. ### Key Generation #### `secret generate mnemonic` Generates a cryptographically secure BIP39 mnemonic phrase. #### `secret generate secret [--length=16] [--type=base58] [--force]` Generates and stores a random secret. - `--length, -l`: Length of generated secret (default: 16) - `--type, -t`: Type of secret (`base58`, `alnum`) - `--force, -f`: Overwrite existing secret ### Unlock Key Management #### `secret keys list [--json]` Lists all unlock keys in the current vault with their metadata. #### `secret keys add [options]` Creates a new unlock key of the specified type: **Types:** - `passphrase`: Password-protected unlock key - `keychain`: macOS Keychain unlock key (Touch ID/Face ID) - `pgp`: GPG/PGP key unlock key **Options:** - `--keyid `: GPG key ID (required for PGP type) #### `secret keys rm ` Removes an unlock key from the current vault. #### `secret key select ` Selects an unlock key as the current default for operations. ### Import Operations #### `secret import --source ` Imports a secret from a file and stores it in the current vault under the given name. #### `secret vault import [vault-name]` Imports a mnemonic phrase into the specified vault (defaults to "default"). #### `secret enroll` Enrolls a macOS Keychain unlock key for biometric authentication. ### Encryption Operations #### `secret encrypt [--input=file] [--output=file]` Encrypts data using an Age key stored as a secret. If the secret doesn't exist, generates a new Age key. #### `secret decrypt [--input=file] [--output=file]` Decrypts data using an Age key stored as a secret. ## Storage Architecture ### Directory Structure ``` $BASE/ # ~/.config/berlin.sneak.pkg.secret (Linux) or ~/Library/Application Support/berlin.sneak.pkg.secret (macOS) ├── configuration.json # Global configuration ├── currentvault -> vaults.d/default # Symlink to current vault └── vaults.d/ ├── default/ # Default vault │ ├── vault-metadata.json # Vault metadata │ ├── pub.age # Long-term public key │ ├── current-unlock-key -> unlock.d/passphrase # Current unlock key symlink │ ├── unlock.d/ # Unlock keys directory │ │ ├── passphrase/ # Passphrase unlock key │ │ │ ├── unlock-metadata.json # Unlock key metadata │ │ │ ├── pub.age # Unlock key public key │ │ │ ├── priv.age # Unlock key private key (encrypted) │ │ │ └── longterm.age # Long-term private key (encrypted to this unlock key) │ │ ├── keychain/ # Keychain unlock key │ │ │ ├── unlock-metadata.json │ │ │ ├── pub.age │ │ │ ├── priv.age │ │ │ └── longterm.age │ │ └── pgp/ # PGP unlock key │ │ ├── unlock-metadata.json │ │ ├── pub.age │ │ ├── priv.asc # PGP-encrypted private key │ │ └── longterm.age │ └── secrets.d/ # Secrets directory │ ├── my-service%password/ # Secret directory (slashes encoded as %) │ │ ├── value.age # Encrypted secret value │ │ ├── pub.age # Secret-specific public key │ │ ├── priv.age # Secret-specific private key (encrypted to long-term key) │ │ └── secret-metadata.json # Secret metadata │ └── api%keys%production/ │ ├── value.age │ ├── pub.age │ ├── priv.age │ └── secret-metadata.json └── work/ # Additional vault └── ... (same structure as default) ``` ### Key Management and Encryption Flow #### Long-term Keys - **Source**: Derived from BIP39 mnemonic phrases using hierarchical deterministic (HD) key derivation - **Purpose**: Master keys for each vault, used to encrypt secret-specific keys - **Storage**: Public key stored as `pub.age`, private key encrypted by unlock keys #### Unlock Keys Unlock keys provide different authentication methods to access the long-term keys: 1. **Passphrase Unlock Keys**: - Private key encrypted using a user-provided passphrase - Stored as encrypted Age identity in `priv.age` 2. **macOS Keychain Keys**: - Private key stored in the macOS Keychain - Requires biometric authentication (Touch ID/Face ID) - Provides hardware-backed security 3. **PGP Unlock Keys**: - Private key encrypted using an existing GPG key - Compatible with hardware tokens (YubiKey, etc.) - Stored as PGP-encrypted data in `priv.asc` #### Secret-specific Keys - Each secret has its own encryption key pair - Private key encrypted to the vault's long-term key - Provides forward secrecy and granular access control ### Environment Variables - `SB_SECRET_STATE_DIR`: Custom state directory location - `SB_SECRET_MNEMONIC`: Pre-set mnemonic phrase (avoids interactive prompt) - `SB_UNLOCK_PASSPHRASE`: Pre-set unlock passphrase (avoids interactive prompt) - `SB_GPG_KEY_ID`: GPG key ID for PGP unlock keys ## Security Features ### Encryption - Uses the [Age encryption library](https://age-encryption.org/) with X25519 keys - All private keys are encrypted at rest - No plaintext secrets stored on disk ### Access Control - Multiple authentication methods supported - Hierarchical key architecture provides defense in depth - Vault isolation prevents cross-contamination ### Forward Secrecy - Per-secret encryption keys limit exposure if compromised - Long-term keys protected by multiple unlock key layers ### Hardware Integration - macOS Keychain support for biometric authentication - Hardware token support via PGP/GPG integration ## Examples ### Basic Workflow ```bash # Initialize with a new mnemonic secret generate mnemonic # Copy the output secret init # Paste the mnemonic when prompted # Add some secrets echo "supersecret123" | secret add database/prod/password echo "api-key-xyz" | secret add services/api/key echo "ssh-private-key-content" | secret add ssh/servers/web01 # List and retrieve secrets secret list secret get database/prod/password secret get services/api/key ``` ### Multi-vault Setup ```bash # Create separate vaults for different contexts secret vault create work secret vault create personal # Work with work vault secret vault select work echo "work-db-pass" | secret add database/password secret keys add keychain # Add Touch ID authentication # Switch to personal vault secret vault select personal echo "personal-email-pass" | secret add email/password # List all vaults secret vault list ``` ### Advanced Authentication ```bash # Add multiple unlock methods secret keys add passphrase # Password-based secret keys add keychain # Touch ID (macOS only) secret keys add pgp --keyid ABCD1234 # GPG key # List unlock keys secret keys list # Select a specific unlock key secret key select ``` ### Encryption/Decryption with Age Keys ```bash # Generate an Age key and store it as a secret secret generate secret encryption/mykey # Encrypt a file using the stored key secret encrypt encryption/mykey --input document.txt --output document.txt.age # Decrypt the file secret decrypt encryption/mykey --input document.txt.age --output document.txt ``` ## Technical Details ### Cryptographic Primitives - **Key Derivation**: BIP32/BIP39 hierarchical deterministic key derivation - **Encryption**: Age (X25519 + ChaCha20-Poly1305) - **Key Exchange**: X25519 elliptic curve Diffie-Hellman - **Authentication**: Poly1305 MAC ### File Formats - **Age Files**: Standard Age encryption format (.age extension) - **Metadata**: JSON format with timestamps and type information - **Configuration**: JSON configuration files ### Cross-Platform Support - **macOS**: Full support including Keychain integration - **Linux**: Full support (excluding Keychain features) - **Windows**: Basic support (filesystem operations only) ## Security Considerations ### Threat Model - Protects against unauthorized access to secret values - Provides defense against compromise of individual components - Supports hardware-backed authentication where available ### Best Practices 1. Use strong, unique passphrases for unlock keys 2. Enable hardware authentication (Keychain, hardware tokens) when available 3. Regularly audit unlock keys and remove unused ones 4. Keep mnemonic phrases securely backed up offline 5. Use separate vaults for different security contexts ### Limitations - Requires access to unlock keys for secret retrieval - Mnemonic phrases must be securely stored and backed up - Hardware features limited to supported platforms ## Development ### Building ```bash make build # Build binary make test # Run tests make lint # Run linter ``` ### Testing The project includes comprehensive tests: ```bash ./test_secret_manager.sh # Full integration test suite go test ./... # Unit tests ```