diff --git a/.golangci.yml b/.golangci.yml
index 006ed93331dec..0782be05312ec 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -59,6 +59,18 @@ issues:
# at this time there are too many offenders.
- linters: [staticcheck]
text: 'BlockUntil is deprecated: New code should prefer BlockUntilContext'
+ # lib/utils/aws/ subpackages are allowed to use AWS SDK constructors.
+ - path: lib/utils/aws/stsutils/sts.go
+ linters: [forbidigo]
+ text: 'sts.NewFromConfig'
+ - path: lib/utils/aws/stsutils/sts_v1.go
+ linters: [forbidigo]
+ text: 'sts.New'
+ # TODO(codingllama): Remove once e/ is updated.
+ - path: e/lib/cloud/aws/aws.go
+ linters: [forbidigo]
+ text: 'sts.NewFromConfig'
+
exclude-use-default: true
max-same-issues: 0
max-issues-per-linter: 0
@@ -390,6 +402,10 @@ linters-settings:
forbid:
- p: '^rsa\.GenerateKey$'
msg: 'generating RSA keys is slow, use lib/cryptosuites to generate an appropriate key type'
+ - p: '^sts\.NewFromConfig$'
+ msg: 'Use stsutils.NewFromConfig'
+ - p: '^sts\.New$'
+ msg: 'Use stsutils.NewV1'
run:
go: '1.23'
diff --git a/integration/ec2_test.go b/integration/ec2_test.go
index a151d169d25a0..6bbce4276e0df 100644
--- a/integration/ec2_test.go
+++ b/integration/ec2_test.go
@@ -51,6 +51,7 @@ import (
"github.com/gravitational/teleport/lib/service/servicecfg"
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/utils"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
logutils "github.com/gravitational/teleport/lib/utils/log"
)
@@ -143,7 +144,7 @@ func getCallerIdentity(ctx context.Context, t *testing.T) *sts.GetCallerIdentity
cfg.Region, err = imdsClient.GetRegion(ctx)
require.NoError(t, err, "trying to get local region from IMDSv2")
}
- stsClient := sts.NewFromConfig(cfg)
+ stsClient := stsutils.NewFromConfig(cfg)
output, err := stsClient.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})
require.NoError(t, err)
return output
diff --git a/lib/auth/join/iam/iam.go b/lib/auth/join/iam/iam.go
index aa69ebd26d521..951c0175ca3f9 100644
--- a/lib/auth/join/iam/iam.go
+++ b/lib/auth/join/iam/iam.go
@@ -34,6 +34,7 @@ import (
"go.opentelemetry.io/otel"
cloudaws "github.com/gravitational/teleport/lib/cloud/imds/aws"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
const (
@@ -103,7 +104,7 @@ func CreateSignedSTSIdentityRequest(ctx context.Context, challenge string, opts
}
var signedRequest bytes.Buffer
- stsClient := sts.NewFromConfig(awsConfig,
+ stsClient := stsutils.NewFromConfig(awsConfig,
sts.WithEndpointResolverV2(newCustomResolver(challenge)),
func(stsOpts *sts.Options) {
if options.useFIPS {
diff --git a/lib/auth/join_ec2.go b/lib/auth/join_ec2.go
index 376ff47d4c91a..3bf273c34056a 100644
--- a/lib/auth/join_ec2.go
+++ b/lib/auth/join_ec2.go
@@ -44,6 +44,7 @@ import (
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/utils"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
type ec2Client interface {
@@ -101,7 +102,7 @@ func checkInstanceRunning(ctx context.Context, instanceID, region, IAMRole strin
// assume the configured IAM role if necessary
if IAMRole != "" {
- stsClient := sts.NewFromConfig(awsClientConfig, func(o *sts.Options) {
+ stsClient := stsutils.NewFromConfig(awsClientConfig, func(o *sts.Options) {
o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider())
})
creds := stscreds.NewAssumeRoleProvider(stsClient, IAMRole)
diff --git a/lib/auth/keystore/aws_kms.go b/lib/auth/keystore/aws_kms.go
index 0a5c6824fe55d..32f63b7ce30fb 100644
--- a/lib/auth/keystore/aws_kms.go
+++ b/lib/auth/keystore/aws_kms.go
@@ -47,6 +47,7 @@ import (
"github.com/gravitational/teleport/api/utils/retryutils"
"github.com/gravitational/teleport/lib/cryptosuites"
"github.com/gravitational/teleport/lib/service/servicecfg"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
const (
@@ -83,9 +84,10 @@ func newAWSKMSKeystore(ctx context.Context, cfg *servicecfg.AWSKMSConfig, opts *
return nil, trace.Wrap(err, "loading default AWS config")
}
if stsClient == nil {
- stsClient = sts.NewFromConfig(awsCfg, func(o *sts.Options) {
+ stsClient = stsutils.NewFromConfig(awsCfg, func(o *sts.Options) {
o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider())
})
+
}
if kmsClient == nil {
kmsClient = kms.NewFromConfig(awsCfg, func(o *kms.Options) {
diff --git a/lib/backend/dynamo/dynamodbbk.go b/lib/backend/dynamo/dynamodbbk.go
index d86f946c1985c..dfe17fd071bc2 100644
--- a/lib/backend/dynamo/dynamodbbk.go
+++ b/lib/backend/dynamo/dynamodbbk.go
@@ -47,9 +47,9 @@ import (
"github.com/gravitational/teleport/api/utils"
"github.com/gravitational/teleport/lib/backend"
"github.com/gravitational/teleport/lib/defaults"
- "github.com/gravitational/teleport/lib/modules"
awsmetrics "github.com/gravitational/teleport/lib/observability/metrics/aws"
dynamometrics "github.com/gravitational/teleport/lib/observability/metrics/dynamo"
+ "github.com/gravitational/teleport/lib/utils/aws/dynamodbutils"
"github.com/gravitational/teleport/lib/utils/aws/endpoint"
)
@@ -293,7 +293,8 @@ func New(ctx context.Context, params backend.Params) (*Backend, error) {
// FIPS settings are applied on the individual service instead of the aws config,
// as Application Auto Scaling do not yet have FIPS endpoints in non-GovCloud.
// See also: https://aws.amazon.com/compliance/fips/#FIPS_Endpoints_by_Service
- if modules.GetModules().IsBoringBinary() {
+ useFIPS := dynamodbutils.IsFIPSEnabled()
+ if useFIPS {
dynamoOpts = append(dynamoOpts, func(o *dynamodb.Options) {
o.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled
})
@@ -322,7 +323,7 @@ func New(ctx context.Context, params backend.Params) (*Backend, error) {
// FIPS settings are applied on the individual service instead of the aws config,
// as Application Auto Scaling do not yet have FIPS endpoints in non-GovCloud.
// See also: https://aws.amazon.com/compliance/fips/#FIPS_Endpoints_by_Service
- if modules.GetModules().IsBoringBinary() {
+ if useFIPS {
streamsOpts = append(streamsOpts, func(o *dynamodbstreams.Options) {
o.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled
})
diff --git a/lib/cloud/awsconfig/awsconfig.go b/lib/cloud/awsconfig/awsconfig.go
index 5e6967d2d4909..bbb1fb2c77e09 100644
--- a/lib/cloud/awsconfig/awsconfig.go
+++ b/lib/cloud/awsconfig/awsconfig.go
@@ -34,6 +34,7 @@ import (
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/modules"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
const defaultRegion = "us-east-1"
@@ -136,9 +137,10 @@ func (o *options) checkAndSetDefaults() error {
if o.stsClientProvider == nil {
o.stsClientProvider = func(cfg aws.Config) STSClient {
- return sts.NewFromConfig(cfg, func(o *sts.Options) {
+ return stsutils.NewFromConfig(cfg, func(o *sts.Options) {
o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider())
})
+
}
}
return nil
diff --git a/lib/configurators/aws/aws.go b/lib/configurators/aws/aws.go
index e1dac54ba8031..490a737127c58 100644
--- a/lib/configurators/aws/aws.go
+++ b/lib/configurators/aws/aws.go
@@ -51,6 +51,7 @@ import (
"github.com/gravitational/teleport/lib/srv/db/secrets"
"github.com/gravitational/teleport/lib/utils"
awsutils "github.com/gravitational/teleport/lib/utils/aws"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
const (
@@ -390,9 +391,10 @@ func (c *ConfiguratorConfig) CheckAndSetDefaults() error {
}
if c.stsClient == nil {
- c.stsClient = sts.NewFromConfig(*c.awsCfg, func(o *sts.Options) {
+ c.stsClient = stsutils.NewFromConfig(*c.awsCfg, func(o *sts.Options) {
o.TracerProvider = smithyoteltracing.Adapt(otel.GetTracerProvider())
})
+
}
if c.iamClient == nil {
c.iamClient = iam.NewFromConfig(*c.awsCfg, func(o *iam.Options) {
diff --git a/lib/events/dynamoevents/dynamoevents.go b/lib/events/dynamoevents/dynamoevents.go
index 97eeae0172495..df7a1ac3012f1 100644
--- a/lib/events/dynamoevents/dynamoevents.go
+++ b/lib/events/dynamoevents/dynamoevents.go
@@ -59,10 +59,10 @@ import (
apievents "github.com/gravitational/teleport/api/types/events"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/events"
- "github.com/gravitational/teleport/lib/modules"
awsmetrics "github.com/gravitational/teleport/lib/observability/metrics/aws"
dynamometrics "github.com/gravitational/teleport/lib/observability/metrics/dynamo"
"github.com/gravitational/teleport/lib/utils"
+ "github.com/gravitational/teleport/lib/utils/aws/dynamodbutils"
"github.com/gravitational/teleport/lib/utils/aws/endpoint"
)
@@ -330,7 +330,8 @@ func New(ctx context.Context, cfg Config) (*Log, error) {
// FIPS settings are applied on the individual service instead of the aws config,
// as DynamoDB Streams and Application Auto Scaling do not yet have FIPS endpoints in non-GovCloud.
// See also: https://aws.amazon.com/compliance/fips/#FIPS_Endpoints_by_Service
- if modules.GetModules().IsBoringBinary() && cfg.UseFIPSEndpoint == types.ClusterAuditConfigSpecV2_FIPS_ENABLED {
+ if dynamodbutils.IsFIPSEnabled() &&
+ cfg.UseFIPSEndpoint == types.ClusterAuditConfigSpecV2_FIPS_ENABLED {
dynamoOpts = append(dynamoOpts, func(o *dynamodb.Options) {
o.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled
})
diff --git a/lib/events/dynamoevents/dynamoevents_test.go b/lib/events/dynamoevents/dynamoevents_test.go
index 572ccc3891791..a176cff26a354 100644
--- a/lib/events/dynamoevents/dynamoevents_test.go
+++ b/lib/events/dynamoevents/dynamoevents_test.go
@@ -610,21 +610,34 @@ func randStringAlpha(n int) string {
}
func TestEndpoints(t *testing.T) {
+ // Don't t.Parallel(), uses t.Setenv and modules.SetTestModules.
+
tests := []struct {
- name string
- fips bool
+ name string
+ fips bool
+ envVarValue string // value for the _DISABLE_FIPS environment variable
+ wantFIPSError bool
}{
{
- name: "fips",
- fips: true,
+ name: "fips",
+ fips: true,
+ wantFIPSError: true,
+ },
+ {
+ name: "fips with env skip",
+ fips: true,
+ envVarValue: "yes",
+ wantFIPSError: false,
},
{
- name: "without fips",
+ name: "without fips",
+ wantFIPSError: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
+ t.Setenv("TELEPORT_UNSTABLE_DISABLE_AWS_FIPS", tt.envVarValue)
fips := types.ClusterAuditConfigSpecV2_FIPS_DISABLED
if tt.fips {
@@ -658,15 +671,13 @@ func TestEndpoints(t *testing.T) {
})
// FIPS mode should fail because it is a violation to enable FIPS
// while also setting a custom endpoint.
- if tt.fips {
- assert.Error(t, err)
- require.ErrorContains(t, err, "FIPS")
+ if tt.wantFIPSError {
+ assert.ErrorContains(t, err, "FIPS")
return
}
- assert.Error(t, err)
- assert.Nil(t, b)
- require.ErrorContains(t, err, fmt.Sprintf("StatusCode: %d", http.StatusTeapot))
+ assert.ErrorContains(t, err, fmt.Sprintf("StatusCode: %d", http.StatusTeapot))
+ assert.Nil(t, b, "backend not nil")
})
}
}
diff --git a/lib/integrations/awsoidc/accessgraph_sync.go b/lib/integrations/awsoidc/accessgraph_sync.go
index d6f6b497429f5..30232598b5e6f 100644
--- a/lib/integrations/awsoidc/accessgraph_sync.go
+++ b/lib/integrations/awsoidc/accessgraph_sync.go
@@ -24,12 +24,12 @@ import (
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/iam"
- "github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/gravitational/trace"
awslib "github.com/gravitational/teleport/lib/cloud/aws"
"github.com/gravitational/teleport/lib/cloud/provisioning"
"github.com/gravitational/teleport/lib/cloud/provisioning/awsactions"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
const (
@@ -90,7 +90,7 @@ func NewAccessGraphIAMConfigureClient(ctx context.Context) (AccessGraphIAMConfig
}
return &defaultTAGIAMConfigureClient{
- CallerIdentityGetter: sts.NewFromConfig(cfg),
+ CallerIdentityGetter: stsutils.NewFromConfig(cfg),
Client: iam.NewFromConfig(cfg),
}, nil
}
diff --git a/lib/integrations/awsoidc/aws_app_access_iam_config.go b/lib/integrations/awsoidc/aws_app_access_iam_config.go
index 70cf3e191ecaf..46fae5ad677d3 100644
--- a/lib/integrations/awsoidc/aws_app_access_iam_config.go
+++ b/lib/integrations/awsoidc/aws_app_access_iam_config.go
@@ -25,13 +25,13 @@ import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/iam"
- "github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/gravitational/trace"
awslib "github.com/gravitational/teleport/lib/cloud/aws"
"github.com/gravitational/teleport/lib/cloud/provisioning"
"github.com/gravitational/teleport/lib/cloud/provisioning/awsactions"
"github.com/gravitational/teleport/lib/modules"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
const (
@@ -109,7 +109,7 @@ func NewAWSAppAccessConfigureClient(ctx context.Context) (AWSAppAccessConfigureC
return &defaultAWSAppAccessConfigureClient{
Client: iam.NewFromConfig(cfg),
- CallerIdentityGetter: sts.NewFromConfig(cfg),
+ CallerIdentityGetter: stsutils.NewFromConfig(cfg),
}, nil
}
diff --git a/lib/integrations/awsoidc/clients.go b/lib/integrations/awsoidc/clients.go
index 52be22b0dabe8..1a7128ef20107 100644
--- a/lib/integrations/awsoidc/clients.go
+++ b/lib/integrations/awsoidc/clients.go
@@ -33,6 +33,7 @@ import (
"github.com/gravitational/trace"
awsutils "github.com/gravitational/teleport/api/utils/aws"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
// AWSClientRequest contains the required fields to set up an AWS service client.
@@ -85,7 +86,7 @@ func newAWSConfig(ctx context.Context, req *AWSClientRequest) (*aws.Config, erro
}
cfg.Credentials = stscreds.NewWebIdentityRoleProvider(
- sts.NewFromConfig(cfg),
+ stsutils.NewFromConfig(cfg),
req.RoleARN,
IdentityToken(req.Token),
)
@@ -129,7 +130,7 @@ func newSTSClient(ctx context.Context, req *AWSClientRequest) (*sts.Client, erro
return nil, trace.Wrap(err)
}
- return sts.NewFromConfig(*cfg), nil
+ return stsutils.NewFromConfig(*cfg), nil
}
// newEC2Client creates an [ec2.Client] using the provided Token, RoleARN and Region.
diff --git a/lib/integrations/awsoidc/clientsv1.go b/lib/integrations/awsoidc/clientsv1.go
index ae2e0be6a186b..576badf79951d 100644
--- a/lib/integrations/awsoidc/clientsv1.go
+++ b/lib/integrations/awsoidc/clientsv1.go
@@ -26,12 +26,12 @@ import (
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/session"
- "github.com/aws/aws-sdk-go/service/sts"
"github.com/gravitational/trace"
"github.com/gravitational/teleport/api/types"
utilsaws "github.com/gravitational/teleport/api/utils/aws"
"github.com/gravitational/teleport/lib/modules"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
// FetchToken returns the token.
@@ -89,7 +89,7 @@ func NewSessionV1(ctx context.Context, client IntegrationTokenGenerator, region
return []byte(token), trace.Wrap(err)
}
- stsSTS := sts.New(sess)
+ stsSTS := stsutils.NewV1(sess)
roleProvider := stscreds.NewWebIdentityRoleProviderWithOptions(
stsSTS,
awsOIDCIntegration.RoleARN,
diff --git a/lib/integrations/awsoidc/credprovider/integration_config_provider.go b/lib/integrations/awsoidc/credprovider/integration_config_provider.go
index 76ed003113588..3145ae6f5b69c 100644
--- a/lib/integrations/awsoidc/credprovider/integration_config_provider.go
+++ b/lib/integrations/awsoidc/credprovider/integration_config_provider.go
@@ -24,13 +24,13 @@ import (
"github.com/aws/aws-sdk-go-v2/aws/arn"
awsConfig "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"
"github.com/gravitational/trace"
"github.com/jonboulle/clockwork"
"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/modules"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
// Options represents additional options for configuring the AWS credentials provider.
@@ -53,7 +53,7 @@ func CreateAWSConfigForIntegration(ctx context.Context, config Config, option ..
return nil, trace.Wrap(err)
}
if config.STSClient == nil {
- config.STSClient = sts.NewFromConfig(*cacheAWSConfig)
+ config.STSClient = stsutils.NewFromConfig(*cacheAWSConfig)
}
credCache, err := newAWSCredCache(ctx, config, config.STSClient)
if err != nil {
diff --git a/lib/integrations/awsoidc/deployservice_iam_config.go b/lib/integrations/awsoidc/deployservice_iam_config.go
index 761a91539a9f2..d7b5b764c1962 100644
--- a/lib/integrations/awsoidc/deployservice_iam_config.go
+++ b/lib/integrations/awsoidc/deployservice_iam_config.go
@@ -25,7 +25,6 @@ import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/iam"
- "github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/gravitational/trace"
awsapiutils "github.com/gravitational/teleport/api/utils/aws"
@@ -34,6 +33,7 @@ import (
"github.com/gravitational/teleport/lib/cloud/provisioning/awsactions"
"github.com/gravitational/teleport/lib/integrations/awsoidc/tags"
awslibutils "github.com/gravitational/teleport/lib/utils/aws"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
var taskRoleDescription = "Used by Teleport Database Service deployed in Amazon ECS."
@@ -147,7 +147,7 @@ func NewDeployServiceIAMConfigureClient(ctx context.Context, region string) (Dep
return &defaultDeployServiceIAMConfigureClient{
Client: iam.NewFromConfig(cfg),
- CallerIdentityGetter: sts.NewFromConfig(cfg),
+ CallerIdentityGetter: stsutils.NewFromConfig(cfg),
}, nil
}
diff --git a/lib/integrations/awsoidc/ec2_ssm_iam_config.go b/lib/integrations/awsoidc/ec2_ssm_iam_config.go
index 7a479e97ca9f3..c2116a5cda714 100644
--- a/lib/integrations/awsoidc/ec2_ssm_iam_config.go
+++ b/lib/integrations/awsoidc/ec2_ssm_iam_config.go
@@ -26,13 +26,13 @@ import (
"github.com/aws/aws-sdk-go-v2/service/iam"
"github.com/aws/aws-sdk-go-v2/service/ssm"
ssmtypes "github.com/aws/aws-sdk-go-v2/service/ssm/types"
- "github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/gravitational/trace"
awslib "github.com/gravitational/teleport/lib/cloud/aws"
"github.com/gravitational/teleport/lib/cloud/provisioning"
"github.com/gravitational/teleport/lib/cloud/provisioning/awsactions"
"github.com/gravitational/teleport/lib/integrations/awsoidc/tags"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
const (
@@ -145,7 +145,7 @@ func NewEC2SSMConfigureClient(ctx context.Context, region string) (EC2SSMConfigu
return &defaultEC2SSMConfigureClient{
Client: iam.NewFromConfig(cfg),
ssmClient: ssm.NewFromConfig(cfg),
- CallerIdentityGetter: sts.NewFromConfig(cfg),
+ CallerIdentityGetter: stsutils.NewFromConfig(cfg),
}, nil
}
diff --git a/lib/integrations/awsoidc/eks_iam_config.go b/lib/integrations/awsoidc/eks_iam_config.go
index bb65522bb74a4..c4b13a5ed1dda 100644
--- a/lib/integrations/awsoidc/eks_iam_config.go
+++ b/lib/integrations/awsoidc/eks_iam_config.go
@@ -24,12 +24,12 @@ import (
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/iam"
- "github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/gravitational/trace"
awslib "github.com/gravitational/teleport/lib/cloud/aws"
"github.com/gravitational/teleport/lib/cloud/provisioning"
"github.com/gravitational/teleport/lib/cloud/provisioning/awsactions"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
const (
@@ -101,7 +101,7 @@ func NewEKSIAMConfigureClient(ctx context.Context, region string) (EKSIAMConfigu
return &defaultEKSEIAMConfigureClient{
Client: iam.NewFromConfig(cfg),
- CallerIdentityGetter: sts.NewFromConfig(cfg),
+ CallerIdentityGetter: stsutils.NewFromConfig(cfg),
}, nil
}
diff --git a/lib/integrations/awsoidc/idp_iam_config.go b/lib/integrations/awsoidc/idp_iam_config.go
index e02e7ef36325a..9b2a00e9f7da0 100644
--- a/lib/integrations/awsoidc/idp_iam_config.go
+++ b/lib/integrations/awsoidc/idp_iam_config.go
@@ -27,7 +27,6 @@ import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/iam"
- "github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/gravitational/trace"
"github.com/gravitational/teleport/api/types"
@@ -36,6 +35,7 @@ import (
"github.com/gravitational/teleport/lib/cloud/provisioning/awsactions"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/integrations/awsoidc/tags"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
const (
@@ -195,7 +195,7 @@ func NewIdPIAMConfigureClient(ctx context.Context) (IdPIAMConfigureClient, error
httpClient: httpClient,
awsConfig: cfg,
Client: iam.NewFromConfig(cfg),
- CallerIdentityGetter: sts.NewFromConfig(cfg),
+ CallerIdentityGetter: stsutils.NewFromConfig(cfg),
}, nil
}
diff --git a/lib/integrations/awsoidc/listdatabases_iam_config.go b/lib/integrations/awsoidc/listdatabases_iam_config.go
index ab8205f78f615..bec7e1a00de73 100644
--- a/lib/integrations/awsoidc/listdatabases_iam_config.go
+++ b/lib/integrations/awsoidc/listdatabases_iam_config.go
@@ -24,12 +24,12 @@ import (
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/iam"
- "github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/gravitational/trace"
awslib "github.com/gravitational/teleport/lib/cloud/aws"
"github.com/gravitational/teleport/lib/cloud/provisioning"
"github.com/gravitational/teleport/lib/cloud/provisioning/awsactions"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
var (
@@ -93,7 +93,7 @@ func NewListDatabasesIAMConfigureClient(ctx context.Context, region string) (Lis
return &defaultListDatabasesIAMConfigureClient{
Client: iam.NewFromConfig(cfg),
- CallerIdentityGetter: sts.NewFromConfig(cfg),
+ CallerIdentityGetter: stsutils.NewFromConfig(cfg),
}, nil
}
diff --git a/lib/integrations/externalauditstorage/configurator.go b/lib/integrations/externalauditstorage/configurator.go
index 739ee9d7342a3..ab18f44aee9a5 100644
--- a/lib/integrations/externalauditstorage/configurator.go
+++ b/lib/integrations/externalauditstorage/configurator.go
@@ -26,7 +26,6 @@ import (
"github.com/aws/aws-sdk-go-v2/aws/arn"
"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"
"github.com/gravitational/trace"
"github.com/jonboulle/clockwork"
@@ -36,6 +35,7 @@ import (
"github.com/gravitational/teleport/lib/integrations/awsoidc/credprovider"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/services"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
const (
@@ -109,7 +109,7 @@ func (o *Options) setDefaults(ctx context.Context, region string) error {
if err != nil {
return trace.Wrap(err)
}
- o.stsClient = sts.NewFromConfig(cfg)
+ o.stsClient = stsutils.NewFromConfig(cfg)
}
return nil
}
diff --git a/lib/kube/proxy/server.go b/lib/kube/proxy/server.go
index f153039d60749..41b7c43773183 100644
--- a/lib/kube/proxy/server.go
+++ b/lib/kube/proxy/server.go
@@ -52,6 +52,7 @@ import (
"github.com/gravitational/teleport/lib/services/readonly"
"github.com/gravitational/teleport/lib/srv"
"github.com/gravitational/teleport/lib/srv/ingress"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
// TLSServerConfig is a configuration for TLS server
@@ -122,7 +123,7 @@ func (f *awsClientsGetter) GetAWSEKSClient(cfg aws.Config) EKSClient {
}
func (f *awsClientsGetter) GetAWSSTSPresignClient(cfg aws.Config) STSPresignClient {
- stsClient := sts.NewFromConfig(cfg)
+ stsClient := stsutils.NewFromConfig(cfg)
return sts.NewPresignClient(stsClient)
}
diff --git a/lib/srv/alpnproxy/local_proxy_test.go b/lib/srv/alpnproxy/local_proxy_test.go
index ed010a9e4faae..1e98812c4707c 100644
--- a/lib/srv/alpnproxy/local_proxy_test.go
+++ b/lib/srv/alpnproxy/local_proxy_test.go
@@ -125,6 +125,7 @@ func TestHandleAWSAccessSigVerification(t *testing.T) {
Path: "/",
}
+ //nolint:forbidigo // OK to not use "stsutils" on tests.
clt := sts.New(sts.Options{
APIOptions: tc.apiOpts,
Region: awsRegion,
diff --git a/lib/srv/app/aws/handler_test.go b/lib/srv/app/aws/handler_test.go
index 4f19b9fb18a95..39f604a06eb40 100644
--- a/lib/srv/app/aws/handler_test.go
+++ b/lib/srv/app/aws/handler_test.go
@@ -59,6 +59,7 @@ import (
"github.com/gravitational/teleport/lib/tlsca"
"github.com/gravitational/teleport/lib/utils"
awsutils "github.com/gravitational/teleport/lib/utils/aws"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
func TestMain(m *testing.M) {
@@ -147,7 +148,7 @@ func lambdaRequestWithPayload(url string, provider client.ConfigProvider, payloa
func assumeRoleRequest(requestDuration time.Duration) makeRequest {
return func(url string, provider client.ConfigProvider, _ string) error {
- stsClient := sts.New(provider, &aws.Config{
+ stsClient := stsutils.NewV1(provider, &aws.Config{
Endpoint: &url,
MaxRetries: aws.Int(0),
HTTPClient: &http.Client{
diff --git a/lib/srv/db/cloud/meta.go b/lib/srv/db/cloud/meta.go
index 9a1de680d9ed6..bf2f6f07cd0a5 100644
--- a/lib/srv/db/cloud/meta.go
+++ b/lib/srv/db/cloud/meta.go
@@ -44,6 +44,7 @@ import (
"github.com/gravitational/teleport/lib/cloud/awsconfig"
"github.com/gravitational/teleport/lib/srv/db/common"
discoverycommon "github.com/gravitational/teleport/lib/srv/discovery/common"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
logutils "github.com/gravitational/teleport/lib/utils/log"
)
@@ -141,7 +142,7 @@ func (defaultAWSClients) getRedshiftServerlessClient(cfg aws.Config, optFns ...f
}
func (defaultAWSClients) getSTSClient(cfg aws.Config, optFns ...func(*sts.Options)) stsClient {
- return sts.NewFromConfig(cfg, optFns...)
+ return stsutils.NewFromConfig(cfg, optFns...)
}
// MetadataConfig is the cloud metadata service config.
diff --git a/lib/srv/db/common/auth.go b/lib/srv/db/common/auth.go
index 9fdd254521bca..67510a8c42c17 100644
--- a/lib/srv/db/common/auth.go
+++ b/lib/srv/db/common/auth.go
@@ -62,6 +62,7 @@ import (
"github.com/gravitational/teleport/lib/tlsca"
"github.com/gravitational/teleport/lib/utils"
awsutils "github.com/gravitational/teleport/lib/utils/aws"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
const (
@@ -164,7 +165,7 @@ func (defaultAWSClients) getRedshiftServerlessClient(cfg aws.Config, optFns ...f
}
func (defaultAWSClients) getSTSClient(cfg aws.Config, optFns ...func(*sts.Options)) stsClient {
- return sts.NewFromConfig(cfg, optFns...)
+ return stsutils.NewFromConfig(cfg, optFns...)
}
// AuthConfig is the database access authenticator configuration.
diff --git a/lib/srv/db/dynamodb/engine.go b/lib/srv/db/dynamodb/engine.go
index 165d856677f9d..7ee66251b59bd 100644
--- a/lib/srv/db/dynamodb/engine.go
+++ b/lib/srv/db/dynamodb/engine.go
@@ -43,11 +43,11 @@ import (
"github.com/gravitational/teleport/lib/cloud/awsconfig"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/events"
- "github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/srv/db/common"
"github.com/gravitational/teleport/lib/srv/db/common/role"
"github.com/gravitational/teleport/lib/utils"
libaws "github.com/gravitational/teleport/lib/utils/aws"
+ "github.com/gravitational/teleport/lib/utils/aws/dynamodbutils"
)
// NewEngine create new DynamoDB engine.
@@ -55,7 +55,7 @@ func NewEngine(ec common.EngineConfig) common.Engine {
return &Engine{
EngineConfig: ec,
RoundTrippers: make(map[string]http.RoundTripper),
- UseFIPS: modules.GetModules().IsBoringBinary(),
+ UseFIPS: dynamodbutils.IsFIPSEnabled(),
}
}
diff --git a/lib/srv/discovery/discovery.go b/lib/srv/discovery/discovery.go
index b29cef50e2cc9..f553be87d6c5b 100644
--- a/lib/srv/discovery/discovery.go
+++ b/lib/srv/discovery/discovery.go
@@ -64,6 +64,7 @@ import (
azure_sync "github.com/gravitational/teleport/lib/srv/discovery/fetchers/azuresync"
"github.com/gravitational/teleport/lib/srv/discovery/fetchers/db"
"github.com/gravitational/teleport/lib/srv/server"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
logutils "github.com/gravitational/teleport/lib/utils/log"
libslices "github.com/gravitational/teleport/lib/utils/slices"
"github.com/gravitational/teleport/lib/utils/spreadwork"
@@ -214,11 +215,11 @@ func (f *awsFetchersClientsGetter) GetAWSEKSClient(cfg aws.Config) fetchers.EKSC
}
func (f *awsFetchersClientsGetter) GetAWSSTSClient(cfg aws.Config) fetchers.STSClient {
- return sts.NewFromConfig(cfg)
+ return stsutils.NewFromConfig(cfg)
}
func (f *awsFetchersClientsGetter) GetAWSSTSPresignClient(cfg aws.Config) fetchers.STSPresignClient {
- stsClient := sts.NewFromConfig(cfg)
+ stsClient := stsutils.NewFromConfig(cfg)
return sts.NewPresignClient(stsClient)
}
diff --git a/lib/srv/discovery/fetchers/aws-sync/aws-sync.go b/lib/srv/discovery/fetchers/aws-sync/aws-sync.go
index 6567158fbbe9a..3de3bd9637c6b 100644
--- a/lib/srv/discovery/fetchers/aws-sync/aws-sync.go
+++ b/lib/srv/discovery/fetchers/aws-sync/aws-sync.go
@@ -37,6 +37,7 @@ import (
accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha"
"github.com/gravitational/teleport/lib/cloud/awsconfig"
"github.com/gravitational/teleport/lib/srv/server"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
// pageSize is the default page size to use when fetching AWS resources
@@ -134,7 +135,7 @@ func (defaultAWSClients) getS3Client(cfg aws.Config, optFns ...func(*s3.Options)
}
func (defaultAWSClients) getSTSClient(cfg aws.Config, optFns ...func(*sts.Options)) stsClient {
- return sts.NewFromConfig(cfg, optFns...)
+ return stsutils.NewFromConfig(cfg, optFns...)
}
// AssumeRole is the configuration for assuming an AWS role.
diff --git a/lib/utils/aws/dynamodbutils/dynamo.go b/lib/utils/aws/dynamodbutils/dynamo.go
new file mode 100644
index 0000000000000..822ee28c3ce7d
--- /dev/null
+++ b/lib/utils/aws/dynamodbutils/dynamo.go
@@ -0,0 +1,30 @@
+// Teleport
+// Copyright (C) 2025 Gravitational, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package dynamodbutils
+
+import (
+ "github.com/gravitational/teleport/lib/modules"
+ awsutils "github.com/gravitational/teleport/lib/utils/aws"
+)
+
+// IsFIPSEnabled returns true if FIPS should be enabled for DynamoDB.
+// FIPS is enabled is the binary is boring ([modules.Modules.IsBoringBinary])
+// and if FIPS is not disabled by the environment
+// ([awsutils.IsFIPSDisabledByEnv]).
+func IsFIPSEnabled() bool {
+ return !awsutils.IsFIPSDisabledByEnv() && modules.GetModules().IsBoringBinary()
+}
diff --git a/lib/utils/aws/dynamodbutils/dynamo_test.go b/lib/utils/aws/dynamodbutils/dynamo_test.go
new file mode 100644
index 0000000000000..22207b53bb00d
--- /dev/null
+++ b/lib/utils/aws/dynamodbutils/dynamo_test.go
@@ -0,0 +1,65 @@
+// Teleport
+// Copyright (C) 2025 Gravitational, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package dynamodbutils_test
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+
+ "github.com/gravitational/teleport/lib/modules"
+ "github.com/gravitational/teleport/lib/utils/aws/dynamodbutils"
+)
+
+func TestIsFIPSEnabled(t *testing.T) {
+ // Don't t.Parallel(), uses t.Setenv and modules.SetTestModules.
+
+ tests := []struct {
+ name string
+ fips bool
+ envVarValue string // value for the _DISABLE_FIPS environment variable
+ want bool
+ }{
+ {
+ name: "non-FIPS binary",
+ want: false,
+ },
+ {
+ name: "FIPS binary",
+ fips: true,
+ want: true,
+ },
+ {
+ name: "FIPS binary with skip",
+ fips: true,
+ envVarValue: "yes",
+ want: false,
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ t.Setenv("TELEPORT_UNSTABLE_DISABLE_AWS_FIPS", test.envVarValue)
+
+ modules.SetTestModules(t, &modules.TestModules{
+ FIPS: test.fips,
+ })
+
+ got := dynamodbutils.IsFIPSEnabled()
+ assert.Equal(t, test.want, got, "IsFIPSEnabled mismatch")
+ })
+ }
+}
diff --git a/lib/utils/aws/fips_disabled.go b/lib/utils/aws/fips_disabled.go
new file mode 100644
index 0000000000000..6773a61413770
--- /dev/null
+++ b/lib/utils/aws/fips_disabled.go
@@ -0,0 +1,42 @@
+// Teleport
+// Copyright (C) 2025 Gravitational, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package aws
+
+import (
+ "os"
+ "strconv"
+)
+
+// IsFIPSDisabledByEnv returns true if the TELEPORT_UNSTABLE_DISABLE_AWS_FIPS
+// environment variable is set.
+//
+// Either "yes" or a "truthy" value (as defined by [strconv.ParseBool]) are
+// considered true.
+//
+// Prefer using specific functions, such as those in the
+// lib/utils/aws/stsutils or lib/utils/aws/dynamodbutils packages.
+func IsFIPSDisabledByEnv() bool {
+ const envVar = "TELEPORT_UNSTABLE_DISABLE_AWS_FIPS"
+
+ // Disable FIPS endpoint?
+ if val := os.Getenv(envVar); val != "" {
+ b, _ := strconv.ParseBool(val)
+ return b || val == "yes"
+ }
+
+ return false
+}
diff --git a/lib/utils/aws/stsutils/sts.go b/lib/utils/aws/stsutils/sts.go
new file mode 100644
index 0000000000000..70f3d63196dce
--- /dev/null
+++ b/lib/utils/aws/stsutils/sts.go
@@ -0,0 +1,38 @@
+// Teleport
+// Copyright (C) 2025 Gravitational, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package stsutils
+
+import (
+ "github.com/aws/aws-sdk-go-v2/aws"
+ "github.com/aws/aws-sdk-go-v2/service/sts"
+
+ awsutils "github.com/gravitational/teleport/lib/utils/aws"
+)
+
+// NewFromConfig wraps [sts.NewFromConfig] and applies FIPS settings
+// according to environment variables.
+//
+// See [awsutils.IsFIPSDisabledByEnv].
+func NewFromConfig(cfg aws.Config, optFns ...func(*sts.Options)) *sts.Client {
+ if awsutils.IsFIPSDisabledByEnv() {
+ // append so it overrides any preceding settings.
+ optFns = append(optFns, func(opts *sts.Options) {
+ opts.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateDisabled
+ })
+ }
+ return sts.NewFromConfig(cfg, optFns...)
+}
diff --git a/lib/utils/aws/stsutils/sts_test.go b/lib/utils/aws/stsutils/sts_test.go
new file mode 100644
index 0000000000000..5fa915a32e4b7
--- /dev/null
+++ b/lib/utils/aws/stsutils/sts_test.go
@@ -0,0 +1,79 @@
+// Teleport
+// Copyright (C) 2025 Gravitational, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package stsutils_test
+
+import (
+ "testing"
+
+ "github.com/aws/aws-sdk-go-v2/aws"
+ "github.com/aws/aws-sdk-go-v2/service/sts"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
+)
+
+func TestNewFromConfig(t *testing.T) {
+ // Don't t.Parallel(), uses t.Setenv().
+
+ cfg := aws.Config{}
+ opts := func(opts *sts.Options) {
+ opts.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled
+ }
+
+ tests := []struct {
+ name string
+ envVarValue string // value for the _DISABLE_FIPS environment variable
+ want aws.FIPSEndpointState
+ }{
+ {
+ name: "env not set",
+ want: aws.FIPSEndpointStateEnabled,
+ },
+ {
+ name: "invalid does not change FIPS",
+ envVarValue: "llama",
+ want: aws.FIPSEndpointStateEnabled,
+ },
+ {
+ name: "false does not change FIPS",
+ envVarValue: "0",
+ want: aws.FIPSEndpointStateEnabled,
+ },
+ {
+ name: `"yes" disables FIPS`,
+ envVarValue: "yes",
+ want: aws.FIPSEndpointStateDisabled,
+ },
+ {
+ name: "1 disables FIPS",
+ envVarValue: "1",
+ want: aws.FIPSEndpointStateDisabled,
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ t.Setenv("TELEPORT_UNSTABLE_DISABLE_AWS_FIPS", test.envVarValue)
+
+ stsClient := stsutils.NewFromConfig(cfg, opts)
+ require.NotNil(t, stsClient, "*sts.Client")
+
+ got := stsClient.Options().EndpointOptions.UseFIPSEndpoint
+ assert.Equal(t, test.want, got, "opts.EndpointOptions.UseFIPSEndpoint mismatch")
+ })
+ }
+}
diff --git a/lib/utils/aws/stsutils/sts_v1.go b/lib/utils/aws/stsutils/sts_v1.go
new file mode 100644
index 0000000000000..3d17e272de847
--- /dev/null
+++ b/lib/utils/aws/stsutils/sts_v1.go
@@ -0,0 +1,37 @@
+// Teleport
+// Copyright (C) 2025 Gravitational, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package stsutils
+
+import (
+ "github.com/aws/aws-sdk-go/aws"
+ "github.com/aws/aws-sdk-go/aws/client"
+ "github.com/aws/aws-sdk-go/service/sts"
+
+ awsutils "github.com/gravitational/teleport/lib/utils/aws"
+)
+
+// NewV1 wraps [sts.New] and applies FIPS settings according to environment
+// variables.
+//
+// See [awsutils.IsFIPSDisabledByEnv].
+func NewV1(p client.ConfigProvider, cfgs ...*aws.Config) *sts.STS {
+ if awsutils.IsFIPSDisabledByEnv() {
+ // append so it overrides any preceding settings.
+ cfgs = append(cfgs, aws.NewConfig().WithUseFIPSEndpoint(false))
+ }
+ return sts.New(p, cfgs...)
+}
diff --git a/lib/utils/aws/stsutils/sts_v1_test.go b/lib/utils/aws/stsutils/sts_v1_test.go
new file mode 100644
index 0000000000000..685bd558af75f
--- /dev/null
+++ b/lib/utils/aws/stsutils/sts_v1_test.go
@@ -0,0 +1,91 @@
+// Teleport
+// Copyright (C) 2025 Gravitational, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package stsutils_test
+
+import (
+ "testing"
+
+ "github.com/aws/aws-sdk-go/aws"
+ "github.com/aws/aws-sdk-go/aws/client"
+ "github.com/aws/aws-sdk-go/aws/endpoints"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
+)
+
+func TestNewV1(t *testing.T) {
+ // Don't t.Parallel(), uses t.Setenv().
+
+ configProvider := &mockConfigProvider{
+ Config: client.Config{
+ Config: aws.NewConfig().WithUseFIPSEndpoint(true),
+ },
+ }
+
+ tests := []struct {
+ name string
+ envVarValue string // value for the _DISABLE_FIPS environment variable
+ want endpoints.FIPSEndpointState
+ }{
+ {
+ name: "env not set",
+ want: endpoints.FIPSEndpointStateEnabled,
+ },
+ {
+ name: "invalid does not change FIPS",
+ envVarValue: "llama",
+ want: endpoints.FIPSEndpointStateEnabled,
+ },
+ {
+ name: "false does not change FIPS",
+ envVarValue: "0",
+ want: endpoints.FIPSEndpointStateEnabled,
+ },
+ {
+ name: `"yes" disables FIPS`,
+ envVarValue: "yes",
+ want: endpoints.FIPSEndpointStateDisabled,
+ },
+ {
+ name: "1 disables FIPS",
+ envVarValue: "1",
+ want: endpoints.FIPSEndpointStateDisabled,
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ t.Setenv("TELEPORT_UNSTABLE_DISABLE_AWS_FIPS", test.envVarValue)
+
+ stsClient := stsutils.NewV1(configProvider)
+ require.NotNil(t, stsClient, "*sts.Client")
+
+ got := stsClient.Config.UseFIPSEndpoint
+ assert.Equal(t, test.want, got, "opts.EndpointOptions.UseFIPSEndpoint mismatch")
+ })
+ }
+}
+
+type mockConfigProvider struct {
+ Config client.Config
+}
+
+func (m *mockConfigProvider) ClientConfig(_ string, cfgs ...*aws.Config) client.Config {
+ cc := m.Config
+ cc.Config = cc.Config.Copy(cfgs...)
+ return cc
+}
diff --git a/tool/teleport/common/integration_configure.go b/tool/teleport/common/integration_configure.go
index 514f61b2ab84b..236a6cc6ef093 100644
--- a/tool/teleport/common/integration_configure.go
+++ b/tool/teleport/common/integration_configure.go
@@ -28,7 +28,6 @@ import (
"github.com/aws/aws-sdk-go-v2/service/glue"
"github.com/aws/aws-sdk-go-v2/service/iam"
"github.com/aws/aws-sdk-go-v2/service/s3"
- "github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/gravitational/trace"
ecatypes "github.com/gravitational/teleport/api/types/externalauditstorage"
@@ -41,6 +40,7 @@ import (
"github.com/gravitational/teleport/lib/integrations/samlidp"
"github.com/gravitational/teleport/lib/integrations/samlidp/samlidpconfig"
"github.com/gravitational/teleport/lib/utils"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
func onIntegrationConfDeployService(ctx context.Context, params config.IntegrationConfDeployServiceIAM) error {
@@ -170,7 +170,7 @@ func onIntegrationConfExternalAuditCmd(ctx context.Context, params easconfig.Ext
}
if params.AccountID != "" {
- stsClient := sts.NewFromConfig(cfg)
+ stsClient := stsutils.NewFromConfig(cfg)
err = awsoidc.CheckAccountID(ctx, stsClient, params.AccountID)
if err != nil {
return trace.Wrap(err)
@@ -201,7 +201,7 @@ func onIntegrationConfExternalAuditCmd(ctx context.Context, params easconfig.Ext
clt := &awsoidc.DefaultConfigureExternalAuditStorageClient{
Iam: iam.NewFromConfig(cfg),
- Sts: sts.NewFromConfig(cfg),
+ Sts: stsutils.NewFromConfig(cfg),
}
return trace.Wrap(awsoidc.ConfigureExternalAuditStorage(ctx, clt, params))
}