add secret versioning support

This commit is contained in:
2025-06-08 22:07:19 -07:00
parent f59ee4d2d6
commit fbda2d91af
16 changed files with 2451 additions and 1608 deletions

View File

@@ -10,7 +10,15 @@ 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. **Unlockers**: 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
3. **Version-specific Keys**: Per-version keys that encrypt individual secret values
### Version Management
Each secret maintains a history of versions, with each version having:
- Its own encryption key pair
- Encrypted metadata including creation time and validity period
- Immutable value storage
- Atomic version switching via symlink updates
### Vault System
@@ -80,12 +88,21 @@ Adds a secret to the current vault. Reads the secret value from stdin.
- Forward slashes (`/`) are converted to percent signs (`%`) for storage
- Examples: `database/password`, `api.key`, `ssh_private_key`
#### `secret get <secret-name>`
#### `secret get <secret-name> [--version <version>]`
Retrieves and outputs a secret value to stdout.
- `--version, -v`: Get a specific version (default: current)
#### `secret list [filter] [--json]` / `secret ls`
Lists all secrets in the current vault. Optional filter for substring matching.
### Version Management
#### `secret version list <secret-name>`
Lists all versions of a secret showing creation time, status, and validity period.
#### `secret version promote <secret-name> <version>`
Promotes a specific version to current by updating the symlink. Does not modify any timestamps, allowing for rollback scenarios.
### Key Generation
#### `secret generate mnemonic`
@@ -147,7 +164,17 @@ Decrypts data using an Age key stored as a secret.
│ │ │ └── pgp/ # PGP unlocker
│ │ ├── secrets.d/
│ │ │ ├── api%key/ # Secret: api/key
│ │ │ │ ├── versions/
│ │ │ │ │ ├── 20231215.001/ # Version directory
│ │ │ │ │ │ ├── pub.age # Version public key
│ │ │ │ │ │ ├── priv.age # Version private key (encrypted)
│ │ │ │ │ │ ├── value.age # Encrypted value
│ │ │ │ │ │ └── metadata.age # Encrypted metadata
│ │ │ │ │ └── 20231216.001/ # Another version
│ │ │ │ └── current -> versions/20231216.001
│ │ │ └── database%password/ # Secret: database/password
│ │ │ ├── versions/
│ │ │ └── current -> versions/20231215.001
│ │ └── current-unlocker -> ../unlockers.d/passphrase
│ └── work/
│ ├── unlockers.d/
@@ -204,8 +231,10 @@ Each vault maintains its own set of unlockers and one long-term key. The long-te
- Vault isolation prevents cross-contamination
### Forward Secrecy
- Per-secret encryption keys limit exposure if compromised
- Per-version encryption keys limit exposure if compromised
- Each version is independently encrypted
- Long-term keys protected by multiple unlocker layers
- Historical versions remain encrypted with their original keys
### Hardware Integration
- Hardware token support via PGP/GPG integration