7.8 KiB
7.8 KiB
Cleanup & Security Improvements Summary
✅ All Requested Changes Implemented
1. 🔒 Secrets Never Cached (Security Fix)
Problem: Secret data was being cached in localStorage, which is a security risk.
Solution:
- ✅ Removed all caching from
readSecret()method - ✅ Secret data is now always fetched fresh from Vault
- ✅ Only directory listings are cached (for search performance)
- ✅ Updated UI to clearly indicate this security improvement
Code Changes:
// Before: Cached secret data
async readSecret() {
const cached = vaultCache.get(cacheKey);
if (cached) return cached; // ❌ Security risk
const data = await client.read(path);
vaultCache.set(cacheKey, data); // ❌ Caching secrets
return data;
}
// After: Never cache secrets
async readSecret() {
console.log(`⚡ API call for read (no cache): ${path}`);
const data = await client.read(path);
// SECURITY: Never cache secret data - always fetch fresh
return data;
}
2. 🎯 Mount Point Selector (UX Improvement)
Problem: Users had to manually type full paths including mount points.
Solution:
- ✅ Added dropdown selector for available mount points
- ✅ Separate input field for the secret path (without mount prefix)
- ✅ Visual preview of the full path being constructed
- ✅ Auto-parsing when selecting paths from search results
UI Changes:
Before: [secret/data/myapp/config ] [Read Secret]
After: Mount Point: [secret ▼] (kv v2)
Secret Path: [secret/] [data/myapp/config] [Read Secret]
Full path: secret/data/myapp/config
Features:
- Mount point dropdown shows:
secret/ (kv v2),kv/ (kv v2), etc. - Path input is disabled until mount point is selected
- Button is disabled until both mount point and path are provided
- Search results auto-populate the correct mount point + path
3. 🔍 Search Shown by Default
Problem: Search was hidden by default, but it's the primary function.
Solution:
- ✅ Changed
showSearch = ref(true)(wasfalse) - ✅ Search component is now visible immediately upon login
- ✅ Button text updated to "Hide Search" / "Show Search"
4. 🌐 Search All Mount Points by Default
Problem: "Search across all mount points" was disabled by default.
Solution:
- ✅ Changed
searchAllMounts = ref(true)(wasfalse) - ✅ Multi-mount search is now enabled by default
- ✅ Users can still disable it if they want to search a specific mount
Security Improvements
🔒 Secret Data Protection
- Never cached: Secret values are always fetched fresh
- Memory only: Secret data exists only in component state during viewing
- No persistence: Secrets are not stored in localStorage
- Clear indicators: UI explicitly states "Secret data is never cached"
📂 Directory Listing Caching (Still Enabled)
- Performance: Directory listings are still cached for search speed
- No sensitive data: Only path names, not secret values
- Configurable: Cache can be cleared manually
- Reasonable: Directory structure is less sensitive than secret values
User Experience Improvements
🎯 Better Path Input
- Guided input: Mount point dropdown prevents typos
- Visual feedback: Shows full path being constructed
- Auto-completion: Search results populate the form correctly
- Validation: Button disabled until valid input provided
🔍 Search-First Interface
- Primary function: Search is now the main interface
- Immediate access: No need to click "Show Search"
- Multi-mount default: Searches all available secret engines
- Comprehensive: Finds secrets across the entire Vault instance
📱 Responsive Design
- Mount point selector: Works well on mobile
- Path preview: Clear indication of what will be accessed
- Disabled states: Clear visual feedback for invalid states
Technical Implementation
Cache Logic Changes
// Only directory listings cached now
async listSecrets(path: string) {
const cached = vaultCache.get(cacheKey);
if (cached) return cached; // ✅ OK - just directory names
const listing = await client.list(path);
vaultCache.set(cacheKey, listing); // ✅ OK - no secret values
return listing;
}
// Secret data never cached
async readSecret(path: string) {
// No cache check - always fetch fresh
return await client.read(path); // ✅ Always fresh data
}
Mount Point Integration
// Parse search results to extract mount + path
const handleSelectPath = (fullPath: string) => {
const mountPoints = connection.mountPoints || []
// Find matching mount point
for (const mount of mountPoints) {
if (fullPath.startsWith(mount.path + '/')) {
selectedMountPoint.value = mount.path
secretPath.value = fullPath.substring(mount.path.length + 1)
break
}
}
handleReadSecret(fullPath)
}
Configuration Updates
Default Settings
- Search visible:
showSearch = true - Multi-mount search:
searchAllMounts = true - No secret caching: Removed from
readSecret() - Directory caching: Still enabled for performance
User Control
- Users can still hide search if desired
- Users can disable multi-mount search for specific searches
- Cache settings still configurable in Settings panel
- Mount point selection is per-operation
Documentation Updates
README.md
- Updated cache security section
- Clarified what is/isn't cached
- Emphasized secret data protection
UI Messages
- "Secret data is never cached - always fetched fresh"
- "Directory listings are cached to improve search performance"
- Clear security indicators throughout interface
Benefits
🔒 Security
- Zero secret persistence: Secrets never touch localStorage
- Fresh data guarantee: Always get current secret values
- Reduced attack surface: No cached secrets to compromise
🚀 Performance
- Smart caching: Directory listings cached for search speed
- Reduced API calls: Search still benefits from caching
- Responsive UI: Mount point selector is fast and intuitive
👥 User Experience
- Search-first: Primary function is immediately available
- Guided input: Mount point selector prevents errors
- Multi-mount default: Comprehensive search out of the box
- Clear feedback: Visual indicators for all states
Migration Notes
For Existing Users
- No data loss: Existing server configurations preserved
- Better security: Secret data no longer cached (automatic improvement)
- New UI: Mount point selector may require brief learning
- Search default: Search is now shown by default (can be hidden)
For Developers
- API unchanged:
vaultApi.readSecret()still works the same - Caching removed: No more secret data in cache
- UI components: New mount point selector component
- Default states: Search and multi-mount enabled by default
Testing Recommendations
-
Verify no secret caching:
- Read a secret
- Check localStorage - should contain no secret values
- Only directory listings should be cached
-
Test mount point selector:
- Select different mount points
- Verify path construction
- Test with search result selection
-
Confirm search defaults:
- Login to Vault
- Search should be visible immediately
- "Search all mount points" should be checked
-
Security validation:
- Read multiple secrets
- Confirm fresh API calls each time
- Verify no secret data in browser storage
Conclusion
✅ All requested changes implemented successfully:
- 🔒 Secrets never cached (security improvement)
- 🎯 Mount point selector (UX improvement)
- 🔍 Search shown by default (primary function)
- 🌐 Multi-mount search by default (comprehensive)
The application is now more secure, more user-friendly, and better aligned with its primary purpose as a Vault search and browsing tool.