@ -11,20 +11,20 @@ import (
// IAMManager orchestrates all IAM components
// IAMManager orchestrates all IAM components
type IAMManager struct {
type IAMManager struct {
stsService * sts . STSService
policyEngine * policy . PolicyEngine
roleStore RoleStore
initialized bool
stsService * sts . STSService
policyEngine * policy . PolicyEngine
roleStore RoleStore
initialized bool
}
}
// IAMConfig holds configuration for all IAM components
// IAMConfig holds configuration for all IAM components
type IAMConfig struct {
type IAMConfig struct {
// STS service configuration
// STS service configuration
STS * sts . STSConfig ` json:"sts" `
STS * sts . STSConfig ` json:"sts" `
// Policy engine configuration
// Policy engine configuration
Policy * policy . PolicyEngineConfig ` json:"policy" `
Policy * policy . PolicyEngineConfig ` json:"policy" `
// Role store configuration
// Role store configuration
Roles * RoleStoreConfig ` json:"roleStore" `
Roles * RoleStoreConfig ` json:"roleStore" `
}
}
@ -42,16 +42,16 @@ type RoleStoreConfig struct {
type RoleDefinition struct {
type RoleDefinition struct {
// RoleName is the name of the role
// RoleName is the name of the role
RoleName string ` json:"roleName" `
RoleName string ` json:"roleName" `
// RoleArn is the full ARN of the role
// RoleArn is the full ARN of the role
RoleArn string ` json:"roleArn" `
RoleArn string ` json:"roleArn" `
// TrustPolicy defines who can assume this role
// TrustPolicy defines who can assume this role
TrustPolicy * policy . PolicyDocument ` json:"trustPolicy" `
TrustPolicy * policy . PolicyDocument ` json:"trustPolicy" `
// AttachedPolicies lists the policy names attached to this role
// AttachedPolicies lists the policy names attached to this role
AttachedPolicies [ ] string ` json:"attachedPolicies" `
AttachedPolicies [ ] string ` json:"attachedPolicies" `
// Description is an optional description of the role
// Description is an optional description of the role
Description string ` json:"description,omitempty" `
Description string ` json:"description,omitempty" `
}
}
@ -60,16 +60,16 @@ type RoleDefinition struct {
type ActionRequest struct {
type ActionRequest struct {
// Principal is the entity performing the action
// Principal is the entity performing the action
Principal string ` json:"principal" `
Principal string ` json:"principal" `
// Action is the action being requested
// Action is the action being requested
Action string ` json:"action" `
Action string ` json:"action" `
// Resource is the resource being accessed
// Resource is the resource being accessed
Resource string ` json:"resource" `
Resource string ` json:"resource" `
// SessionToken for temporary credential validation
// SessionToken for temporary credential validation
SessionToken string ` json:"sessionToken" `
SessionToken string ` json:"sessionToken" `
// RequestContext contains additional request information
// RequestContext contains additional request information
RequestContext map [ string ] interface { } ` json:"requestContext,omitempty" `
RequestContext map [ string ] interface { } ` json:"requestContext,omitempty" `
}
}
@ -84,26 +84,26 @@ func (m *IAMManager) Initialize(config *IAMConfig) error {
if config == nil {
if config == nil {
return fmt . Errorf ( "config cannot be nil" )
return fmt . Errorf ( "config cannot be nil" )
}
}
// Initialize STS service
// Initialize STS service
m . stsService = sts . NewSTSService ( )
m . stsService = sts . NewSTSService ( )
if err := m . stsService . Initialize ( config . STS ) ; err != nil {
if err := m . stsService . Initialize ( config . STS ) ; err != nil {
return fmt . Errorf ( "failed to initialize STS service: %w" , err )
return fmt . Errorf ( "failed to initialize STS service: %w" , err )
}
}
// Initialize policy engine
// Initialize policy engine
m . policyEngine = policy . NewPolicyEngine ( )
m . policyEngine = policy . NewPolicyEngine ( )
if err := m . policyEngine . Initialize ( config . Policy ) ; err != nil {
if err := m . policyEngine . Initialize ( config . Policy ) ; err != nil {
return fmt . Errorf ( "failed to initialize policy engine: %w" , err )
return fmt . Errorf ( "failed to initialize policy engine: %w" , err )
}
}
// Initialize role store
// Initialize role store
roleStore , err := m . createRoleStore ( config . Roles )
roleStore , err := m . createRoleStore ( config . Roles )
if err != nil {
if err != nil {
return fmt . Errorf ( "failed to initialize role store: %w" , err )
return fmt . Errorf ( "failed to initialize role store: %w" , err )
}
}
m . roleStore = roleStore
m . roleStore = roleStore
m . initialized = true
m . initialized = true
return nil
return nil
}
}
@ -114,7 +114,7 @@ func (m *IAMManager) createRoleStore(config *RoleStoreConfig) (RoleStore, error)
// Default to memory role store
// Default to memory role store
return NewMemoryRoleStore ( ) , nil
return NewMemoryRoleStore ( ) , nil
}
}
switch config . StoreType {
switch config . StoreType {
case "" , "memory" :
case "" , "memory" :
return NewMemoryRoleStore ( ) , nil
return NewMemoryRoleStore ( ) , nil
@ -130,7 +130,7 @@ func (m *IAMManager) RegisterIdentityProvider(provider providers.IdentityProvide
if ! m . initialized {
if ! m . initialized {
return fmt . Errorf ( "IAM manager not initialized" )
return fmt . Errorf ( "IAM manager not initialized" )
}
}
return m . stsService . RegisterProvider ( provider )
return m . stsService . RegisterProvider ( provider )
}
}
@ -139,7 +139,7 @@ func (m *IAMManager) CreatePolicy(ctx context.Context, name string, policyDoc *p
if ! m . initialized {
if ! m . initialized {
return fmt . Errorf ( "IAM manager not initialized" )
return fmt . Errorf ( "IAM manager not initialized" )
}
}
return m . policyEngine . AddPolicy ( name , policyDoc )
return m . policyEngine . AddPolicy ( name , policyDoc )
}
}
@ -148,27 +148,27 @@ func (m *IAMManager) CreateRole(ctx context.Context, roleName string, roleDef *R
if ! m . initialized {
if ! m . initialized {
return fmt . Errorf ( "IAM manager not initialized" )
return fmt . Errorf ( "IAM manager not initialized" )
}
}
if roleName == "" {
if roleName == "" {
return fmt . Errorf ( "role name cannot be empty" )
return fmt . Errorf ( "role name cannot be empty" )
}
}
if roleDef == nil {
if roleDef == nil {
return fmt . Errorf ( "role definition cannot be nil" )
return fmt . Errorf ( "role definition cannot be nil" )
}
}
// Set role ARN if not provided
// Set role ARN if not provided
if roleDef . RoleArn == "" {
if roleDef . RoleArn == "" {
roleDef . RoleArn = fmt . Sprintf ( "arn:seaweed:iam::role/%s" , roleName )
roleDef . RoleArn = fmt . Sprintf ( "arn:seaweed:iam::role/%s" , roleName )
}
}
// Validate trust policy
// Validate trust policy
if roleDef . TrustPolicy != nil {
if roleDef . TrustPolicy != nil {
if err := policy . ValidateTrustPolicyDocument ( roleDef . TrustPolicy ) ; err != nil {
if err := policy . ValidateTrustPolicyDocument ( roleDef . TrustPolicy ) ; err != nil {
return fmt . Errorf ( "invalid trust policy: %w" , err )
return fmt . Errorf ( "invalid trust policy: %w" , err )
}
}
}
}
// Store role definition
// Store role definition
return m . roleStore . StoreRole ( ctx , roleName , roleDef )
return m . roleStore . StoreRole ( ctx , roleName , roleDef )
}
}
@ -178,21 +178,21 @@ func (m *IAMManager) AssumeRoleWithWebIdentity(ctx context.Context, request *sts
if ! m . initialized {
if ! m . initialized {
return nil , fmt . Errorf ( "IAM manager not initialized" )
return nil , fmt . Errorf ( "IAM manager not initialized" )
}
}
// Extract role name from ARN
// Extract role name from ARN
roleName := extractRoleNameFromArn ( request . RoleArn )
roleName := extractRoleNameFromArn ( request . RoleArn )
// Get role definition
// Get role definition
roleDef , err := m . roleStore . GetRole ( ctx , roleName )
roleDef , err := m . roleStore . GetRole ( ctx , roleName )
if err != nil {
if err != nil {
return nil , fmt . Errorf ( "role not found: %s" , roleName )
return nil , fmt . Errorf ( "role not found: %s" , roleName )
}
}
// Validate trust policy before allowing STS to assume the role
// Validate trust policy before allowing STS to assume the role
if err := m . validateTrustPolicyForWebIdentity ( ctx , roleDef , request . WebIdentityToken ) ; err != nil {
if err := m . validateTrustPolicyForWebIdentity ( ctx , roleDef , request . WebIdentityToken ) ; err != nil {
return nil , fmt . Errorf ( "trust policy validation failed: %w" , err )
return nil , fmt . Errorf ( "trust policy validation failed: %w" , err )
}
}
// Use STS service to assume the role
// Use STS service to assume the role
return m . stsService . AssumeRoleWithWebIdentity ( ctx , request )
return m . stsService . AssumeRoleWithWebIdentity ( ctx , request )
}
}
@ -202,21 +202,21 @@ func (m *IAMManager) AssumeRoleWithCredentials(ctx context.Context, request *sts
if ! m . initialized {
if ! m . initialized {
return nil , fmt . Errorf ( "IAM manager not initialized" )
return nil , fmt . Errorf ( "IAM manager not initialized" )
}
}
// Extract role name from ARN
// Extract role name from ARN
roleName := extractRoleNameFromArn ( request . RoleArn )
roleName := extractRoleNameFromArn ( request . RoleArn )
// Get role definition
// Get role definition
roleDef , err := m . roleStore . GetRole ( ctx , roleName )
roleDef , err := m . roleStore . GetRole ( ctx , roleName )
if err != nil {
if err != nil {
return nil , fmt . Errorf ( "role not found: %s" , roleName )
return nil , fmt . Errorf ( "role not found: %s" , roleName )
}
}
// Validate trust policy
// Validate trust policy
if err := m . validateTrustPolicyForCredentials ( ctx , roleDef , request ) ; err != nil {
if err := m . validateTrustPolicyForCredentials ( ctx , roleDef , request ) ; err != nil {
return nil , fmt . Errorf ( "trust policy validation failed: %w" , err )
return nil , fmt . Errorf ( "trust policy validation failed: %w" , err )
}
}
// Use STS service to assume the role
// Use STS service to assume the role
return m . stsService . AssumeRoleWithCredentials ( ctx , request )
return m . stsService . AssumeRoleWithCredentials ( ctx , request )
}
}
@ -226,25 +226,25 @@ func (m *IAMManager) IsActionAllowed(ctx context.Context, request *ActionRequest
if ! m . initialized {
if ! m . initialized {
return false , fmt . Errorf ( "IAM manager not initialized" )
return false , fmt . Errorf ( "IAM manager not initialized" )
}
}
// Validate session token first
// Validate session token first
_ , err := m . stsService . ValidateSessionToken ( ctx , request . SessionToken )
_ , err := m . stsService . ValidateSessionToken ( ctx , request . SessionToken )
if err != nil {
if err != nil {
return false , fmt . Errorf ( "invalid session: %w" , err )
return false , fmt . Errorf ( "invalid session: %w" , err )
}
}
// Extract role name from principal ARN
// Extract role name from principal ARN
roleName := extractRoleNameFromPrincipal ( request . Principal )
roleName := extractRoleNameFromPrincipal ( request . Principal )
if roleName == "" {
if roleName == "" {
return false , fmt . Errorf ( "could not extract role from principal: %s" , request . Principal )
return false , fmt . Errorf ( "could not extract role from principal: %s" , request . Principal )
}
}
// Get role definition
// Get role definition
roleDef , err := m . roleStore . GetRole ( ctx , roleName )
roleDef , err := m . roleStore . GetRole ( ctx , roleName )
if err != nil {
if err != nil {
return false , fmt . Errorf ( "role not found: %s" , roleName )
return false , fmt . Errorf ( "role not found: %s" , roleName )
}
}
// Create evaluation context
// Create evaluation context
evalCtx := & policy . EvaluationContext {
evalCtx := & policy . EvaluationContext {
Principal : request . Principal ,
Principal : request . Principal ,
@ -252,13 +252,13 @@ func (m *IAMManager) IsActionAllowed(ctx context.Context, request *ActionRequest
Resource : request . Resource ,
Resource : request . Resource ,
RequestContext : request . RequestContext ,
RequestContext : request . RequestContext ,
}
}
// Evaluate policies attached to the role
// Evaluate policies attached to the role
result , err := m . policyEngine . Evaluate ( ctx , evalCtx , roleDef . AttachedPolicies )
result , err := m . policyEngine . Evaluate ( ctx , evalCtx , roleDef . AttachedPolicies )
if err != nil {
if err != nil {
return false , fmt . Errorf ( "policy evaluation failed: %w" , err )
return false , fmt . Errorf ( "policy evaluation failed: %w" , err )
}
}
return result . Effect == policy . EffectAllow , nil
return result . Effect == policy . EffectAllow , nil
}
}
@ -269,7 +269,7 @@ func (m *IAMManager) ValidateTrustPolicy(ctx context.Context, roleArn, provider,
if err != nil {
if err != nil {
return false
return false
}
}
// Simple validation based on provider in trust policy
// Simple validation based on provider in trust policy
if roleDef . TrustPolicy != nil {
if roleDef . TrustPolicy != nil {
for _ , statement := range roleDef . TrustPolicy . Statement {
for _ , statement := range roleDef . TrustPolicy . Statement {
@ -284,7 +284,7 @@ func (m *IAMManager) ValidateTrustPolicy(ctx context.Context, roleArn, provider,
}
}
}
}
}
}
return false
return false
}
}
@ -293,13 +293,13 @@ func (m *IAMManager) validateTrustPolicyForWebIdentity(ctx context.Context, role
if roleDef . TrustPolicy == nil {
if roleDef . TrustPolicy == nil {
return fmt . Errorf ( "role has no trust policy" )
return fmt . Errorf ( "role has no trust policy" )
}
}
// For simplified implementation, we'll do basic validation
// For simplified implementation, we'll do basic validation
// In a full implementation, this would:
// In a full implementation, this would:
// 1. Parse the web identity token
// 1. Parse the web identity token
// 2. Check issuer against trust policy
// 2. Check issuer against trust policy
// 3. Validate conditions in trust policy
// 3. Validate conditions in trust policy
// Check if trust policy allows web identity assumption
// Check if trust policy allows web identity assumption
for _ , statement := range roleDef . TrustPolicy . Statement {
for _ , statement := range roleDef . TrustPolicy . Statement {
if statement . Effect == "Allow" {
if statement . Effect == "Allow" {
@ -315,7 +315,7 @@ func (m *IAMManager) validateTrustPolicyForWebIdentity(ctx context.Context, role
}
}
}
}
}
}
return fmt . Errorf ( "trust policy does not allow web identity assumption" )
return fmt . Errorf ( "trust policy does not allow web identity assumption" )
}
}
@ -324,7 +324,7 @@ func (m *IAMManager) validateTrustPolicyForCredentials(ctx context.Context, role
if roleDef . TrustPolicy == nil {
if roleDef . TrustPolicy == nil {
return fmt . Errorf ( "role has no trust policy" )
return fmt . Errorf ( "role has no trust policy" )
}
}
// Check if trust policy allows credential assumption for the specific provider
// Check if trust policy allows credential assumption for the specific provider
for _ , statement := range roleDef . TrustPolicy . Statement {
for _ , statement := range roleDef . TrustPolicy . Statement {
if statement . Effect == "Allow" {
if statement . Effect == "Allow" {
@ -341,7 +341,7 @@ func (m *IAMManager) validateTrustPolicyForCredentials(ctx context.Context, role
}
}
}
}
}
}
return fmt . Errorf ( "trust policy does not allow credential assumption for provider: %s" , request . ProviderName )
return fmt . Errorf ( "trust policy does not allow credential assumption for provider: %s" , request . ProviderName )
}
}
@ -385,6 +385,6 @@ func (m *IAMManager) ExpireSessionForTesting(ctx context.Context, sessionToken s
if ! m . initialized {
if ! m . initialized {
return fmt . Errorf ( "IAM manager not initialized" )
return fmt . Errorf ( "IAM manager not initialized" )
}
}
return m . stsService . ExpireSessionForTesting ( ctx , sessionToken )
return m . stsService . ExpireSessionForTesting ( ctx , sessionToken )
}
}