Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use session token in aws authentication #9419

Merged
merged 2 commits into from
Mar 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const (
SshKnownHostsEnv = "SSH_KNOWN_HOSTS"
EksaAccessKeyIdEnv = "EKSA_AWS_ACCESS_KEY_ID"
EksaSecretAccessKeyEnv = "EKSA_AWS_SECRET_ACCESS_KEY"
EksaSessionTokenKeyEnv = "EKSA_AWS_SESSION_TOKEN"
AwsAccessKeyIdEnv = "AWS_ACCESS_KEY_ID"
AwsSecretAccessKeyEnv = "AWS_SECRET_ACCESS_KEY"
EksaAwsConfigFileEnv = "EKSA_AWS_CONFIG_FILE"
Expand Down
3 changes: 3 additions & 0 deletions pkg/curatedpackages/config/secrets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ awsSecret:
id: "{{.eksaAccessKeyId}}"
secret: "{{.eksaSecretAccessKey}}"
region: "{{.eksaRegion}}"
{{- if .eksaSessionToken }}
sessionToken: "{{.eksaSessionToken}}"
{{- end }}
config: "{{.eksaAwsConfig}}"
19 changes: 18 additions & 1 deletion pkg/curatedpackages/packagecontrollerclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type PackageControllerClient struct {
kubectl KubectlRunner
eksaAccessKeyID string
eksaSecretAccessKey string
eksaSessionToken string
eksaRegion string
eksaAwsConfig string
httpProxy string
Expand Down Expand Up @@ -270,7 +271,15 @@ func (pc *PackageControllerClient) GetCuratedPackagesRegistries(ctx context.Cont
}

regionalRegistry := GetRegionalRegistry(defaultRegistry, pc.eksaRegion)
if err := pc.registryAccessTester.Test(ctx, pc.eksaAccessKeyID, pc.eksaSecretAccessKey, pc.eksaRegion, pc.eksaAwsConfig, regionalRegistry); err == nil {
registryTestParams := RegistryAccessTestParams{
AccessKey: pc.eksaAccessKeyID,
Secret: pc.eksaSecretAccessKey,
SessionToken: pc.eksaSessionToken,
Region: pc.eksaRegion,
AwsConfig: pc.eksaAwsConfig,
Registry: regionalRegistry,
}
if err := pc.registryAccessTester.Test(ctx, registryTestParams); err == nil {
// use regional registry when the above credential is good
logger.V(6).Info("Using regional registry")
defaultRegistry = regionalRegistry
Expand Down Expand Up @@ -318,6 +327,7 @@ func (pc *PackageControllerClient) generateHelmOverrideValues() ([]byte, error)
templateValues := map[string]interface{}{
"eksaAccessKeyId": base64.StdEncoding.EncodeToString([]byte(pc.eksaAccessKeyID)),
"eksaSecretAccessKey": base64.StdEncoding.EncodeToString([]byte(pc.eksaSecretAccessKey)),
"eksaSessionToken": base64.StdEncoding.EncodeToString([]byte(pc.eksaSessionToken)),
"eksaRegion": base64.StdEncoding.EncodeToString([]byte(pc.eksaRegion)),
"eksaAwsConfig": base64.StdEncoding.EncodeToString([]byte(pc.eksaAwsConfig)),
"mirrorEndpoint": base64.StdEncoding.EncodeToString([]byte(endpoint)),
Expand Down Expand Up @@ -575,6 +585,13 @@ func WithEksaSecretAccessKey(eksaSecretAccessKey string) func(client *PackageCon
}
}

// WithEksaSessionToken set the eksaSessionToken field.
func WithEksaSessionToken(eksaSessionToken string) func(client *PackageControllerClient) {
return func(config *PackageControllerClient) {
config.eksaSessionToken = eksaSessionToken
}
}

func WithEksaRegion(eksaRegion string) func(client *PackageControllerClient) {
return func(config *PackageControllerClient) {
if eksaRegion != "" {
Expand Down
32 changes: 31 additions & 1 deletion pkg/curatedpackages/packagecontrollerclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func newPackageControllerTests(t *testing.T) []*packageControllerTest {
}
eksaAccessId := "test-access-id"
eksaAccessKey := "test-access-key"
eksaSessionToken := "test-session-token"
eksaAwsConfigFile := "test-aws-config-file"
eksaRegion := "test-region"
clusterName := "billy"
Expand Down Expand Up @@ -139,6 +140,35 @@ func newPackageControllerTests(t *testing.T) []*packageControllerTest {
writer: writer,
wantValueFile: "testdata/values_test.yaml",
},
{
WithT: NewWithT(t),
ctx: context.Background(),
kubectl: k,
chartManager: cm,
command: curatedpackages.NewPackageControllerClient(
cm, k, clusterName, kubeConfig, chart, registryMirror,
curatedpackages.WithEksaSecretAccessKey(eksaAccessKey),
curatedpackages.WithEksaRegion(eksaRegion),
curatedpackages.WithEksaAccessKeyId(eksaAccessId),
curatedpackages.WithEksaSessionToken(eksaSessionToken),
curatedpackages.WithEksaAwsConfig(eksaAwsConfigFile),
curatedpackages.WithManagementClusterName(clusterName),
curatedpackages.WithValuesFileWriter(writer),
curatedpackages.WithClusterSpec(clusterSpec),
),
clusterName: clusterName,
kubeConfig: kubeConfig,
chart: chart,
eksaAccessID: eksaAccessId,
eksaAccessKey: eksaAccessKey,
eksaRegion: eksaRegion,
httpProxy: "1.1.1.1",
httpsProxy: "1.1.1.1",
noProxy: []string{"1.1.1.1/24"},
registryMirror: registryMirror,
writer: writer,
wantValueFile: "testdata/values_with_sessiontoken.yaml",
},
{
WithT: NewWithT(t),
ctx: context.Background(),
Expand Down Expand Up @@ -1229,7 +1259,7 @@ func TestEnableFullLifecyclePath(t *testing.T) {

type stubRegistryAccessTester struct{}

func (s *stubRegistryAccessTester) Test(ctx context.Context, accessKey, secret, registry, region, awsConfig string) error {
func (s *stubRegistryAccessTester) Test(_ context.Context, _ curatedpackages.RegistryAccessTestParams) error {
return nil
}

Expand Down
30 changes: 20 additions & 10 deletions pkg/curatedpackages/regional_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,39 @@
"github.com/aws/aws-sdk-go-v2/service/ecr"
)

// RegistryAccessTestParams struct for testing resigtry access.
type RegistryAccessTestParams struct {
AccessKey string
Secret string
SessionToken string
Region string
AwsConfig string
Registry string
}

// RegistryAccessTester test if AWS credentials has valid permission to access an ECR registry.
type RegistryAccessTester interface {
Test(ctx context.Context, accessKey, secret, region, awsConfig, registry string) error
Test(ctx context.Context, params RegistryAccessTestParams) error
}

// DefaultRegistryAccessTester the default implementation of RegistryAccessTester.
type DefaultRegistryAccessTester struct{}

// Test if the AWS static credential or sharedConfig has valid permission to access an ECR registry.
func (r *DefaultRegistryAccessTester) Test(ctx context.Context, accessKey, secret, region, awsConfig, registry string) (err error) {
func (r *DefaultRegistryAccessTester) Test(ctx context.Context, params RegistryAccessTestParams) (err error) {
authTokenProvider := &DefaultRegistryAuthTokenProvider{}

var authToken string
if len(awsConfig) > 0 {
authToken, err = authTokenProvider.GetTokenByAWSConfig(ctx, awsConfig)
if len(params.AwsConfig) > 0 {
authToken, err = authTokenProvider.GetTokenByAWSConfig(ctx, params.AwsConfig)

Check warning on line 41 in pkg/curatedpackages/regional_registry.go

View check run for this annotation

Codecov / codecov/patch

pkg/curatedpackages/regional_registry.go#L41

Added line #L41 was not covered by tests
} else {
authToken, err = authTokenProvider.GetTokenByAWSKeySecret(ctx, accessKey, secret, region)
authToken, err = authTokenProvider.GetTokenByAWSKeySecret(ctx, params.AccessKey, params.Secret, params.SessionToken, params.Region)
}
if err != nil {
return err
}

return TestRegistryWithAuthToken(authToken, registry, http.DefaultClient.Do)
return TestRegistryWithAuthToken(authToken, params.Registry, http.DefaultClient.Do)

Check warning on line 49 in pkg/curatedpackages/regional_registry.go

View check run for this annotation

Codecov / codecov/patch

pkg/curatedpackages/regional_registry.go#L49

Added line #L49 was not covered by tests
}

// TestRegistryWithAuthToken test if the registry can be acccessed with auth token.
Expand Down Expand Up @@ -116,9 +126,9 @@
}

// GetAWSConfigFromKeySecret get AWS config from key, secret and region.
func GetAWSConfigFromKeySecret(ctx context.Context, key, secret, region string) (*aws.Config, error) {
func GetAWSConfigFromKeySecret(ctx context.Context, key, secret, sessionToken, region string) (*aws.Config, error) {
cfg, err := config.LoadDefaultConfig(ctx,
config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(key, secret, "")),
config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(key, secret, sessionToken)),
config.WithRegion(region),
)
if err != nil {
Expand All @@ -128,8 +138,8 @@
}

// GetTokenByAWSKeySecret get auth token by AWS key and secret.
func (d *DefaultRegistryAuthTokenProvider) GetTokenByAWSKeySecret(ctx context.Context, key, secret, region string) (string, error) {
cfg, err := GetAWSConfigFromKeySecret(ctx, key, secret, region)
func (d *DefaultRegistryAuthTokenProvider) GetTokenByAWSKeySecret(ctx context.Context, key, secret, sessionToken, region string) (string, error) {
cfg, err := GetAWSConfigFromKeySecret(ctx, key, secret, sessionToken, region)
if err != nil {
return "", err
}
Expand Down
6 changes: 5 additions & 1 deletion pkg/curatedpackages/regional_registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ aws_secret_access_key=secret
}

func TestGetAWSConfigFromKeySecret(t *testing.T) {
cfg, err := curatedpackages.GetAWSConfigFromKeySecret(context.Background(), "key", "secret", "us-west-2")
cfg, err := curatedpackages.GetAWSConfigFromKeySecret(context.Background(), "key", "secret", "sessionToken", "us-west-2")
if err != nil {
t.Errorf("Error parsing AWS Config: %s", err)
}
Expand All @@ -183,6 +183,10 @@ func TestGetAWSConfigFromKeySecret(t *testing.T) {
t.Errorf("secret is not generated correctly")
}

if cred.SessionToken != "sessionToken" {
t.Errorf("sessionToken is not generated correctly")
}

if cfg.Region != "us-west-2" {
t.Errorf("Region is not parsed correctly")
}
Expand Down
12 changes: 12 additions & 0 deletions pkg/curatedpackages/testdata/values_with_sessiontoken.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
registryMirrorSecret:
endpoint: "MS4yLjMuNDo0NDM="
username: "dXNlcm5hbWU="
password: "cGFzc3dvcmQ="
cacertcontent: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCmFiYwplZmcKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo="
insecure: "ZmFsc2U="
awsSecret:
id: "dGVzdC1hY2Nlc3MtaWQ="
secret: "dGVzdC1hY2Nlc3Mta2V5"
region: "dGVzdC1yZWdpb24="
sessionToken: "dGVzdC1zZXNzaW9uLXRva2Vu"
config: "dGVzdC1hd3MtY29uZmlnLWZpbGU="
3 changes: 2 additions & 1 deletion pkg/dependencies/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -1363,7 +1363,7 @@ func (f *Factory) WithPackageControllerClient(spec *cluster.Spec, kubeConfig str
mgmtKubeConfig := kubeconfig.ResolveFilename(kubeConfig, managementClusterName)

httpProxy, httpsProxy, noProxy := getProxyConfiguration(spec)
eksaAccessKeyID, eksaSecretKey, eksaRegion := os.Getenv(cliconfig.EksaAccessKeyIdEnv), os.Getenv(cliconfig.EksaSecretAccessKeyEnv), os.Getenv(cliconfig.EksaRegionEnv)
eksaAccessKeyID, eksaSecretKey, eksaRegion, eksSessionToken := os.Getenv(cliconfig.EksaAccessKeyIdEnv), os.Getenv(cliconfig.EksaSecretAccessKeyEnv), os.Getenv(cliconfig.EksaRegionEnv), os.Getenv(cliconfig.EksaSessionTokenKeyEnv)

eksaAwsConfig := ""
p := os.Getenv(cliconfig.EksaAwsConfigFileEnv)
Expand All @@ -1386,6 +1386,7 @@ func (f *Factory) WithPackageControllerClient(spec *cluster.Spec, kubeConfig str
options := []curatedpackages.PackageControllerClientOpt{
curatedpackages.WithEksaAccessKeyId(eksaAccessKeyID),
curatedpackages.WithEksaSecretAccessKey(eksaSecretKey),
curatedpackages.WithEksaSessionToken(eksSessionToken),
curatedpackages.WithEksaRegion(eksaRegion),
curatedpackages.WithEksaAwsConfig(eksaAwsConfig),
curatedpackages.WithHTTPProxy(httpProxy),
Expand Down
1 change: 1 addition & 0 deletions pkg/executables/executables.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ var redactedEnvKeys = []string{
githubTokenEnv,
config.EksaAccessKeyIdEnv,
config.EksaSecretAccessKeyEnv,
config.EksaSessionTokenKeyEnv,
config.AwsAccessKeyIdEnv,
config.AwsSecretAccessKeyEnv,
constants.SnowCredentialsKey,
Expand Down
3 changes: 1 addition & 2 deletions test/e2e/curatedpackages.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ func WaitForResource(
if !strings.HasPrefix(jsonpath, "jsonpath") {
jsonpath = fmt.Sprintf("jsonpath='%s'", jsonpath)
}
command := []string{}
for time.Now().Before(end) {
out, err := test.KubectlClient.Execute(ctx, "get", "-n", namespace,
"--kubeconfig="+kubeconfig.FromClusterName(test.ClusterName),
Expand All @@ -137,7 +136,7 @@ func WaitForResource(
}
return fmt.Errorf(
"timed out waiting for resource: %s [namespace: %s, jsonpath: %s, timeout: %s]",
command,
resource,
namespace,
jsonpath,
timeout,
Expand Down
16 changes: 9 additions & 7 deletions test/framework/curatedpackages.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,21 @@ func WithPackageConfig(t *testing.T, bundleURI, chartName, chartURI,
}

const (
eksaPackagesSecretKey = "EKSA_AWS_SECRET_ACCESS_KEY"
eksaPackagesAccessKey = "EKSA_AWS_ACCESS_KEY_ID"
eksaPackagesRegion = "EKSA_AWS_REGION"
route53AccessKey = "ROUTE53_ACCESS_KEY_ID"
route53SecretKey = "ROUTE53_SECRET_ACCESS_KEY"
route53Region = "ROUTE53_REGION"
route53ZoneID = "ROUTE53_ZONEID"
eksaPackagesSecretKey = "EKSA_AWS_SECRET_ACCESS_KEY"
eksaPackagesAccessKey = "EKSA_AWS_ACCESS_KEY_ID"
eksaPackagesSessionTokenKey = "EKSA_AWS_SESSION_TOKEN"
eksaPackagesRegion = "EKSA_AWS_REGION"
route53AccessKey = "ROUTE53_ACCESS_KEY_ID"
route53SecretKey = "ROUTE53_SECRET_ACCESS_KEY"
route53Region = "ROUTE53_REGION"
route53ZoneID = "ROUTE53_ZONEID"
)

var requiredPackagesEnvVars = []string{
eksaPackagesRegion,
eksaPackagesAccessKey,
eksaPackagesSecretKey,
eksaPackagesSessionTokenKey,
}

var requiredCertManagerEnvVars = []string{
Expand Down