Skip to content

Commit

Permalink
cloud connectors role chainning
Browse files Browse the repository at this point in the history
  • Loading branch information
moukoublen committed Jan 29, 2025
1 parent acb197b commit 6eb24ec
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 2 deletions.
5 changes: 3 additions & 2 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ type CloudConfig struct {
}

type AwsConfig struct {
Cred aws.ConfigAWS `config:"credentials"`
AccountType string `config:"account_type"`
Cred aws.ConfigAWS `config:"credentials"`
AccountType string `config:"account_type"`
CloudConnectors bool `config:"supports_cloud_connectors"`
}

type GcpConfig struct {
Expand Down
74 changes: 74 additions & 0 deletions internal/resources/providers/awslib/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@
package awslib

import (
"context"
"fmt"
"net/http"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/aws/retry"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
libbeataws "github.com/elastic/beats/v7/x-pack/libbeat/common/aws"
)

Expand All @@ -43,3 +49,71 @@ func InitializeAWSConfig(cfg libbeataws.ConfigAWS) (*aws.Config, error) {

return &awsConfig, nil
}

func CloudConnectorsExternalID(resourceID, externalIDPart string) string {
return fmt.Sprintf("%s-%s", resourceID, externalIDPart)
}

func InitializeAWSConfigCloudConnectors(
ctx context.Context,
elasticSuperRoleLocalARN string,
elasticSuperRoleGlobalARN string,
resourceID string,
cfg libbeataws.ConfigAWS,
) (aws.Config, error) {
// 1. Load initial config
// (TODO: check directly assuming the first role in chain and/or libbeataws.InitializeAWSConfig(cfg))
// (TODO: consider os.Setenv("AWS_EC2_METADATA_DISABLED", "true"))
awsConfig, err := config.LoadDefaultConfig(ctx)
if err != nil {
return aws.Config{}, err
}

// Create an STS client using the base credentials
firstClient := sts.NewFromConfig(awsConfig)

const defaultDuration = 5 * time.Minute

// Chain Part 1 - Elastic Super Role Local
localSuperRoleProvider := stscreds.NewAssumeRoleProvider(
firstClient,
elasticSuperRoleLocalARN,
func(aro *stscreds.AssumeRoleOptions) {
aro.RoleSessionName = "cloudbeat-super-role-local"
aro.Duration = defaultDuration
},
)
localSuperRoleCredentialsCache := aws.NewCredentialsCache(localSuperRoleProvider)

// Chain Part 2 - Elastic Super Role Global
globalSuperRoleCfg := awsConfig
globalSuperRoleCfg.Credentials = localSuperRoleCredentialsCache
globalSuperRoleProvider := stscreds.NewAssumeRoleProvider(
sts.NewFromConfig(globalSuperRoleCfg),
elasticSuperRoleGlobalARN,
func(aro *stscreds.AssumeRoleOptions) {
aro.RoleSessionName = "cloudbeat-super-role-global"
aro.Duration = defaultDuration
},
)
globalSuperRoleCredentialsCache := aws.NewCredentialsCache(globalSuperRoleProvider)

// Chain Part 3 - Elastic Super Role Local
customerRemoteRoleCfg := awsConfig
customerRemoteRoleCfg.Credentials = globalSuperRoleCredentialsCache
customerRemoteRoleProvider := stscreds.NewAssumeRoleProvider(
sts.NewFromConfig(customerRemoteRoleCfg),
cfg.RoleArn, // Customer Remote Role passed in package policy.
func(aro *stscreds.AssumeRoleOptions) {
aro.RoleSessionName = "cloudbeat-remote-role"
aro.Duration = cfg.AssumeRoleDuration
aro.ExternalID = aws.String(CloudConnectorsExternalID(resourceID, cfg.ExternalID))
},
)
customerRemoteRoleCredentialsCache := aws.NewCredentialsCache(customerRemoteRoleProvider)

ret := awsConfig
ret.Credentials = customerRemoteRoleCredentialsCache

return ret, nil
}

0 comments on commit 6eb24ec

Please sign in to comment.