lsh-framework 2.3.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +200 -832
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,975 +1,350 @@
|
|
|
1
|
-
# LSH - Encrypted Secrets Manager
|
|
1
|
+
# LSH v3.0.0 - Encrypted Secrets Manager
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**The simplest way to sync `.env` files across all your machines.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`lsh` is an encrypted secrets manager that syncs your environment files across development machines with AES-256 encryption via the IPFS network. Push once, pull anywhere.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
[](https://badge.fury.io/js/lsh-framework)
|
|
8
|
+
[](https://github.com/gwicho38/lsh/actions/workflows/node.js.yml)
|
|
9
|
+
[](https://opensource.org/licenses/MIT)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
- **Encrypted sync** with AES-256 encryption before upload
|
|
13
|
-
- **Automatic rotation** with built-in daemon scheduling
|
|
14
|
-
- **Team collaboration** with shared encryption keys
|
|
15
|
-
- **Multi-environment** support (dev/staging/prod)
|
|
16
|
-
- **Local-first** - works offline, graceful fallback to local cache
|
|
17
|
-
- **Free & Open Source** - no per-seat pricing, 5GB free tier on Storacha
|
|
11
|
+
## What's New in v3.0.0
|
|
18
12
|
|
|
19
|
-
**
|
|
13
|
+
- **Registry Fallback** - Pull now automatically checks the Storacha registry when local metadata is missing
|
|
14
|
+
- **Improved Error Messages** - Clear, actionable error messages with environment context
|
|
15
|
+
- **One-Command Setup** - `lsh init` handles everything with interactive prompts
|
|
16
|
+
- **Zero-Config IPFS Sync** - Storacha network enabled by default after email authentication
|
|
17
|
+
- **Smart Environment Detection** - Automatic repository-based namespacing
|
|
20
18
|
|
|
21
19
|
## Quick Start
|
|
22
20
|
|
|
23
|
-
**New to LSH?** Choose your sync method:
|
|
24
|
-
- **Storacha (IPFS network)** - One-time email auth, automatic multi-host sync (NEW in v2.1.0!)
|
|
25
|
-
- **Local storage** - Zero config, works offline, encrypted at `~/.lsh/secrets-cache/`
|
|
26
|
-
- **Supabase** - Team collaboration with audit logs and role-based access
|
|
27
|
-
|
|
28
|
-
### Quick Install (Works Immediately!)
|
|
29
|
-
|
|
30
21
|
```bash
|
|
31
|
-
# Install
|
|
22
|
+
# Install
|
|
32
23
|
npm install -g lsh-framework
|
|
33
24
|
|
|
34
|
-
#
|
|
35
|
-
|
|
36
|
-
# Secrets: ~/.lsh/secrets-cache/ (encrypted IPFS storage)
|
|
37
|
-
# Metadata: ~/.lsh/secrets-metadata.json
|
|
38
|
-
|
|
39
|
-
# Start using it right away
|
|
40
|
-
lsh --version
|
|
41
|
-
lsh config # Edit configuration (optional)
|
|
42
|
-
lsh daemon start
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### Smart Sync (Easiest Way!)
|
|
25
|
+
# Interactive setup (recommended)
|
|
26
|
+
lsh init
|
|
46
27
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
npm install -g lsh-framework
|
|
50
|
-
|
|
51
|
-
# 2. ONE command does everything!
|
|
52
|
-
cd ~/repos/your-project
|
|
28
|
+
# Or quick start
|
|
29
|
+
cd ~/your-project
|
|
53
30
|
lsh sync
|
|
54
|
-
|
|
55
|
-
# That's it! Smart Sync:
|
|
56
|
-
# ✅ Auto-generates encryption key
|
|
57
|
-
# ✅ Creates .env from .env.example
|
|
58
|
-
# ✅ Adds .env to .gitignore
|
|
59
|
-
# ✅ Stores encrypted secrets locally via IPFS
|
|
60
|
-
# ✅ Namespaces by repo name
|
|
61
|
-
# ✅ Works completely offline
|
|
62
31
|
```
|
|
63
32
|
|
|
64
|
-
|
|
33
|
+
That's it! Your secrets are now encrypted and synced.
|
|
65
34
|
|
|
66
|
-
|
|
67
|
-
# Sync and load secrets into current shell
|
|
68
|
-
eval "$(lsh sync --load)"
|
|
35
|
+
## Why LSH?
|
|
69
36
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
37
|
+
| Feature | LSH | dotenv-vault | 1Password | Doppler |
|
|
38
|
+
|---------|-----|--------------|-----------|---------|
|
|
39
|
+
| **Free** | Yes | Limited | No | No |
|
|
40
|
+
| **Self-Hosted** | Yes | No | No | No |
|
|
41
|
+
| **Auto Rotation** | Built-in | No | No | No |
|
|
42
|
+
| **IPFS Storage** | Yes | No | No | No |
|
|
43
|
+
| **Setup Time** | 2 min | 5 min | 10 min | 10 min |
|
|
73
44
|
|
|
74
|
-
|
|
45
|
+
## Core Commands
|
|
75
46
|
|
|
76
47
|
```bash
|
|
77
|
-
#
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# 2. Generate encryption key (for team sharing)
|
|
81
|
-
lsh key
|
|
82
|
-
# Add the output to your .env:
|
|
83
|
-
# LSH_SECRETS_KEY=<your-key>
|
|
48
|
+
# Setup
|
|
49
|
+
lsh init # Interactive setup wizard
|
|
50
|
+
lsh key # Generate encryption key
|
|
84
51
|
|
|
85
|
-
#
|
|
86
|
-
lsh push
|
|
52
|
+
# Daily use
|
|
53
|
+
lsh push # Upload encrypted .env to cloud
|
|
54
|
+
lsh pull # Download .env from cloud
|
|
55
|
+
lsh sync # Smart sync (auto push/pull)
|
|
56
|
+
lsh list # List local secrets
|
|
57
|
+
lsh env # List cloud environments
|
|
87
58
|
|
|
88
|
-
#
|
|
89
|
-
lsh
|
|
59
|
+
# Get/Set individual secrets
|
|
60
|
+
lsh get API_KEY # Get a secret value
|
|
61
|
+
lsh set API_KEY xxx # Set a secret value
|
|
62
|
+
printenv | lsh set # Batch import from stdin
|
|
90
63
|
|
|
91
|
-
#
|
|
92
|
-
|
|
64
|
+
# Multi-environment
|
|
65
|
+
lsh push --env prod
|
|
66
|
+
lsh pull --env staging
|
|
93
67
|
```
|
|
94
68
|
|
|
95
|
-
##
|
|
96
|
-
|
|
97
|
-
### 🚀 Smart Sync (New in v0.8.2!)
|
|
69
|
+
## How It Works
|
|
98
70
|
|
|
99
|
-
**One command. Zero configuration. Automatic everything.**
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
cd ~/repos/my-app
|
|
103
|
-
lsh sync # Auto-setup and sync
|
|
104
|
-
eval "$(lsh sync --load)" # Sync AND load into shell
|
|
105
71
|
```
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
cd ~/repos/app1
|
|
119
|
-
lsh sync # Stored as: app1_dev
|
|
120
|
-
|
|
121
|
-
cd ~/repos/app2
|
|
122
|
-
lsh sync # Stored as: app2_dev (separate!)
|
|
123
|
-
|
|
124
|
-
# See what's tracked in the current directory
|
|
125
|
-
lsh info
|
|
72
|
+
Your Machine Storacha (IPFS Network)
|
|
73
|
+
┌─────────────┐ ┌─────────────────────┐
|
|
74
|
+
│ .env │ AES-256 │ Encrypted Blob │
|
|
75
|
+
│ (secrets) │ ───encrypt───► │ (content-addressed)│
|
|
76
|
+
└─────────────┘ └─────────────────────┘
|
|
77
|
+
│
|
|
78
|
+
▼
|
|
79
|
+
Another Machine ┌─────────────────────┐
|
|
80
|
+
┌─────────────┐ AES-256 │ Registry │
|
|
81
|
+
│ .env │ ◄──decrypt──── │ (points to blob) │
|
|
82
|
+
│ (secrets) │ └─────────────────────┘
|
|
83
|
+
└─────────────┘
|
|
126
84
|
```
|
|
127
85
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
Name: myapp
|
|
134
|
-
Branch: main
|
|
135
|
-
|
|
136
|
-
🔐 Environment Tracking:
|
|
137
|
-
Base environment: dev
|
|
138
|
-
Cloud storage name: myapp_dev
|
|
139
|
-
Namespace: myapp
|
|
140
|
-
ℹ️ Repo-based isolation enabled
|
|
141
|
-
|
|
142
|
-
📄 Local .env File:
|
|
143
|
-
Keys: 12
|
|
144
|
-
Has encryption key: ✅
|
|
145
|
-
|
|
146
|
-
☁️ Cloud Storage:
|
|
147
|
-
Environment: myapp_dev
|
|
148
|
-
Keys stored: 12
|
|
149
|
-
Last updated: 11/6/2025, 10:15:23 PM
|
|
150
|
-
Key matches: ✅
|
|
151
|
-
```
|
|
86
|
+
1. Your `.env` is encrypted locally with AES-256
|
|
87
|
+
2. Encrypted data uploads to IPFS via Storacha
|
|
88
|
+
3. A registry tracks the latest version per repository
|
|
89
|
+
4. Other machines pull via the content ID (CID)
|
|
90
|
+
5. Decryption happens locally with your shared key
|
|
152
91
|
|
|
153
|
-
|
|
92
|
+
## Installation
|
|
154
93
|
|
|
155
|
-
###
|
|
94
|
+
### Prerequisites
|
|
95
|
+
- Node.js 20.18.0+
|
|
96
|
+
- npm 10.0.0+
|
|
156
97
|
|
|
157
|
-
|
|
98
|
+
### Install from npm
|
|
158
99
|
|
|
159
100
|
```bash
|
|
160
|
-
|
|
161
|
-
lsh
|
|
162
|
-
✅ Pushed 60 secrets from .env to Supabase
|
|
163
|
-
📝 Recorded on IPFS: ipfs://bafkreiabc123...
|
|
164
|
-
View: https://ipfs.io/ipfs/bafkreiabc123...
|
|
165
|
-
|
|
166
|
-
# View sync history
|
|
167
|
-
lsh sync-history show
|
|
168
|
-
|
|
169
|
-
📊 Sync History for: myproject/dev
|
|
170
|
-
|
|
171
|
-
2025-11-20 21:00:00 push 60 keys myproject/dev
|
|
172
|
-
2025-11-20 20:45:00 pull 60 keys myproject/dev
|
|
173
|
-
2025-11-20 20:30:00 push 58 keys myproject/dev
|
|
174
|
-
|
|
175
|
-
📦 Total: 3 records
|
|
176
|
-
🔒 All records are permanently stored on IPFS
|
|
101
|
+
npm install -g lsh-framework
|
|
102
|
+
lsh --version
|
|
177
103
|
```
|
|
178
104
|
|
|
179
|
-
|
|
180
|
-
- ✅ **Zero Config** - Works automatically, no setup required
|
|
181
|
-
- ✅ **Content-Addressed** - IPFS-style CIDs for each record
|
|
182
|
-
- ✅ **Privacy-First** - Only metadata, never secret values
|
|
183
|
-
- ✅ **Immutable** - Content cannot change without changing CID
|
|
184
|
-
- ✅ **Opt-Out** - Disable with `lsh config set DISABLE_IPFS_SYNC true`
|
|
185
|
-
|
|
186
|
-
**What's Recorded:**
|
|
187
|
-
- Timestamp, command, action type (push/pull)
|
|
188
|
-
- Number of keys synced
|
|
189
|
-
- Git repo, branch, environment name
|
|
190
|
-
- Key fingerprint (hash only, not actual key)
|
|
191
|
-
- Machine ID (anonymized hash)
|
|
105
|
+
### First-Time Setup
|
|
192
106
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
- ❌ File contents or variable names
|
|
197
|
-
|
|
198
|
-
See [IPFS Sync Records Documentation](docs/features/IPFS_SYNC_RECORDS.md) for complete details.
|
|
107
|
+
```bash
|
|
108
|
+
# Interactive setup (handles everything)
|
|
109
|
+
lsh init
|
|
199
110
|
|
|
200
|
-
|
|
111
|
+
# Or manual setup:
|
|
112
|
+
lsh key # Generate encryption key
|
|
113
|
+
echo "LSH_SECRETS_KEY=..." >> .env
|
|
114
|
+
lsh push # Push to cloud
|
|
115
|
+
```
|
|
201
116
|
|
|
202
|
-
|
|
117
|
+
## Multi-Host Sync
|
|
203
118
|
|
|
204
|
-
|
|
119
|
+
**The killer feature.** Sync secrets across all your machines:
|
|
205
120
|
|
|
206
121
|
```bash
|
|
207
|
-
#
|
|
208
|
-
lsh storacha login [email protected]
|
|
209
|
-
# ✅ Email verification → payment plan → space created automatically
|
|
210
|
-
|
|
211
|
-
# Push secrets (automatic network sync)
|
|
122
|
+
# Machine 1: Push secrets
|
|
212
123
|
cd ~/repos/my-project
|
|
213
|
-
lsh push
|
|
214
|
-
# 📤 Uploaded to Storacha: bafkrei...
|
|
215
|
-
# ☁️ Synced to IPFS network
|
|
216
|
-
|
|
217
|
-
# On Host B (Linux server) - One-time setup
|
|
218
|
-
lsh storacha login [email protected]
|
|
124
|
+
lsh push
|
|
219
125
|
|
|
220
|
-
# Pull secrets (
|
|
126
|
+
# Machine 2: Pull secrets (same encryption key)
|
|
221
127
|
cd ~/repos/my-project
|
|
222
|
-
lsh pull
|
|
223
|
-
# 📥 Downloading from Storacha: bafkrei...
|
|
224
|
-
# ✅ Downloaded from IPFS network
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
**Features:**
|
|
228
|
-
- ✅ **Default enabled** - Works automatically after authentication
|
|
229
|
-
- ✅ **One-time setup** - Just authenticate with email per machine
|
|
230
|
-
- ✅ **Encrypted before upload** - AES-256 encryption (secrets never leave your machine unencrypted)
|
|
231
|
-
- ✅ **Graceful fallback** - Uses local cache if network unavailable
|
|
232
|
-
- ✅ **Content-addressed** - IPFS CIDs ensure tamper-proof integrity
|
|
233
|
-
- ✅ **Free tier** - 5GB storage on Storacha's free plan
|
|
234
|
-
|
|
235
|
-
**How it works:**
|
|
236
|
-
1. Your secrets are encrypted locally with `LSH_SECRETS_KEY`
|
|
237
|
-
2. Encrypted data is uploaded to IPFS via Storacha
|
|
238
|
-
3. On another machine, LSH downloads from IPFS using the content ID (CID)
|
|
239
|
-
4. Secrets are decrypted locally with the same encryption key
|
|
240
|
-
5. Local cache speeds up offline access
|
|
241
|
-
|
|
242
|
-
**Check status:**
|
|
243
|
-
```bash
|
|
244
|
-
lsh storacha status
|
|
245
|
-
# 🔐 Authentication: ✅ Authenticated
|
|
246
|
-
# 🌐 Network Sync: ✅ Enabled
|
|
247
|
-
# 📦 Spaces: lsh-secrets (current)
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
**Disable network sync (local cache only):**
|
|
251
|
-
```bash
|
|
252
|
-
lsh storacha disable
|
|
253
|
-
# Or set environment variable:
|
|
254
|
-
export LSH_STORACHA_ENABLED=false
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### 🔐 Secrets Management
|
|
258
|
-
|
|
259
|
-
- **AES-256 Encryption** - Military-grade encryption for all secrets
|
|
260
|
-
- **Multi-Environment** - Separate configs for dev, staging, and production
|
|
261
|
-
- **Team Sync** - Share encryption keys securely with your team
|
|
262
|
-
- **Masked Viewing** - View secrets safely without exposing full values
|
|
263
|
-
- **Automatic Backup** - Never lose your `.env` files
|
|
264
|
-
- **Version Control** - Track changes to your secrets over time
|
|
265
|
-
- **Smart Sync** - Auto-setup with git repo detection (v0.8.2+)
|
|
266
|
-
|
|
267
|
-
### 🔄 Automatic Rotation (Unique Feature!)
|
|
268
|
-
|
|
269
|
-
Use the built-in daemon to automatically rotate secrets on a schedule:
|
|
270
|
-
|
|
271
|
-
```bash
|
|
272
|
-
# Schedule API key rotation every 30 days
|
|
273
|
-
lsh cron add \
|
|
274
|
-
--name "rotate-api-keys" \
|
|
275
|
-
--schedule "0 0 1 * *" \
|
|
276
|
-
--command "./scripts/rotate-keys.sh && lsh push"
|
|
128
|
+
lsh pull
|
|
277
129
|
|
|
278
|
-
#
|
|
279
|
-
lsh cron add \
|
|
280
|
-
--name "sync-secrets" \
|
|
281
|
-
--interval 3600 \
|
|
282
|
-
--command "lsh pull && ./scripts/reload-app.sh"
|
|
130
|
+
# That's it - your .env is synced!
|
|
283
131
|
```
|
|
284
132
|
|
|
285
|
-
|
|
133
|
+
### First-Time on New Machine
|
|
286
134
|
|
|
287
|
-
### 👥 Team Collaboration
|
|
288
|
-
|
|
289
|
-
**Setup (One Time):**
|
|
290
135
|
```bash
|
|
291
|
-
#
|
|
292
|
-
|
|
293
|
-
lsh push --env prod # Push team secrets
|
|
294
|
-
# Share LSH_SECRETS_KEY via 1Password
|
|
295
|
-
```
|
|
136
|
+
# 1. Install LSH
|
|
137
|
+
npm install -g lsh-framework
|
|
296
138
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
# 1. Get key from 1Password
|
|
300
|
-
# 2. Add to .env
|
|
301
|
-
echo "LSH_SECRETS_KEY=<shared-key>" > .env
|
|
139
|
+
# 2. Authenticate with Storacha (one-time)
|
|
140
|
+
lsh storacha login your@email.com
|
|
302
141
|
|
|
303
|
-
# 3.
|
|
304
|
-
|
|
142
|
+
# 3. Add your encryption key
|
|
143
|
+
echo "LSH_SECRETS_KEY=your-shared-key" > .env
|
|
305
144
|
|
|
306
|
-
# 4.
|
|
307
|
-
|
|
145
|
+
# 4. Pull secrets
|
|
146
|
+
lsh pull
|
|
308
147
|
```
|
|
309
148
|
|
|
310
|
-
|
|
149
|
+
## Multi-Environment Support
|
|
311
150
|
|
|
312
151
|
```bash
|
|
313
152
|
# Development
|
|
314
153
|
lsh push --env dev
|
|
315
154
|
|
|
316
|
-
# Staging
|
|
155
|
+
# Staging
|
|
317
156
|
lsh push --file .env.staging --env staging
|
|
318
157
|
|
|
319
|
-
# Production
|
|
320
|
-
lsh push --file .env.
|
|
321
|
-
|
|
322
|
-
# Pull whatever you need
|
|
323
|
-
lsh pull --env dev # for local dev
|
|
324
|
-
lsh pull --env staging # for testing
|
|
325
|
-
lsh pull --env prod # for production debugging
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
### 📝 Batch Upsert Secrets
|
|
329
|
-
|
|
330
|
-
**New in v1.1.0:** Pipe environment variables directly into your `.env` file!
|
|
331
|
-
|
|
332
|
-
```bash
|
|
333
|
-
# Copy all current environment variables
|
|
334
|
-
printenv | lsh set
|
|
335
|
-
|
|
336
|
-
# Import from another .env file
|
|
337
|
-
cat .env.backup | lsh set
|
|
338
|
-
|
|
339
|
-
# Import specific variables
|
|
340
|
-
printenv | grep "^AWS_" | lsh set
|
|
341
|
-
|
|
342
|
-
# Merge multiple sources
|
|
343
|
-
cat .env.base .env.local | lsh set
|
|
344
|
-
|
|
345
|
-
# From file with --stdin flag
|
|
346
|
-
lsh set --stdin < .env.production
|
|
347
|
-
|
|
348
|
-
# Single key-value still works
|
|
349
|
-
lsh set API_KEY sk_live_12345
|
|
350
|
-
lsh set DATABASE_URL postgres://localhost/db
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
**Features:**
|
|
354
|
-
- ✅ Automatic upsert (updates existing, adds new)
|
|
355
|
-
- ✅ Preserves comments and formatting
|
|
356
|
-
- ✅ Handles quoted values
|
|
357
|
-
- ✅ Validates key names
|
|
358
|
-
- ✅ Shows summary of changes
|
|
359
|
-
|
|
360
|
-
### 🔄 Multi-Format Export
|
|
361
|
-
|
|
362
|
-
**New in v1.2.1:** Export secrets in multiple formats for easy integration with other tools!
|
|
158
|
+
# Production
|
|
159
|
+
lsh push --file .env.prod --env prod
|
|
363
160
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
lsh list --format json
|
|
367
|
-
|
|
368
|
-
# YAML format (for Docker Compose, Kubernetes, etc.)
|
|
369
|
-
lsh list --format yaml
|
|
370
|
-
|
|
371
|
-
# TOML format (auto-detects namespaces!)
|
|
372
|
-
lsh list --format toml
|
|
373
|
-
|
|
374
|
-
# Shell export format (for sourcing in scripts)
|
|
375
|
-
lsh list --format export
|
|
376
|
-
eval "$(lsh list --format export)"
|
|
377
|
-
|
|
378
|
-
# Works with get command too
|
|
379
|
-
lsh get --all --format yaml > config.yaml
|
|
380
|
-
|
|
381
|
-
# And with env command for cloud secrets
|
|
382
|
-
lsh env prod --format json
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
**Supported Formats:**
|
|
386
|
-
- ✅ `env` - Standard KEY=value format (default, masked)
|
|
387
|
-
- ✅ `json` - JSON object format
|
|
388
|
-
- ✅ `yaml` - YAML format
|
|
389
|
-
- ✅ `toml` - TOML with smart namespace detection
|
|
390
|
-
- ✅ `export` - Shell export statements
|
|
391
|
-
|
|
392
|
-
**Smart Features:**
|
|
393
|
-
- Auto-detects namespaces in TOML (e.g., `DATABASE_*` → `[database]`)
|
|
394
|
-
- Auto-disables masking for structured formats (JSON/YAML/TOML)
|
|
395
|
-
- Use `--no-mask` to show full values in any format
|
|
396
|
-
|
|
397
|
-
## Secrets Commands
|
|
398
|
-
|
|
399
|
-
| Command | Description |
|
|
400
|
-
|---------|-------------|
|
|
401
|
-
| `lsh push` | Upload .env to encrypted cloud storage |
|
|
402
|
-
| `lsh pull` | Download .env from cloud storage |
|
|
403
|
-
| `lsh list` | List secrets in current .env file |
|
|
404
|
-
| `lsh env` | List all stored environments |
|
|
405
|
-
| `lsh key` | Generate encryption key |
|
|
406
|
-
| `lsh create` | Create new .env file |
|
|
407
|
-
| `lsh delete` | Delete .env file (with confirmation) |
|
|
408
|
-
| `lsh sync` | Smart sync (auto-setup and sync) |
|
|
409
|
-
| `lsh status` | Get detailed secrets status (JSON) |
|
|
410
|
-
| `lsh info` | Show current context and tracked environment |
|
|
411
|
-
| `lsh get <key>` | Get a specific secret value |
|
|
412
|
-
| `lsh set <key> <value>` | Set a single secret value |
|
|
413
|
-
| `printenv \| lsh set` | Batch upsert from stdin (pipe) |
|
|
414
|
-
| `lsh set --stdin < file` | Batch upsert from file |
|
|
415
|
-
|
|
416
|
-
See the complete guide: [SECRETS_GUIDE.md](docs/features/secrets/SECRETS_GUIDE.md)
|
|
417
|
-
|
|
418
|
-
## Installation
|
|
419
|
-
|
|
420
|
-
### Prerequisites
|
|
421
|
-
- Node.js 20.18.0 or higher
|
|
422
|
-
- npm 10.0.0 or higher
|
|
423
|
-
- Supabase account (free tier works) OR PostgreSQL database
|
|
424
|
-
|
|
425
|
-
### Install from npm
|
|
426
|
-
|
|
427
|
-
```bash
|
|
428
|
-
npm install -g lsh-framework
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
### Verify installation
|
|
432
|
-
|
|
433
|
-
```bash
|
|
434
|
-
lsh --version
|
|
435
|
-
lsh self version
|
|
161
|
+
# Pull any environment
|
|
162
|
+
lsh pull --env prod
|
|
436
163
|
```
|
|
437
164
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
**New in v1.3.2:** Enable intelligent Tab completion for bash/zsh!
|
|
441
|
-
|
|
442
|
-
**Bash:**
|
|
443
|
-
```bash
|
|
444
|
-
# Add to ~/.bashrc
|
|
445
|
-
echo 'source <(lsh completion bash)' >> ~/.bashrc
|
|
446
|
-
source ~/.bashrc
|
|
447
|
-
```
|
|
165
|
+
## Team Collaboration
|
|
448
166
|
|
|
449
|
-
**
|
|
167
|
+
**Setup (Team Lead):**
|
|
450
168
|
```bash
|
|
451
|
-
#
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
echo 'fpath=(~/.zsh/completions $fpath)' >> ~/.zshrc
|
|
455
|
-
echo 'autoload -Uz compinit && compinit' >> ~/.zshrc
|
|
456
|
-
source ~/.zshrc
|
|
169
|
+
lsh key # Generate team key
|
|
170
|
+
lsh push --env prod # Push team secrets
|
|
171
|
+
# Share LSH_SECRETS_KEY via 1Password/LastPass
|
|
457
172
|
```
|
|
458
173
|
|
|
459
|
-
|
|
460
|
-
- Complete command names: `lsh pu<Tab>` → `lsh push`
|
|
461
|
-
- Discover options: `lsh push <Tab>` → `-f --file -e --env --force -h --help`
|
|
462
|
-
- Complete environments: `lsh push --env <Tab>` → `dev staging production`
|
|
463
|
-
- Complete formats: `lsh list --format <Tab>` → `env json yaml toml export`
|
|
464
|
-
|
|
465
|
-
See [Shell Completion Guide](docs/features/SHELL_COMPLETION.md) for more details.
|
|
466
|
-
|
|
467
|
-
### Initial Setup
|
|
468
|
-
|
|
174
|
+
**Team Members:**
|
|
469
175
|
```bash
|
|
470
|
-
#
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
#
|
|
474
|
-
cat > .env <<EOF
|
|
475
|
-
# Supabase (for encrypted storage)
|
|
476
|
-
SUPABASE_URL=https://your-project.supabase.co
|
|
477
|
-
SUPABASE_ANON_KEY=your-anon-key
|
|
478
|
-
|
|
479
|
-
# Encryption key (generated above)
|
|
480
|
-
LSH_SECRETS_KEY=your-key-here
|
|
481
|
-
|
|
482
|
-
# Your application secrets
|
|
483
|
-
DATABASE_URL=postgresql://localhost/mydb
|
|
484
|
-
API_KEY=your-api-key
|
|
485
|
-
EOF
|
|
486
|
-
|
|
487
|
-
# 3. Push to cloud
|
|
488
|
-
lsh push --env dev
|
|
176
|
+
# Get key from 1Password
|
|
177
|
+
echo "LSH_SECRETS_KEY=shared-key" > .env
|
|
178
|
+
lsh pull --env prod
|
|
179
|
+
# Done!
|
|
489
180
|
```
|
|
490
181
|
|
|
491
|
-
##
|
|
492
|
-
|
|
493
|
-
Because LSH is built on a complete shell framework, you also get powerful automation capabilities:
|
|
494
|
-
|
|
495
|
-
### Persistent Daemon
|
|
182
|
+
## Automatic Secret Rotation
|
|
496
183
|
|
|
497
|
-
|
|
184
|
+
Use the built-in daemon for automated rotation:
|
|
498
185
|
|
|
499
186
|
```bash
|
|
500
187
|
# Start daemon
|
|
501
188
|
lsh daemon start
|
|
502
189
|
|
|
503
|
-
#
|
|
504
|
-
lsh
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
lsh
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
### Cron-Style Scheduling
|
|
511
|
-
|
|
512
|
-
Schedule any task with cron expressions:
|
|
513
|
-
|
|
514
|
-
```bash
|
|
515
|
-
# Daily backup at midnight
|
|
516
|
-
lsh cron add --name "backup" \
|
|
517
|
-
--schedule "0 0 * * *" \
|
|
518
|
-
--command "./backup.sh"
|
|
519
|
-
|
|
520
|
-
# Every 6 hours
|
|
521
|
-
lsh cron add --name "sync" \
|
|
522
|
-
--schedule "0 */6 * * *" \
|
|
523
|
-
--command "lsh pull && ./reload.sh"
|
|
190
|
+
# Schedule monthly key rotation
|
|
191
|
+
lsh cron add \
|
|
192
|
+
--name "rotate-keys" \
|
|
193
|
+
--schedule "0 0 1 * *" \
|
|
194
|
+
--command "./scripts/rotate.sh && lsh push"
|
|
524
195
|
|
|
525
|
-
# List
|
|
196
|
+
# List scheduled jobs
|
|
526
197
|
lsh cron list
|
|
527
|
-
|
|
528
|
-
# Trigger manually
|
|
529
|
-
lsh cron trigger backup
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
### RESTful API
|
|
533
|
-
|
|
534
|
-
Control everything via HTTP API:
|
|
535
|
-
|
|
536
|
-
```bash
|
|
537
|
-
# Start API server
|
|
538
|
-
LSH_API_KEY=your-key lsh api start --port 3030
|
|
539
|
-
|
|
540
|
-
# Use the API
|
|
541
|
-
curl -H "X-API-Key: your-key" http://localhost:3030/api/jobs
|
|
542
198
|
```
|
|
543
199
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
- **Webhook Receiver** - GitHub, GitLab, Jenkins webhook support
|
|
547
|
-
- **Build Analytics** - Track build metrics and performance
|
|
548
|
-
- **Pipeline Orchestration** - Workflow engine for complex pipelines
|
|
200
|
+
## Export Formats
|
|
549
201
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
LSH is also a full POSIX-compatible shell with ZSH enhancements:
|
|
553
|
-
|
|
554
|
-
- Extended globbing patterns
|
|
555
|
-
- Parameter expansion
|
|
556
|
-
- Associative arrays
|
|
557
|
-
- Command history and tab completion
|
|
558
|
-
- Interactive mode
|
|
202
|
+
Export secrets in multiple formats:
|
|
559
203
|
|
|
560
204
|
```bash
|
|
561
|
-
|
|
562
|
-
lsh
|
|
563
|
-
|
|
564
|
-
#
|
|
565
|
-
lsh -c "echo 'Hello World'"
|
|
205
|
+
lsh list --format json # JSON
|
|
206
|
+
lsh list --format yaml # YAML
|
|
207
|
+
lsh list --format toml # TOML
|
|
208
|
+
lsh list --format export # Shell export statements
|
|
566
209
|
|
|
567
|
-
#
|
|
568
|
-
lsh
|
|
210
|
+
# Load into current shell
|
|
211
|
+
eval "$(lsh list --format export)"
|
|
569
212
|
```
|
|
570
213
|
|
|
571
214
|
## Security
|
|
572
215
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
### Encryption
|
|
579
|
-
|
|
580
|
-
- **Algorithm**: AES-256-CBC
|
|
581
|
-
- **Key Management**: User-controlled encryption keys
|
|
582
|
-
- **Storage**: Encrypted at rest in Supabase/PostgreSQL
|
|
583
|
-
- **Transport**: HTTPS for all API calls
|
|
216
|
+
- **AES-256-CBC** encryption for all secrets
|
|
217
|
+
- **Content-addressed storage** - tamper-proof IPFS CIDs
|
|
218
|
+
- **Zero-knowledge** - Storacha never sees your unencrypted data
|
|
219
|
+
- **Local-first** - Works offline with cached secrets
|
|
584
220
|
|
|
585
221
|
### Best Practices
|
|
586
222
|
|
|
587
|
-
|
|
588
|
-
- Store `LSH_SECRETS_KEY` in
|
|
589
|
-
-
|
|
590
|
-
-
|
|
591
|
-
- Use different keys for dev/staging/production environments
|
|
223
|
+
**DO:**
|
|
224
|
+
- Store `LSH_SECRETS_KEY` in shell profile (`~/.zshrc`)
|
|
225
|
+
- Share keys via password manager (1Password, etc.)
|
|
226
|
+
- Use different keys per project/team
|
|
592
227
|
- Rotate keys periodically
|
|
593
|
-
- Keep encrypted backups of your encryption key
|
|
594
228
|
|
|
595
|
-
|
|
596
|
-
- Store `LSH_SECRETS_KEY` in your project's `.env` file
|
|
229
|
+
**DON'T:**
|
|
597
230
|
- Commit `LSH_SECRETS_KEY` to git
|
|
598
|
-
- Share keys in plain text (Slack, email
|
|
599
|
-
- Reuse keys across different teams/projects
|
|
231
|
+
- Share keys in plain text (Slack, email)
|
|
600
232
|
- Store production secrets in dev environment
|
|
601
233
|
|
|
602
|
-
|
|
234
|
+
## Troubleshooting
|
|
603
235
|
|
|
604
|
-
|
|
236
|
+
### "No secrets found for environment"
|
|
605
237
|
|
|
606
|
-
```
|
|
607
|
-
|
|
238
|
+
```bash
|
|
239
|
+
# Check what environments exist
|
|
240
|
+
lsh env
|
|
608
241
|
|
|
609
|
-
|
|
610
|
-
|
|
242
|
+
# Push if missing
|
|
243
|
+
lsh push --env dev
|
|
611
244
|
```
|
|
612
245
|
|
|
613
|
-
###
|
|
614
|
-
|
|
615
|
-
LSH validates all environment variables at startup and fails fast if:
|
|
616
|
-
- Required secrets are missing or too short
|
|
617
|
-
- Invalid URL formats
|
|
618
|
-
- Dangerous commands enabled in production
|
|
619
|
-
|
|
620
|
-
## Use Cases
|
|
621
|
-
|
|
622
|
-
### 1. Multi-Machine Development
|
|
246
|
+
### "Decryption failed"
|
|
623
247
|
|
|
624
|
-
|
|
248
|
+
Wrong encryption key. Make sure `LSH_SECRETS_KEY` matches.
|
|
625
249
|
|
|
626
|
-
**Solution:**
|
|
627
250
|
```bash
|
|
628
|
-
#
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
# Desktop
|
|
632
|
-
lsh pull --env dev
|
|
633
|
-
|
|
634
|
-
# Cloud server
|
|
635
|
-
lsh pull --env dev
|
|
251
|
+
# Check current key
|
|
252
|
+
cat .env | grep LSH_SECRETS_KEY
|
|
636
253
|
|
|
637
|
-
#
|
|
254
|
+
# If lost, generate new key and re-push
|
|
255
|
+
lsh key
|
|
256
|
+
lsh push --force
|
|
638
257
|
```
|
|
639
258
|
|
|
640
|
-
###
|
|
641
|
-
|
|
642
|
-
**Problem:** New team member needs to set up 5 microservices with different env vars.
|
|
259
|
+
### "Storacha authentication required"
|
|
643
260
|
|
|
644
|
-
**Solution:**
|
|
645
261
|
```bash
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
cd ~/projects/service-2 && lsh pull --env dev
|
|
649
|
-
cd ~/projects/service-3 && lsh pull --env dev
|
|
650
|
-
cd ~/projects/service-4 && lsh pull --env dev
|
|
651
|
-
cd ~/projects/service-5 && lsh pull --env dev
|
|
652
|
-
|
|
653
|
-
# Done in 30 seconds instead of 30 minutes
|
|
262
|
+
lsh storacha login your@email.com
|
|
263
|
+
# Check email for verification
|
|
654
264
|
```
|
|
655
265
|
|
|
656
|
-
###
|
|
266
|
+
### Pull fails after clearing metadata
|
|
657
267
|
|
|
658
|
-
|
|
268
|
+
v3.0.0 fix: Pull now automatically checks the Storacha registry when local metadata is missing.
|
|
659
269
|
|
|
660
|
-
**Solution:**
|
|
661
270
|
```bash
|
|
662
|
-
#
|
|
663
|
-
|
|
664
|
-
#!/bin/bash
|
|
665
|
-
# Generate new API key from provider
|
|
666
|
-
NEW_KEY=$(curl -X POST https://api.provider.com/keys/rotate)
|
|
271
|
+
# If secrets were pushed before, pull should auto-recover
|
|
272
|
+
lsh pull
|
|
667
273
|
|
|
668
|
-
#
|
|
669
|
-
|
|
274
|
+
# If truly no secrets exist, push first
|
|
275
|
+
lsh push
|
|
276
|
+
```
|
|
670
277
|
|
|
671
|
-
|
|
672
|
-
lsh push --env prod
|
|
278
|
+
## Documentation
|
|
673
279
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
280
|
+
- **[Secrets Guide](docs/features/secrets/SECRETS_GUIDE.md)** - Complete secrets management guide
|
|
281
|
+
- **[Smart Sync Guide](docs/features/secrets/SMART_SYNC_GUIDE.md)** - One-command sync guide
|
|
282
|
+
- **[Quick Reference](docs/features/secrets/SECRETS_QUICK_REFERENCE.md)** - Daily use cheatsheet
|
|
283
|
+
- **[Installation](docs/deployment/INSTALL.md)** - Detailed installation
|
|
284
|
+
- **[Developer Guide](CLAUDE.md)** - Contributing to LSH
|
|
677
285
|
|
|
678
|
-
|
|
679
|
-
lsh cron add --name "rotate-keys" \
|
|
680
|
-
--schedule "0 0 1 * *" \
|
|
681
|
-
--command "./rotate-keys.sh"
|
|
682
|
-
```
|
|
286
|
+
## Advanced Features
|
|
683
287
|
|
|
684
|
-
|
|
288
|
+
LSH includes a full automation platform:
|
|
685
289
|
|
|
686
|
-
**
|
|
290
|
+
- **Persistent Daemon** - Background job execution
|
|
291
|
+
- **Cron Scheduling** - Time-based job scheduling
|
|
292
|
+
- **REST API** - HTTP API for integration
|
|
293
|
+
- **CI/CD Webhooks** - GitHub/GitLab webhook support
|
|
294
|
+
- **POSIX Shell** - Interactive shell with ZSH features
|
|
687
295
|
|
|
688
|
-
**Solution:**
|
|
689
296
|
```bash
|
|
690
|
-
#
|
|
691
|
-
lsh
|
|
692
|
-
|
|
693
|
-
# Push staging config
|
|
694
|
-
lsh push --file .env.staging --env staging
|
|
297
|
+
# Start daemon
|
|
298
|
+
lsh daemon start
|
|
695
299
|
|
|
696
|
-
#
|
|
697
|
-
lsh
|
|
300
|
+
# API server
|
|
301
|
+
LSH_API_KEY=xxx lsh api start --port 3030
|
|
698
302
|
|
|
699
|
-
#
|
|
700
|
-
|
|
701
|
-
- name: Get secrets
|
|
702
|
-
run: lsh pull --env ${{ github.ref == 'refs/heads/main' && 'prod' || 'staging' }}
|
|
303
|
+
# Interactive shell
|
|
304
|
+
lsh -i
|
|
703
305
|
```
|
|
704
306
|
|
|
705
|
-
## Comparison with Other Tools
|
|
706
|
-
|
|
707
|
-
| Feature | LSH | dotenv-vault | 1Password | Doppler | HashiCorp Vault |
|
|
708
|
-
|---------|-----|--------------|-----------|---------|-----------------|
|
|
709
|
-
| **Cost** | Free | Free tier | $3-8/mo/user | $5-10/user | Free (complex) |
|
|
710
|
-
| **Encryption** | AES-256 | ✓ | ✓ | ✓ | ✓ |
|
|
711
|
-
| **Self-Hosted** | ✓ (Supabase) | ✗ | ✗ | ✗ | ✓ (complex) |
|
|
712
|
-
| **Auto Rotation** | ✓ Built-in | ✗ | Manual | ✗ | ✓ (complex) |
|
|
713
|
-
| **Team Sync** | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
714
|
-
| **CLI Native** | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
715
|
-
| **Setup Time** | 2 min | 5 min | 10 min | 10 min | 30+ min |
|
|
716
|
-
| **Daemon/Cron** | ✓ Built-in | ✗ | ✗ | ✗ | ✗ |
|
|
717
|
-
| **Learning Curve** | Easy | Easy | Medium | Medium | Hard |
|
|
718
|
-
|
|
719
|
-
**LSH is the only tool that combines:**
|
|
720
|
-
- Simple, fast setup
|
|
721
|
-
- Built-in scheduling for rotation
|
|
722
|
-
- Self-hosted option (no vendor lock-in)
|
|
723
|
-
- Completely free
|
|
724
|
-
|
|
725
307
|
## Configuration
|
|
726
308
|
|
|
727
309
|
### Environment Variables
|
|
728
310
|
|
|
729
|
-
Copy `.env.example` to `.env`:
|
|
730
|
-
|
|
731
311
|
```bash
|
|
732
|
-
#
|
|
733
|
-
|
|
734
|
-
SUPABASE_ANON_KEY=<your-anon-key>
|
|
735
|
-
LSH_SECRETS_KEY=<generate-with-lsh-lib-secrets-key>
|
|
312
|
+
# Required
|
|
313
|
+
LSH_SECRETS_KEY=<your-encryption-key>
|
|
736
314
|
|
|
737
|
-
# Optional
|
|
315
|
+
# Optional - Storacha (default enabled)
|
|
316
|
+
LSH_STORACHA_ENABLED=true
|
|
738
317
|
|
|
739
|
-
#
|
|
318
|
+
# Optional - Supabase backend
|
|
319
|
+
SUPABASE_URL=https://xxx.supabase.co
|
|
320
|
+
SUPABASE_ANON_KEY=<key>
|
|
321
|
+
|
|
322
|
+
# Optional - API server
|
|
740
323
|
LSH_API_ENABLED=true
|
|
741
324
|
LSH_API_PORT=3030
|
|
742
|
-
LSH_API_KEY=<
|
|
743
|
-
LSH_JWT_SECRET=<generate-32-char-secret>
|
|
744
|
-
|
|
745
|
-
# Webhooks (for CI/CD integration)
|
|
746
|
-
LSH_ENABLE_WEBHOOKS=true
|
|
747
|
-
WEBHOOK_PORT=3033
|
|
748
|
-
GITHUB_WEBHOOK_SECRET=<your-secret>
|
|
749
|
-
GITLAB_WEBHOOK_SECRET=<your-secret>
|
|
750
|
-
|
|
751
|
-
# Database (alternative to Supabase)
|
|
752
|
-
DATABASE_URL=postgresql://localhost:5432/lsh
|
|
753
|
-
|
|
754
|
-
# Caching
|
|
755
|
-
REDIS_URL=redis://localhost:6379
|
|
756
|
-
|
|
757
|
-
# Security
|
|
758
|
-
LSH_ALLOW_DANGEROUS_COMMANDS=false # Keep false in production
|
|
325
|
+
LSH_API_KEY=<key>
|
|
759
326
|
```
|
|
760
327
|
|
|
761
|
-
###
|
|
762
|
-
|
|
763
|
-
```bash
|
|
764
|
-
# Encryption key for secrets
|
|
765
|
-
lsh key
|
|
766
|
-
|
|
767
|
-
# API key for HTTP API
|
|
768
|
-
openssl rand -hex 32
|
|
328
|
+
### Configuration Files
|
|
769
329
|
|
|
770
|
-
# JWT secret
|
|
771
|
-
openssl rand -hex 32
|
|
772
330
|
```
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
### Building
|
|
777
|
-
|
|
778
|
-
```bash
|
|
779
|
-
# Build TypeScript
|
|
780
|
-
npm run build
|
|
781
|
-
|
|
782
|
-
# Watch mode
|
|
783
|
-
npm run watch
|
|
784
|
-
|
|
785
|
-
# Type checking
|
|
786
|
-
npm run typecheck
|
|
787
|
-
```
|
|
788
|
-
|
|
789
|
-
### Testing
|
|
790
|
-
|
|
791
|
-
```bash
|
|
792
|
-
# Run tests
|
|
793
|
-
npm test
|
|
794
|
-
|
|
795
|
-
# With coverage
|
|
796
|
-
npm run test:coverage
|
|
797
|
-
|
|
798
|
-
# Lint
|
|
799
|
-
npm run lint
|
|
800
|
-
|
|
801
|
-
# Auto-fix
|
|
802
|
-
npm run lint:fix
|
|
331
|
+
~/.config/lsh/lshrc # LSH configuration
|
|
332
|
+
~/.lsh/secrets-cache/ # Encrypted secrets cache
|
|
333
|
+
~/.lsh/secrets-metadata.json # Metadata index
|
|
803
334
|
```
|
|
804
335
|
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
Install git hooks for automatic linting before commits:
|
|
808
|
-
|
|
809
|
-
```bash
|
|
810
|
-
# Install hooks
|
|
811
|
-
./scripts/install-git-hooks.sh
|
|
812
|
-
|
|
813
|
-
# Hooks will run automatically on git commit
|
|
814
|
-
# To skip hooks on a specific commit:
|
|
815
|
-
git commit --no-verify
|
|
816
|
-
```
|
|
817
|
-
|
|
818
|
-
The pre-commit hook runs `npm run lint` and blocks commits if linting fails.
|
|
819
|
-
|
|
820
|
-
### From Source
|
|
336
|
+
## Contributing
|
|
821
337
|
|
|
822
338
|
```bash
|
|
823
339
|
git clone https://github.com/gwicho38/lsh.git
|
|
824
340
|
cd lsh
|
|
825
341
|
npm install
|
|
826
342
|
npm run build
|
|
343
|
+
npm test
|
|
827
344
|
npm link
|
|
828
|
-
lsh --version
|
|
829
|
-
```
|
|
830
|
-
|
|
831
|
-
## Troubleshooting
|
|
832
|
-
|
|
833
|
-
### "No secrets found"
|
|
834
|
-
|
|
835
|
-
```bash
|
|
836
|
-
# Check stored environments
|
|
837
|
-
lsh list
|
|
838
|
-
|
|
839
|
-
# Push if missing
|
|
840
|
-
lsh push --env dev
|
|
841
|
-
```
|
|
842
|
-
|
|
843
|
-
### "Decryption failed"
|
|
844
|
-
|
|
845
|
-
```bash
|
|
846
|
-
# Wrong encryption key!
|
|
847
|
-
# Make sure LSH_SECRETS_KEY matches the one used to encrypt
|
|
848
|
-
|
|
849
|
-
# Generate new key and re-push
|
|
850
|
-
lsh key
|
|
851
|
-
lsh push
|
|
852
|
-
```
|
|
853
|
-
|
|
854
|
-
### "Supabase not configured"
|
|
855
|
-
|
|
856
|
-
```bash
|
|
857
|
-
# Add to .env:
|
|
858
|
-
SUPABASE_URL=https://your-project.supabase.co
|
|
859
|
-
SUPABASE_ANON_KEY=your-anon-key
|
|
860
|
-
```
|
|
861
|
-
|
|
862
|
-
### Daemon won't start
|
|
863
|
-
|
|
864
|
-
```bash
|
|
865
|
-
# Check if already running
|
|
866
|
-
ps aux | grep lshd
|
|
867
|
-
|
|
868
|
-
# Remove stale PID file
|
|
869
|
-
rm /tmp/lsh-job-daemon-$USER.pid
|
|
870
|
-
|
|
871
|
-
# Restart
|
|
872
|
-
lsh daemon start
|
|
873
345
|
```
|
|
874
346
|
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
### Secrets Management
|
|
878
|
-
- **[SMART_SYNC_GUIDE.md](docs/features/secrets/SMART_SYNC_GUIDE.md)** - 🆕 Smart Sync complete guide (v0.8.2+)
|
|
879
|
-
- **[SECRETS_GUIDE.md](docs/features/secrets/SECRETS_GUIDE.md)** - Complete secrets management guide
|
|
880
|
-
- **[SECRETS_QUICK_REFERENCE.md](docs/features/secrets/SECRETS_QUICK_REFERENCE.md)** - Quick reference for daily use
|
|
881
|
-
- **[SECRETS_CHEATSHEET.txt](SECRETS_CHEATSHEET.txt)** - Command cheatsheet
|
|
882
|
-
|
|
883
|
-
### IPFS Integration
|
|
884
|
-
- **[IPFS_CLIENT_GUIDE.md](docs/features/ipfs/IPFS_CLIENT_GUIDE.md)** - 🆕 IPFS client installation and management (v1.6.0+)
|
|
885
|
-
|
|
886
|
-
### Installation & Development
|
|
887
|
-
- **[INSTALL.md](docs/deployment/INSTALL.md)** - Detailed installation instructions
|
|
888
|
-
- **[CLAUDE.md](CLAUDE.md)** - Developer guide for contributors
|
|
889
|
-
|
|
890
|
-
### Release Notes
|
|
891
|
-
- **[v0.8.3](docs/releases/0.8.3.md)** - Hotfix: Logger output in load mode
|
|
892
|
-
- **[v0.8.2](docs/releases/0.8.2.md)** - Smart Sync feature release
|
|
893
|
-
- **[v0.8.1](docs/releases/0.8.1.md)** - Previous releases
|
|
894
|
-
|
|
895
|
-
## Architecture
|
|
896
|
-
|
|
897
|
-
### Secrets Flow
|
|
898
|
-
|
|
899
|
-
```
|
|
900
|
-
Local .env → Encrypt (AES-256) → Supabase/PostgreSQL
|
|
901
|
-
↓
|
|
902
|
-
Pull on any machine
|
|
903
|
-
↓
|
|
904
|
-
Decrypt → Local .env
|
|
905
|
-
```
|
|
906
|
-
|
|
907
|
-
### Rotation Flow
|
|
908
|
-
|
|
909
|
-
```
|
|
910
|
-
Cron Schedule → Daemon → Rotation Script → Update .env → Push to cloud
|
|
911
|
-
↓
|
|
912
|
-
Notify team/reload apps
|
|
913
|
-
```
|
|
914
|
-
|
|
915
|
-
### Security Architecture
|
|
916
|
-
|
|
917
|
-
```
|
|
918
|
-
API Request → JWT Validation → Command Validation → Execution
|
|
919
|
-
Webhook → HMAC Verification → Event Processing → Job Trigger
|
|
920
|
-
Daemon Startup → Env Validation → Fail Fast if Invalid
|
|
921
|
-
Secrets → AES-256 Encryption → Encrypted Storage
|
|
922
|
-
```
|
|
923
|
-
|
|
924
|
-
## API Reference
|
|
925
|
-
|
|
926
|
-
### Secrets API
|
|
927
|
-
|
|
928
|
-
All secrets commands are available programmatically:
|
|
929
|
-
|
|
930
|
-
```typescript
|
|
931
|
-
import SecretsManager from 'lsh-framework/dist/lib/secrets-manager.js';
|
|
932
|
-
|
|
933
|
-
const manager = new SecretsManager();
|
|
934
|
-
|
|
935
|
-
// Push secrets
|
|
936
|
-
await manager.push('.env', 'production');
|
|
937
|
-
|
|
938
|
-
// Pull secrets
|
|
939
|
-
await manager.pull('.env', 'production');
|
|
940
|
-
|
|
941
|
-
// List environments
|
|
942
|
-
const envs = await manager.listEnvironments();
|
|
943
|
-
|
|
944
|
-
// Show secrets (masked)
|
|
945
|
-
await manager.show('production');
|
|
946
|
-
```
|
|
947
|
-
|
|
948
|
-
### REST API
|
|
949
|
-
|
|
950
|
-
See API endpoints documentation in the Advanced Features section.
|
|
951
|
-
|
|
952
|
-
## Roadmap
|
|
953
|
-
|
|
954
|
-
- [ ] CLI command shortcuts (`lsh push` instead of `lsh push`)
|
|
955
|
-
- [ ] Built-in secret rotation templates (AWS, GCP, Azure)
|
|
956
|
-
- [ ] Web dashboard for team secret management
|
|
957
|
-
- [ ] Audit logging for secret access
|
|
958
|
-
- [ ] Integration with cloud secret managers (AWS Secrets Manager, etc.)
|
|
959
|
-
- [ ] Automatic secret expiration warnings
|
|
960
|
-
- [ ] Git hooks for secret validation
|
|
961
|
-
|
|
962
|
-
## Contributing
|
|
963
|
-
|
|
964
|
-
Contributions welcome! Please:
|
|
965
|
-
|
|
966
|
-
1. Fork the repository
|
|
967
|
-
2. Create a feature branch: `git checkout -b feature/your-feature`
|
|
968
|
-
3. Make your changes
|
|
969
|
-
4. Add tests: `npm test`
|
|
970
|
-
5. Lint: `npm run lint:fix`
|
|
971
|
-
6. Commit and push
|
|
972
|
-
7. Create a Pull Request
|
|
347
|
+
See [CLAUDE.md](CLAUDE.md) for development guidelines.
|
|
973
348
|
|
|
974
349
|
## License
|
|
975
350
|
|
|
@@ -979,19 +354,12 @@ MIT
|
|
|
979
354
|
|
|
980
355
|
- **Issues**: https://github.com/gwicho38/lsh/issues
|
|
981
356
|
- **Discussions**: https://github.com/gwicho38/lsh/discussions
|
|
982
|
-
- **Documentation**: See docs/ folder
|
|
983
|
-
|
|
984
|
-
## Credits
|
|
985
|
-
|
|
986
|
-
Built with:
|
|
987
|
-
- TypeScript for type safety
|
|
988
|
-
- Supabase for encrypted storage
|
|
989
|
-
- Node.js crypto for AES-256 encryption
|
|
990
|
-
- Commander.js for CLI framework
|
|
991
|
-
- React/Ink for terminal UI
|
|
992
357
|
|
|
993
358
|
---
|
|
994
359
|
|
|
995
|
-
**
|
|
360
|
+
**Stop copying `.env` files. Start syncing.**
|
|
996
361
|
|
|
997
|
-
|
|
362
|
+
```bash
|
|
363
|
+
npm install -g lsh-framework
|
|
364
|
+
lsh init
|
|
365
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lsh-framework",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Simple, cross-platform encrypted secrets manager with automatic sync, IPFS audit logs, and multi-environment support. Just run lsh sync and start managing your secrets.",
|
|
5
5
|
"main": "dist/app.js",
|
|
6
6
|
"bin": {
|