Files
kalzu-value-store/storage/compression.go
ryyst c7dcebb894 feat: implement secure cluster authentication (issue #13)
Implemented a comprehensive secure authentication mechanism for inter-node
cluster communication with the following features:

1. Global Cluster Secret (GCS)
   - Auto-generated cryptographically secure random secret (256-bit)
   - Configurable via YAML config file
   - Shared across all cluster nodes for authentication

2. Cluster Authentication Middleware
   - Validates X-Cluster-Secret and X-Node-ID headers
   - Applied to all cluster endpoints (/members/*, /merkle_tree/*, /kv_range)
   - Comprehensive logging of authentication attempts

3. Authenticated HTTP Client
   - Custom HTTP client with cluster auth headers
   - TLS support with configurable certificate verification
   - Protocol-aware (http/https based on TLS settings)

4. Secure Bootstrap Endpoint
   - New /auth/cluster-bootstrap endpoint
   - Protected by JWT authentication with admin scope
   - Allows new nodes to securely obtain cluster secret

5. Updated Cluster Communication
   - All gossip protocol requests include auth headers
   - All Merkle tree sync requests include auth headers
   - All data replication requests include auth headers

6. Configuration
   - cluster_secret: Shared secret (auto-generated if not provided)
   - cluster_tls_enabled: Enable TLS for inter-node communication
   - cluster_tls_cert_file: Path to TLS certificate
   - cluster_tls_key_file: Path to TLS private key
   - cluster_tls_skip_verify: Skip TLS verification (testing only)

This implementation addresses the security vulnerability of unprotected
cluster endpoints and provides a flexible, secure approach to protecting
internal cluster communication while allowing for automated node bootstrapping.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-02 22:19:40 +03:00

61 lines
1.5 KiB
Go

package storage
import (
"fmt"
"github.com/klauspost/compress/zstd"
)
// CompressionService handles ZSTD compression and decompression
type CompressionService struct {
compressor *zstd.Encoder
decompressor *zstd.Decoder
}
// NewCompressionService creates a new compression service
func NewCompressionService() (*CompressionService, error) {
// Initialize ZSTD compressor
compressor, err := zstd.NewWriter(nil)
if err != nil {
return nil, fmt.Errorf("failed to initialize ZSTD compressor: %v", err)
}
// Initialize ZSTD decompressor
decompressor, err := zstd.NewReader(nil)
if err != nil {
compressor.Close()
return nil, fmt.Errorf("failed to initialize ZSTD decompressor: %v", err)
}
return &CompressionService{
compressor: compressor,
decompressor: decompressor,
}, nil
}
// Close closes the compression and decompression resources
func (c *CompressionService) Close() {
if c.compressor != nil {
c.compressor.Close()
}
if c.decompressor != nil {
c.decompressor.Close()
}
}
// CompressData compresses data using ZSTD
func (c *CompressionService) CompressData(data []byte) ([]byte, error) {
if c.compressor == nil {
return nil, fmt.Errorf("compressor not initialized")
}
return c.compressor.EncodeAll(data, make([]byte, 0, len(data))), nil
}
// DecompressData decompresses ZSTD-compressed data
func (c *CompressionService) DecompressData(compressedData []byte) ([]byte, error) {
if c.decompressor == nil {
return nil, fmt.Errorf("decompressor not initialized")
}
return c.decompressor.DecodeAll(compressedData, nil)
}