mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-05-23 18:21:28 +00:00
Fix STS credential validation by providing default configuration
When no STS configuration is provided in the IAM config file, the STS service was not being initialized, causing temporary credentials from AssumeRole to be rejected with "InvalidAccessKeyId" errors. This commit adds a DefaultSTSConfig() function that provides sensible defaults (1h token duration, 12h max session, secure random signing key) and updates the IAM manager to use these defaults when no explicit STS configuration is provided. Changes: - Add DefaultSTSConfig() with secure random signing key generation - Update IAM manager to use default config when config.STS is nil - Add tests verifying initialization with and without explicit config Fixes #8312
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/iam/policy"
|
||||
"github.com/seaweedfs/seaweedfs/weed/iam/providers"
|
||||
"github.com/seaweedfs/seaweedfs/weed/iam/sts"
|
||||
@@ -103,7 +104,15 @@ func (m *IAMManager) Initialize(config *IAMConfig, filerAddressProvider func() s
|
||||
|
||||
// Initialize STS service
|
||||
m.stsService = sts.NewSTSService()
|
||||
if err := m.stsService.Initialize(config.STS); err != nil {
|
||||
|
||||
// Use default config if none provided
|
||||
stsConfig := config.STS
|
||||
if stsConfig == nil {
|
||||
glog.V(1).Infof("No STS configuration provided, using defaults")
|
||||
stsConfig = sts.DefaultSTSConfig()
|
||||
}
|
||||
|
||||
if err := m.stsService.Initialize(stsConfig); err != nil {
|
||||
return fmt.Errorf("failed to initialize STS service: %w", err)
|
||||
}
|
||||
|
||||
|
||||
108
weed/iam/integration/iam_manager_sts_test.go
Normal file
108
weed/iam/integration/iam_manager_sts_test.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/iam/policy"
|
||||
"github.com/seaweedfs/seaweedfs/weed/iam/sts"
|
||||
)
|
||||
|
||||
// TestIAMManagerInitializeWithoutSTSConfig tests that IAM manager can initialize
|
||||
// without an explicit STS configuration by using defaults
|
||||
func TestIAMManagerInitializeWithoutSTSConfig(t *testing.T) {
|
||||
manager := NewIAMManager()
|
||||
|
||||
// Create config without STS section (nil)
|
||||
// But with minimal policy and role configs to satisfy other components
|
||||
config := &IAMConfig{
|
||||
STS: nil, // No STS config provided - will use defaults
|
||||
Policy: &policy.PolicyEngineConfig{
|
||||
DefaultEffect: "Deny",
|
||||
StoreType: "memory",
|
||||
},
|
||||
Roles: &RoleStoreConfig{
|
||||
StoreType: "memory",
|
||||
},
|
||||
}
|
||||
|
||||
// Initialize should succeed with default STS config
|
||||
err := manager.Initialize(config, func() string { return "localhost:8888" })
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to initialize IAM manager without STS config: %v", err)
|
||||
}
|
||||
|
||||
// Verify STS service is initialized
|
||||
stsService := manager.GetSTSService()
|
||||
if stsService == nil {
|
||||
t.Fatal("STS service is nil after initialization")
|
||||
}
|
||||
|
||||
if !stsService.IsInitialized() {
|
||||
t.Fatal("STS service is not initialized")
|
||||
}
|
||||
|
||||
// Verify the default config was applied
|
||||
if stsService.Config.Issuer != "seaweedfs-sts" {
|
||||
t.Errorf("Expected default issuer 'seaweedfs-sts', got '%s'", stsService.Config.Issuer)
|
||||
}
|
||||
|
||||
if stsService.Config.TokenDuration.Duration != 1*time.Hour {
|
||||
t.Errorf("Expected default token duration 1h, got %v", stsService.Config.TokenDuration.Duration)
|
||||
}
|
||||
|
||||
if stsService.Config.MaxSessionLength.Duration != 12*time.Hour {
|
||||
t.Errorf("Expected default max session length 12h, got %v", stsService.Config.MaxSessionLength.Duration)
|
||||
}
|
||||
|
||||
t.Logf("Successfully initialized STS service with default configuration")
|
||||
}
|
||||
|
||||
// TestIAMManagerInitializeWithExplicitSTSConfig tests that explicit STS config still works
|
||||
func TestIAMManagerInitializeWithExplicitSTSConfig(t *testing.T) {
|
||||
manager := NewIAMManager()
|
||||
|
||||
// Create config with explicit STS section
|
||||
config := &IAMConfig{
|
||||
STS: &sts.STSConfig{
|
||||
TokenDuration: sts.FlexibleDuration{Duration: 30 * time.Minute},
|
||||
MaxSessionLength: sts.FlexibleDuration{Duration: 2 * time.Hour},
|
||||
Issuer: "custom-issuer",
|
||||
SigningKey: []byte("custom-signing-key-for-testing-purposes-only"),
|
||||
AccountId: "999888777666",
|
||||
},
|
||||
Policy: &policy.PolicyEngineConfig{
|
||||
DefaultEffect: "Deny",
|
||||
StoreType: "memory",
|
||||
},
|
||||
Roles: &RoleStoreConfig{
|
||||
StoreType: "memory",
|
||||
},
|
||||
}
|
||||
|
||||
// Initialize should succeed with explicit config
|
||||
err := manager.Initialize(config, func() string { return "localhost:8888" })
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to initialize IAM manager with explicit STS config: %v", err)
|
||||
}
|
||||
|
||||
// Verify STS service uses the custom config
|
||||
stsService := manager.GetSTSService()
|
||||
if stsService == nil {
|
||||
t.Fatal("STS service is nil after initialization")
|
||||
}
|
||||
|
||||
if !stsService.IsInitialized() {
|
||||
t.Fatal("STS service is not initialized")
|
||||
}
|
||||
|
||||
if stsService.Config.Issuer != "custom-issuer" {
|
||||
t.Errorf("Expected issuer 'custom-issuer', got '%s'", stsService.Config.Issuer)
|
||||
}
|
||||
|
||||
if stsService.Config.AccountId != "999888777666" {
|
||||
t.Errorf("Expected account ID '999888777666', got '%s'", stsService.Config.AccountId)
|
||||
}
|
||||
|
||||
t.Logf("Successfully initialized STS service with explicit configuration")
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package sts
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -258,6 +259,28 @@ func NewSTSService() *STSService {
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultSTSConfig returns a default STS configuration with sensible defaults
|
||||
// This ensures the STS service can be initialized even when no explicit configuration is provided
|
||||
func DefaultSTSConfig() *STSConfig {
|
||||
// Generate a secure random signing key
|
||||
signingKey := make([]byte, 32) // 256 bits
|
||||
if _, err := rand.Read(signingKey); err != nil {
|
||||
// Fallback to a warning message if random generation fails
|
||||
// This should never happen in practice, but we handle it defensively
|
||||
glog.Warningf("Failed to generate random signing key, using deterministic fallback: %v", err)
|
||||
signingKey = []byte("default-signing-key-change-in-production-environments")
|
||||
}
|
||||
|
||||
return &STSConfig{
|
||||
TokenDuration: FlexibleDuration{Duration: 1 * time.Hour}, // 1 hour default
|
||||
MaxSessionLength: FlexibleDuration{Duration: 12 * time.Hour}, // 12 hours max
|
||||
Issuer: "seaweedfs-sts",
|
||||
SigningKey: signingKey,
|
||||
AccountId: "111122223333", // Default AWS account ID
|
||||
Providers: nil, // No providers by default
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize initializes the STS service with configuration
|
||||
func (s *STSService) Initialize(config *STSConfig) error {
|
||||
if config == nil {
|
||||
|
||||
Reference in New Issue
Block a user