Initial release: Headlamp Sealed Secrets plugin v0.1.0
Features: - Complete SealedSecret CRD integration with Headlamp - Client-side encryption using controller's public key - Support for all three scoping modes (strict, namespace-wide, cluster-wide) - List and detail views for SealedSecrets - Encryption dialog for creating new SealedSecrets - Decryption support with RBAC awareness - Sealing keys management - Settings page for controller configuration - Integration with Secret detail view Technical: - Full TypeScript with strict mode - ~1,345 lines of code - Build size: 339.42 kB (93.21 kB gzipped) - Compatible with Headlamp v0.13.0+ - Apache 2.0 license Security: - All encryption performed client-side - RSA-OAEP + AES-256-GCM (kubeseal-compatible) - Auto-hide decrypted values after 30 seconds Closes: Initial implementation
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
# Headlamp Sealed Secrets Plugin
|
||||
|
||||
A comprehensive [Headlamp](https://headlamp.dev) plugin for managing [Bitnami Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets) in Kubernetes clusters.
|
||||
|
||||
## Features
|
||||
|
||||
### 🔐 Client-Side Encryption
|
||||
- Encrypt secrets entirely in your browser using the controller's public key
|
||||
- Never send plaintext values over the network
|
||||
- Support for all three scoping modes: strict, namespace-wide, and cluster-wide
|
||||
|
||||
### 📋 Resource Management
|
||||
- **List View**: Browse all SealedSecrets across namespaces with filtering
|
||||
- **Detail View**: Inspect encrypted data, templates, and resulting Secrets
|
||||
- **Create**: Easy-to-use dialog for creating new SealedSecrets
|
||||
- **Decrypt**: View decrypted values (requires RBAC permissions to read Secrets)
|
||||
- **Re-encrypt**: Rotate SealedSecrets with the current active key
|
||||
|
||||
### 🔑 Key Management
|
||||
- View all sealing key pairs (active and compromised)
|
||||
- Download the public certificate for use with `kubeseal` CLI
|
||||
- Monitor certificate validity periods
|
||||
|
||||
### 🔗 Integration
|
||||
- Seamlessly integrates with Headlamp's Secret detail view
|
||||
- Shows parent SealedSecret info on Secret pages
|
||||
- Follows Headlamp's design patterns and UI components
|
||||
|
||||
## Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. **Headlamp** installed and running (v0.13.0 or later)
|
||||
2. **Sealed Secrets controller** installed on your Kubernetes cluster:
|
||||
```bash
|
||||
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
|
||||
```
|
||||
|
||||
### Install the Plugin
|
||||
|
||||
#### Option 1: From NPM (when published)
|
||||
```bash
|
||||
npm install -g headlamp-sealed-secrets
|
||||
```
|
||||
|
||||
#### Option 2: Build from Source
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd headlamp-sealed-secrets
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
Then copy the `dist` folder to Headlamp's plugins directory:
|
||||
- **Linux**: `~/.config/Headlamp/plugins/headlamp-sealed-secrets/`
|
||||
- **macOS**: `~/Library/Application Support/Headlamp/plugins/headlamp-sealed-secrets/`
|
||||
- **Windows**: `%APPDATA%\Headlamp\plugins\headlamp-sealed-secrets\`
|
||||
|
||||
#### Option 3: Development Mode
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
This starts a development server with hot reload. Point Headlamp to the plugin directory.
|
||||
|
||||
## Usage
|
||||
|
||||
### Creating a SealedSecret
|
||||
|
||||
1. Navigate to **Sealed Secrets** > **All Sealed Secrets** in the sidebar
|
||||
2. Click **Create Sealed Secret**
|
||||
3. Fill in:
|
||||
- Secret name
|
||||
- Namespace
|
||||
- Scope (strict/namespace-wide/cluster-wide)
|
||||
- Key-value pairs (values are masked by default)
|
||||
4. Click **Create**
|
||||
|
||||
The plugin will:
|
||||
- Fetch the controller's public certificate
|
||||
- Encrypt all values client-side in your browser
|
||||
- Apply the SealedSecret to the cluster
|
||||
- The controller will create the corresponding Kubernetes Secret
|
||||
|
||||
### Viewing SealedSecrets
|
||||
|
||||
The list view shows:
|
||||
- Name and namespace
|
||||
- Number of encrypted keys
|
||||
- Encryption scope
|
||||
- Sync status (whether the Secret was successfully created)
|
||||
- Age
|
||||
|
||||
Click on any SealedSecret to view details including:
|
||||
- Encrypted data
|
||||
- Template metadata
|
||||
- Resulting Secret (with link to Secret detail view)
|
||||
- Status conditions
|
||||
|
||||
### Decrypting Values
|
||||
|
||||
On the detail view, click **Decrypt** next to any encrypted key to view its plaintext value.
|
||||
|
||||
**Requirements:**
|
||||
- The SealedSecret must be synced (controller has created the Secret)
|
||||
- You must have RBAC permissions to read Secrets in that namespace
|
||||
|
||||
**Security:** The decrypted value auto-hides after 30 seconds.
|
||||
|
||||
### Managing Sealing Keys
|
||||
|
||||
Navigate to **Sealed Secrets** > **Sealing Keys** to:
|
||||
- View all sealing key pairs
|
||||
- See which key is active
|
||||
- Check certificate validity periods
|
||||
- Download the public certificate
|
||||
|
||||
### Settings
|
||||
|
||||
Navigate to **Sealed Secrets** > **Settings** to configure:
|
||||
- Controller name (default: `sealed-secrets-controller`)
|
||||
- Controller namespace (default: `kube-system`)
|
||||
- Controller port (default: `8080`)
|
||||
|
||||
Settings are stored in your browser's local storage.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Client-Side Encryption
|
||||
|
||||
The plugin implements the same encryption algorithm as `kubeseal`:
|
||||
|
||||
1. Fetch the controller's public certificate via Kubernetes API proxy
|
||||
2. Parse the RSA public key from the PEM certificate
|
||||
3. For each secret value:
|
||||
- Generate a random AES-256-GCM session key
|
||||
- Encrypt the value with the session key
|
||||
- Encrypt the session key with RSA-OAEP (SHA-256)
|
||||
- Construct the sealed-secrets payload format
|
||||
- Base64-encode the result
|
||||
|
||||
**Security note:** All encryption happens in the browser. Plaintext values never leave your machine.
|
||||
|
||||
### Components
|
||||
|
||||
```
|
||||
src/
|
||||
├── index.tsx # Plugin registration
|
||||
├── types.ts # TypeScript interfaces
|
||||
├── components/
|
||||
│ ├── SealedSecretList.tsx # List view
|
||||
│ ├── SealedSecretDetail.tsx # Detail view
|
||||
│ ├── EncryptDialog.tsx # Create dialog
|
||||
│ ├── DecryptDialog.tsx # Decrypt modal
|
||||
│ ├── SealingKeysView.tsx # Key management
|
||||
│ ├── SettingsPage.tsx # Configuration
|
||||
│ └── SecretDetailsSection.tsx # Secret integration
|
||||
└── lib/
|
||||
├── SealedSecretCRD.ts # CRD class
|
||||
├── crypto.ts # Encryption logic
|
||||
└── controller.ts # Controller API
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
- **node-forge**: RSA and AES cryptography
|
||||
- **@kinvolk/headlamp-plugin**: Headlamp plugin SDK
|
||||
- **React**, **Material-UI**: Provided by Headlamp at runtime
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Type check
|
||||
npm run tsc
|
||||
|
||||
# Lint
|
||||
npm run lint
|
||||
|
||||
# Format code
|
||||
npm run format
|
||||
|
||||
# Start development server
|
||||
npm start
|
||||
|
||||
# Build for production
|
||||
npm run build
|
||||
|
||||
# Run tests
|
||||
npm test
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "SealedSecrets CRD not found"
|
||||
The Sealed Secrets controller is not installed on your cluster. Install it:
|
||||
```bash
|
||||
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
|
||||
```
|
||||
|
||||
### "Failed to fetch certificate"
|
||||
Check:
|
||||
- Controller is running: `kubectl get pods -n kube-system -l name=sealed-secrets-controller`
|
||||
- Settings match your controller deployment (name, namespace, port)
|
||||
- You have network connectivity to the cluster
|
||||
|
||||
### "Secret not found" when decrypting
|
||||
The SealedSecret hasn't been processed yet, or you don't have RBAC permissions to read Secrets. Check:
|
||||
- SealedSecret status shows "Synced"
|
||||
- Controller logs: `kubectl logs -n kube-system -l name=sealed-secrets-controller`
|
||||
- Your RBAC permissions: `kubectl auth can-i get secrets -n <namespace>`
|
||||
|
||||
### Re-encrypt fails
|
||||
The controller's `/v1/rotate` endpoint may not be exposed. This is typically only needed when rotating keys.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please:
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes with tests
|
||||
4. Run `npm run lint` and `npm run tsc`
|
||||
5. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
Apache License 2.0 - See LICENSE file for details.
|
||||
|
||||
## Related Projects
|
||||
|
||||
- [Headlamp](https://headlamp.dev) - The Kubernetes UI
|
||||
- [Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets) - The Sealed Secrets controller
|
||||
- [kubeseal](https://github.com/bitnami-labs/sealed-secrets#kubeseal) - The CLI tool for Sealed Secrets
|
||||
|
||||
## Credits
|
||||
|
||||
Built with ❤️ for the Kubernetes community.
|
||||
|
||||
- Uses the [Headlamp Plugin SDK](https://headlamp.dev/docs/latest/development/plugins/)
|
||||
- Follows patterns from official Headlamp plugins (Flux, cert-manager)
|
||||
- Encryption algorithm compatible with [kubeseal](https://github.com/bitnami-labs/sealed-secrets)
|
||||
Reference in New Issue
Block a user