diff --git a/lib/auth/auth.go b/lib/auth/auth.go index 859dfb308f34f..7b1243095f8b2 100644 --- a/lib/auth/auth.go +++ b/lib/auth/auth.go @@ -1060,6 +1060,8 @@ type certRequest struct { awsRoleARN string // azureIdentity is the Azure identity to generate certificate for. azureIdentity string + // gcpServiceAccount is the GCP service account to generate certificate for. + gcpServiceAccount string // dbService identifies the name of the database service requests will // be routed to. dbService string @@ -1196,6 +1198,8 @@ type AppTestCertRequest struct { AWSRoleARN string // AzureIdentity is the optional Azure identity a user wants to assume to encode. AzureIdentity string + // GCPServiceAccount is optional GCP service account a user wants to assume to encode. + GCPServiceAccount string } // GenerateUserAppTestCert generates an application specific certificate, used @@ -1232,11 +1236,12 @@ func (a *Server) GenerateUserAppTestCert(req AppTestCertRequest) ([]byte, error) // Only allow this certificate to be used for applications. usage: []string{teleport.UsageAppsOnly}, // Add in the application routing information. - appSessionID: sessionID, - appPublicAddr: req.PublicAddr, - appClusterName: req.ClusterName, - awsRoleARN: req.AWSRoleARN, - azureIdentity: req.AzureIdentity, + appSessionID: sessionID, + appPublicAddr: req.PublicAddr, + appClusterName: req.ClusterName, + awsRoleARN: req.AWSRoleARN, + azureIdentity: req.AzureIdentity, + gcpServiceAccount: req.GCPServiceAccount, }) if err != nil { return nil, trace.Wrap(err) @@ -1719,6 +1724,12 @@ func (a *Server) generateUserCert(req certRequest) (*proto.Certs, error) { return nil, trace.Wrap(err) } + // Enumerate allowed GCP service accounts. + gcpAccounts, err := req.checker.CheckGCPServiceAccounts(sessionTTL, req.overrideRoleTTL) + if err != nil && !trace.IsNotFound(err) { + return nil, trace.Wrap(err) + } + // generate TLS certificate identity := tlsca.Identity{ Username: req.user.GetName(), @@ -1732,12 +1743,13 @@ func (a *Server) generateUserCert(req certRequest) (*proto.Certs, error) { KubernetesGroups: kubeGroups, KubernetesUsers: kubeUsers, RouteToApp: tlsca.RouteToApp{ - SessionID: req.appSessionID, - PublicAddr: req.appPublicAddr, - ClusterName: req.appClusterName, - Name: req.appName, - AWSRoleARN: req.awsRoleARN, - AzureIdentity: req.azureIdentity, + SessionID: req.appSessionID, + PublicAddr: req.appPublicAddr, + ClusterName: req.appClusterName, + Name: req.appName, + AWSRoleARN: req.awsRoleARN, + AzureIdentity: req.azureIdentity, + GCPServiceAccount: req.gcpServiceAccount, }, TeleportCluster: clusterName, RouteToDatabase: tlsca.RouteToDatabase{ @@ -1753,6 +1765,7 @@ func (a *Server) generateUserCert(req certRequest) (*proto.Certs, error) { ClientIP: req.clientIP, AWSRoleARNs: roleARNs, AzureIdentities: azureIdentities, + GCPServiceAccounts: gcpAccounts, ActiveRequests: req.activeRequests.AccessRequests, DisallowReissue: req.disallowReissue, Renewable: req.renewable, diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index b21dafb125e7a..bcd680229e2af 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -2614,6 +2614,7 @@ func (a *ServerWithRoles) generateUserCerts(ctx context.Context, req proto.UserC appClusterName: req.RouteToApp.ClusterName, awsRoleARN: req.RouteToApp.AWSRoleARN, azureIdentity: req.RouteToApp.AzureIdentity, + gcpServiceAccount: req.RouteToApp.GCPServiceAccount, checker: checker, // Copy IP from current identity to the generated certificate, if present, // to avoid generateUserCerts() being used to drop IP pinning in the new certificates. diff --git a/lib/auth/grpcserver.go b/lib/auth/grpcserver.go index 735c74733da7b..7d6ae97a12bca 100644 --- a/lib/auth/grpcserver.go +++ b/lib/auth/grpcserver.go @@ -1481,11 +1481,12 @@ func (g *GRPCServer) CreateAppSession(ctx context.Context, req *proto.CreateAppS } session, err := auth.CreateAppSession(ctx, types.CreateAppSessionRequest{ - Username: req.GetUsername(), - PublicAddr: req.GetPublicAddr(), - ClusterName: req.GetClusterName(), - AWSRoleARN: req.GetAWSRoleARN(), - AzureIdentity: req.GetAzureIdentity(), + Username: req.GetUsername(), + PublicAddr: req.GetPublicAddr(), + ClusterName: req.GetClusterName(), + AWSRoleARN: req.GetAWSRoleARN(), + AzureIdentity: req.GetAzureIdentity(), + GCPServiceAccount: req.GetGCPServiceAccount(), }) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/auth/sessions.go b/lib/auth/sessions.go index 94e36f76061ba..cdacac0a8b20d 100644 --- a/lib/auth/sessions.go +++ b/lib/auth/sessions.go @@ -77,14 +77,15 @@ func (s *Server) CreateAppSession(ctx context.Context, req types.CreateAppSessio // Only allow this certificate to be used for applications. usage: []string{teleport.UsageAppsOnly}, // Add in the application routing information. - appSessionID: uuid.New().String(), - appPublicAddr: req.PublicAddr, - appClusterName: req.ClusterName, - awsRoleARN: req.AWSRoleARN, + appSessionID: uuid.New().String(), + appPublicAddr: req.PublicAddr, + appClusterName: req.ClusterName, + awsRoleARN: req.AWSRoleARN, + azureIdentity: req.AzureIdentity, + gcpServiceAccount: req.GCPServiceAccount, // Since we are generating the keys and certs directly on the Auth Server, // we need to skip attestation. skipAttestation: true, - azureIdentity: req.AzureIdentity, // Pass along device extensions from the user. deviceExtensions: DeviceExtensions(identity.DeviceExtensions), })