# 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 <repository> cd secret go build -o secret ./cmd/secret ``` ## 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 <name>` Creates a new vault with the specified name. #### `secret vault select <name>` Switches to the specified vault for subsequent operations. ### Secret Management #### `secret add <secret-name> [--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 <secret-name>` 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 <name> [--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 <type> [options]` Creates a new unlock key of the specified type: **Types:** - `passphrase`: Traditional passphrase-protected unlock key - `keychain`: macOS Keychain-protected unlock key (macOS only) - `pgp`: Uses an existing GPG key for encryption/decryption **Options:** - `--keyid <id>`: GPG key ID (required for PGP type) #### `secret keys rm <key-id>` Removes an unlock key. #### `secret key select <key-id>` Selects an unlock key as the current default for operations. ### Import Operations #### `secret import <secret-name> --source <filename>` 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"). ### Encryption Operations #### `secret encrypt <secret-name> [--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 <secret-name> [--input=file] [--output=file]` Decrypts data using an Age key stored as a secret. ## Storage Architecture ### Directory Structure ``` ~/.local/share/secret/ ├── vaults.d/ │ ├── default/ │ │ ├── unlock-keys.d/ │ │ │ ├── passphrase/ # Passphrase unlock key │ │ │ ├── keychain/ # Keychain unlock key (macOS) │ │ │ └── pgp/ # PGP unlock key │ │ ├── secrets.d/ │ │ │ ├── api%key/ # Secret: api/key │ │ │ └── database%password/ # Secret: database/password │ │ └── current-unlock-key -> ../unlock-keys.d/passphrase │ └── work/ │ ├── unlock-keys.d/ │ ├── secrets.d/ │ └── current-unlock-key ├── currentvault -> vaults.d/default └── configuration.json ``` ### 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 Keys**: - Encrypted with user-provided passphrase - Stored as encrypted Age keys - Cross-platform compatible 2. **Keychain Keys** (macOS only): - Uses macOS Keychain for secure storage - Provides seamless authentication on macOS systems - Age private key encrypted with random passphrase stored in Keychain 3. **PGP Keys**: - Uses existing GPG key infrastructure - Leverages existing key management workflows - Strong authentication through GPG Each vault maintains its own set of unlock keys and one long-term key. The long-term key is encrypted to each unlock key, allowing any authorized unlock key to access vault secrets. #### 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 ### Platform Integration - macOS Keychain integration for seamless authentication - GPG integration for existing key management workflows ## 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 passphrase # Add passphrase 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 # macOS Keychain (macOS only) secret keys add pgp --keyid ABCD1234 # GPG key # List unlock keys secret keys list # Select a specific unlock key secret key select <key-id> ``` ### 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 platform-specific authentication where available ### Best Practices 1. Use strong, unique passphrases for unlock keys 2. Enable platform-specific authentication (Keychain) 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 - Platform-specific features limited to supported platforms ## Development ### Building ```bash go build -o secret ./cmd/secret # Build binary go test ./... # Run tests go vet ./... # Run static analysis ``` ### Testing The project includes comprehensive tests: ```bash ./test_secret_manager.sh # Full integration test suite go test ./... # Unit tests ``` ## Features - **Multiple Authentication Methods**: Supports passphrase-based, keychain-based (macOS), and PGP-based unlock keys - **Vault Isolation**: Complete separation between different vaults - **Per-Secret Encryption**: Each secret has its own encryption key - **BIP39 Mnemonic Support**: Keyless operation using mnemonic phrases - **Cross-Platform**: Works on macOS, Linux, and other Unix-like systems