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>
This commit is contained in:
18
auth/auth.go
18
auth/auth.go
@@ -41,7 +41,7 @@ func NewAuthService(db *badger.DB, logger *logrus.Logger, config *types.Config)
|
||||
// StoreAPIToken stores an API token in BadgerDB with TTL
|
||||
func (s *AuthService) StoreAPIToken(tokenString string, userUUID string, scopes []string, expiresAt int64) error {
|
||||
tokenHash := utils.HashToken(tokenString)
|
||||
|
||||
|
||||
apiToken := types.APIToken{
|
||||
TokenHash: tokenHash,
|
||||
UserUUID: userUUID,
|
||||
@@ -57,13 +57,13 @@ func (s *AuthService) StoreAPIToken(tokenString string, userUUID string, scopes
|
||||
|
||||
return s.db.Update(func(txn *badger.Txn) error {
|
||||
entry := badger.NewEntry([]byte(TokenStorageKey(tokenHash)), tokenData)
|
||||
|
||||
|
||||
// Set TTL to the token expiration time
|
||||
ttl := time.Until(time.Unix(expiresAt, 0))
|
||||
if ttl > 0 {
|
||||
entry = entry.WithTTL(ttl)
|
||||
}
|
||||
|
||||
|
||||
return txn.SetEntry(entry)
|
||||
})
|
||||
}
|
||||
@@ -71,7 +71,7 @@ func (s *AuthService) StoreAPIToken(tokenString string, userUUID string, scopes
|
||||
// GetAPIToken retrieves an API token from BadgerDB by hash
|
||||
func (s *AuthService) GetAPIToken(tokenHash string) (*types.APIToken, error) {
|
||||
var apiToken types.APIToken
|
||||
|
||||
|
||||
err := s.db.View(func(txn *badger.Txn) error {
|
||||
item, err := txn.Get([]byte(TokenStorageKey(tokenHash)))
|
||||
if err != nil {
|
||||
@@ -209,22 +209,22 @@ func GetAuthContext(ctx context.Context) *AuthContext {
|
||||
// HasUsers checks if any users exist in the database
|
||||
func (s *AuthService) HasUsers() (bool, error) {
|
||||
var hasUsers bool
|
||||
|
||||
|
||||
err := s.db.View(func(txn *badger.Txn) error {
|
||||
opts := badger.DefaultIteratorOptions
|
||||
opts.PrefetchValues = false // We only need to check if keys exist
|
||||
iterator := txn.NewIterator(opts)
|
||||
defer iterator.Close()
|
||||
|
||||
|
||||
// Look for any key starting with "user:"
|
||||
prefix := []byte("user:")
|
||||
for iterator.Seek(prefix); iterator.ValidForPrefix(prefix); iterator.Next() {
|
||||
hasUsers = true
|
||||
return nil // Found at least one user, can exit early
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
|
||||
return hasUsers, err
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user