diff --git a/.golangci.yml b/.golangci.yml
index 0bc4e7309cadf..79929e35e17b0 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -58,6 +58,17 @@ issues:
- linters: [govet]
path-except: ^e/
text: "non-constant format string in call to github.com/gravitational/trace."
+ # 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
@@ -270,6 +281,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 4c685be1a55db..d34fa96bef6fe 100644
--- a/integration/ec2_test.go
+++ b/integration/ec2_test.go
@@ -52,6 +52,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"
)
func newSilentLogger() utils.Logger {
@@ -150,7 +151,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 f381912a56ad2..a7974f36eb2cd 100644
--- a/lib/auth/join/iam/iam.go
+++ b/lib/auth/join/iam/iam.go
@@ -32,6 +32,7 @@ import (
"github.com/gravitational/trace"
cloudaws "github.com/gravitational/teleport/lib/cloud/imds/aws"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
const (
@@ -101,7 +102,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 72622caedd35f..9f2df1b2bb371 100644
--- a/lib/auth/join_ec2.go
+++ b/lib/auth/join_ec2.go
@@ -33,7 +33,6 @@ import (
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/aws/aws-sdk-go-v2/service/ec2"
ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
- "github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/digitorus/pkcs7"
"github.com/gravitational/trace"
"github.com/jonboulle/clockwork"
@@ -41,6 +40,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 {
@@ -96,7 +96,7 @@ func checkInstanceRunning(ctx context.Context, instanceID, region, IAMRole strin
// assume the configured IAM role if necessary
if IAMRole != "" {
- stsClient := sts.NewFromConfig(awsClientConfig)
+ stsClient := stsutils.NewFromConfig(awsClientConfig)
creds := stscreds.NewAssumeRoleProvider(stsClient, IAMRole)
awsClientConfig.Credentials = aws.NewCredentialsCache(creds)
}
diff --git a/lib/auth/keystore/aws_kms.go b/lib/auth/keystore/aws_kms.go
index 536a940654a62..28915c62bf5ca 100644
--- a/lib/auth/keystore/aws_kms.go
+++ b/lib/auth/keystore/aws_kms.go
@@ -45,6 +45,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 (
@@ -81,7 +82,7 @@ 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)
+ stsClient = stsutils.NewFromConfig(awsCfg)
}
if kmsClient == nil {
kmsClient = kms.NewFromConfig(awsCfg)
diff --git a/lib/backend/dynamo/dynamodbbk.go b/lib/backend/dynamo/dynamodbbk.go
index 44f9774584b7e..fb5ef1ae52dc9 100644
--- a/lib/backend/dynamo/dynamodbbk.go
+++ b/lib/backend/dynamo/dynamodbbk.go
@@ -46,9 +46,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"
)
@@ -287,7 +287,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 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() {
+ useFIPS := dynamodbutils.IsFIPSEnabled()
+ if useFIPS {
dynamoOpts = append(dynamoOpts, func(o *dynamodb.Options) {
o.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled
})
diff --git a/lib/cloud/clients.go b/lib/cloud/clients.go
index bc2b77d2d0abb..f8351d6309fa7 100644
--- a/lib/cloud/clients.go
+++ b/lib/cloud/clients.go
@@ -64,7 +64,6 @@ import (
"github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface"
"github.com/aws/aws-sdk-go/service/ssm"
"github.com/aws/aws-sdk-go/service/ssm/ssmiface"
- "github.com/aws/aws-sdk-go/service/sts"
"github.com/aws/aws-sdk-go/service/sts/stsiface"
"github.com/gravitational/trace"
"github.com/sirupsen/logrus"
@@ -82,6 +81,7 @@ import (
gcpimds "github.com/gravitational/teleport/lib/cloud/imds/gcp"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/utils"
+ "github.com/gravitational/teleport/lib/utils/aws/stsutils"
)
// Clients provides interface for obtaining cloud provider clients.
@@ -607,7 +607,7 @@ func (c *cloudClients) GetAWSSTSClient(ctx context.Context, region string, opts
if err != nil {
return nil, trace.Wrap(err)
}
- return sts.New(session), nil
+ return stsutils.NewV1(session), nil
}
// GetAWSEC2Client returns AWS EC2 client for the specified region.
@@ -880,7 +880,7 @@ func (c *cloudClients) getAWSSessionForRole(ctx context.Context, region string,
}
createSession := func(ctx context.Context) (*awssession.Session, error) {
- stsClient := sts.New(options.baseSession)
+ stsClient := stsutils.NewV1(options.baseSession)
return newSessionWithRole(ctx, stsClient, region, options.assumeRoleARN, options.assumeRoleExternalID)
}
diff --git a/lib/configurators/aws/aws.go b/lib/configurators/aws/aws.go
index 839bf08de2df1..45063d9bc05bf 100644
--- a/lib/configurators/aws/aws.go
+++ b/lib/configurators/aws/aws.go
@@ -49,6 +49,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 (
@@ -388,7 +389,7 @@ func (c *ConfiguratorConfig) CheckAndSetDefaults() error {
}
if c.stsClient == nil {
- c.stsClient = sts.NewFromConfig(*c.awsCfg)
+ c.stsClient = stsutils.NewFromConfig(*c.awsCfg)
}
if c.iamClient == nil {
c.iamClient = iam.NewFromConfig(*c.awsCfg)
diff --git a/lib/events/dynamoevents/dynamoevents.go b/lib/events/dynamoevents/dynamoevents.go
index 4c10a0d826164..22ade06096d55 100644
--- a/lib/events/dynamoevents/dynamoevents.go
+++ b/lib/events/dynamoevents/dynamoevents.go
@@ -58,10 +58,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"
)
@@ -324,7 +324,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 8c16f4c66156a..a204f8566d625 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.
@@ -92,7 +92,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/eice_iam_config.go b/lib/integrations/awsoidc/eice_iam_config.go
index 7026fa97fef5e..8158b45042e11 100644
--- a/lib/integrations/awsoidc/eice_iam_config.go
+++ b/lib/integrations/awsoidc/eice_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 (
@@ -100,7 +100,7 @@ func NewEICEIAMConfigureClient(ctx context.Context, region string) (EICEIAMConfi
}
return &defaultEICEIAMConfigureClient{
- CallerIdentityGetter: sts.NewFromConfig(cfg),
+ CallerIdentityGetter: stsutils.NewFromConfig(cfg),
Client: iam.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/srv/app/aws/handler_test.go b/lib/srv/app/aws/handler_test.go
index 9189bb7e3e572..9baca1472d5c4 100644
--- a/lib/srv/app/aws/handler_test.go
+++ b/lib/srv/app/aws/handler_test.go
@@ -55,6 +55,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"
)
type makeRequest func(url string, provider client.ConfigProvider, awsHost string) error
@@ -138,7 +139,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/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 26f8d93896853..79e9275f17c91 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 {
@@ -188,7 +188,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)
@@ -219,7 +219,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))
}