Add branded types to prevent mixing plaintext, encrypted, and certificate
values at compile time. This provides an additional layer of type safety
without any runtime cost.
## Changes
### Type System (src/types.ts)
- Add PlaintextValue branded type for user input
- Add EncryptedValue branded type for encrypted data
- Add Base64String branded type for base64-encoded values
- Add PEMCertificate branded type for PEM certificates
- Add constructor functions for each branded type
- Add unwrap() utility for extracting raw strings
### Crypto Module (src/lib/crypto.ts)
- Update parsePublicKeyFromCert() to require PEMCertificate
- Update encryptValue() to accept PlaintextValue, return Base64String
- Update encryptKeyValues() to accept PlaintextValue[], return Base64String[]
- Update validateCertificate() to require PEMCertificate
### Controller API (src/lib/controller.ts)
- Update fetchPublicCertificate() to return PEMCertificate
- Brand certificate at source when fetching from API
### UI Components
- EncryptDialog: Brand user input as PlaintextValue before encryption
- SealingKeysView: Brand certificates as PEMCertificate when parsing
## Benefits
- Zero runtime cost (types erased at compile time)
- Prevents passing plaintext where encrypted expected
- Prevents passing encrypted where plaintext expected
- Self-documenting function signatures
- TypeScript enforces correct value handling
## Verification
- TypeScript: 0 errors
- Linting: 0 errors
- Build: Success (340.20 kB, 93.41 kB gzipped)
- Build time: 3.99s (improved from 4.64s)
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
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