secret/README.md
2025-05-29 08:21:05 -07:00

346 lines
11 KiB
Markdown

# 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