Skip to content

Commit e31d2c3

Browse files
Prevent creation of invalid App for AWS OIDC Integration
When enabling AWS Access using an integration, the final address will be a concatenation of the integration name and the proxy's public address. The proxy must present a certificate valid for that address. However, when the integration name has a dot, it will usually not work with the proxy's certificate. We know it won't work for Teleport Cloud, where the certificates only allow for `<app>.<tenant>.teleport.sh`. So, for Teleport Cloud enabling AWS Access is not possible. For self-hosted, a warning is emitted.
1 parent 70a8daa commit e31d2c3

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

lib/web/integrations_awsoidc.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,18 @@ func (h *Handler) awsOIDCCreateAWSAppAccess(w http.ResponseWriter, r *http.Reque
10411041
return nil, trace.Wrap(err)
10421042
}
10431043

1044+
// If the integration name contains a dot, then the proxy must provide a certificate allowing *.<something>.<proxyPublicAddr>
1045+
if strings.Contains(integrationName, ".") {
1046+
// Teleport Cloud only provides certificates for *.<tenant>.teleport.sh, so this would generate an invalid address.
1047+
if h.GetClusterFeatures().Cloud {
1048+
return nil, trace.BadParameter(`Invalid integration name for enabling AWS Access. Please re-create the integration without the "."`)
1049+
}
1050+
1051+
// Typically, self-hosted clusters will also have a single wildcard for the name.
1052+
// Logging a warning message should help debug the problem in case the certificate is not valid.
1053+
h.logger.WarnContext(ctx, `Enabling AWS Access using an integration with a "." might not work unless your Proxy's certificate is valid for the address`, "public_addr", appServer.GetApp().GetPublicAddr())
1054+
}
1055+
10441056
if _, err := clt.UpsertApplicationServer(ctx, appServer); err != nil {
10451057
return nil, trace.Wrap(err)
10461058
}

lib/web/integrations_awsoidc_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,37 @@ func TestAWSOIDCAppAccessAppServerCreationDeletion(t *testing.T) {
10311031
_, err = pack.clt.PostJSON(ctx, endpoint, nil)
10321032
require.NoError(t, err)
10331033
})
1034+
1035+
t.Run("using a period in the name fails when running in cloud", func(t *testing.T) {
1036+
enableCloudFeatureProxy(t, proxy)
1037+
1038+
// Creating an Integration using the account id as name should not return an error if the proxy is listening at the default HTTPS port
1039+
myIntegrationWithAccountID, err := types.NewIntegrationAWSOIDC(types.Metadata{
1040+
Name: "env.prod",
1041+
}, &types.AWSOIDCIntegrationSpecV1{
1042+
RoleARN: "arn:aws:iam::123456789012:role/teleport",
1043+
})
1044+
require.NoError(t, err)
1045+
1046+
_, err = env.server.Auth().CreateIntegration(ctx, myIntegrationWithAccountID)
1047+
require.NoError(t, err)
1048+
endpoint = pack.clt.Endpoint("webapi", "sites", "localhost", "integrations", "aws-oidc", "env.prod", "aws-app-access")
1049+
_, err = pack.clt.PostJSON(ctx, endpoint, nil)
1050+
require.Error(t, err)
1051+
require.ErrorContains(t, err, "Invalid integration name for enabling AWS Access")
1052+
})
1053+
}
1054+
1055+
func enableCloudFeatureProxy(t *testing.T, proxy *testProxy) {
1056+
t.Helper()
1057+
1058+
existingFeatures := proxy.handler.handler.clusterFeatures
1059+
existingFeatures.Cloud = true
1060+
proxy.handler.handler.clusterFeatures = existingFeatures
1061+
t.Cleanup(func() {
1062+
existingFeatures.Cloud = false
1063+
proxy.handler.handler.clusterFeatures = existingFeatures
1064+
})
10341065
}
10351066

10361067
func TestAWSOIDCAppAccessAppServerCreationWithUserProvidedLabels(t *testing.T) {

0 commit comments

Comments
 (0)