mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-11 22:49:54 +00:00
* support `where` RBAC on application session recordings application session recordings are backed by AppSessionChunk events, but those events were never wired into the session recording RBAC path, so `where` clauses on `kind: session` rules could not match them. Fixes https://github.com/gravitational/teleport/issues/67775 Signed-off-by: Tiago Silva <[email protected]> * fix unit test * handle feedback --------- Signed-off-by: Tiago Silva <[email protected]>
146 lines
4.5 KiB
Go
146 lines
4.5 KiB
Go
/*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package services
|
|
|
|
import (
|
|
apidefaults "github.com/gravitational/teleport/api/defaults"
|
|
headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
|
|
linuxdesktopv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/linuxdesktop/v1"
|
|
"github.com/gravitational/teleport/api/types"
|
|
apievents "github.com/gravitational/teleport/api/types/events"
|
|
)
|
|
|
|
// ExtendWithSessionEnd extends the context with a session end event and
|
|
// rebuilds the resource from the event. An AccessChecker must be provided
|
|
// to allow access checks to other resources in the where clause.
|
|
func (ctx *Context) ExtendWithSessionEnd(sessionEnd apievents.AuditEvent, checker AccessChecker) {
|
|
ctx.Session = sessionEnd
|
|
ctx.Resource = rebuildResourceFromSessionEndEvent(sessionEnd)
|
|
if linuxEnd, ok := sessionEnd.(*apievents.LinuxDesktopSessionEnd); ok {
|
|
ctx.Resource153 = linuxdesktopv1.LinuxDesktop_builder{
|
|
Kind: types.KindLinuxDesktop,
|
|
SubKind: "",
|
|
Version: types.V1,
|
|
Metadata: headerv1.Metadata_builder{
|
|
Name: linuxEnd.DesktopName,
|
|
Labels: linuxEnd.DesktopLabels,
|
|
}.Build(),
|
|
Spec: linuxdesktopv1.LinuxDesktopSpec_builder{
|
|
Addr: linuxEnd.DesktopAddr,
|
|
}.Build(),
|
|
}.Build()
|
|
}
|
|
// AccessCheker is set here to allow access checks to other resources
|
|
// in the where clause.
|
|
ctx.AccessChecker = checker
|
|
}
|
|
|
|
// rebuildResourceFromSessionEndEvent rebuilds a resource from a session end event.
|
|
// This is used to reconstruct the resource that was active at the time of the session end event
|
|
// for audit log RBAC purposes.
|
|
func rebuildResourceFromSessionEndEvent(event apievents.AuditEvent) types.Resource {
|
|
switch sEnd := event.(type) {
|
|
case *apievents.SessionEnd:
|
|
if sEnd == nil {
|
|
return nil
|
|
}
|
|
switch sEnd.Protocol {
|
|
case apievents.EventProtocolSSH:
|
|
return &types.ServerV2{
|
|
Kind: types.KindNode,
|
|
Version: types.V2,
|
|
Metadata: types.Metadata{
|
|
Name: sEnd.ServerMetadata.ServerID,
|
|
Namespace: sEnd.ServerMetadata.ServerNamespace,
|
|
Labels: sEnd.ServerMetadata.ServerLabels,
|
|
},
|
|
Spec: types.ServerSpecV2{
|
|
Addr: sEnd.ServerMetadata.ServerAddr,
|
|
Hostname: sEnd.ServerMetadata.ServerHostname,
|
|
},
|
|
}
|
|
case apievents.EventProtocolKube:
|
|
return &types.KubernetesClusterV3{
|
|
Kind: types.KindKubernetesCluster,
|
|
Version: types.V3,
|
|
Metadata: types.Metadata{
|
|
Name: sEnd.KubernetesClusterMetadata.KubernetesCluster,
|
|
Namespace: apidefaults.Namespace,
|
|
Labels: sEnd.KubernetesClusterMetadata.KubernetesLabels,
|
|
},
|
|
Spec: types.KubernetesClusterSpecV3{},
|
|
}
|
|
}
|
|
case *apievents.WindowsDesktopSessionEnd:
|
|
if sEnd == nil {
|
|
return nil
|
|
}
|
|
return &types.WindowsDesktopV3{
|
|
ResourceHeader: types.ResourceHeader{
|
|
Kind: types.KindWindowsDesktop,
|
|
Version: types.V3,
|
|
Metadata: types.Metadata{
|
|
Name: sEnd.DesktopName,
|
|
Namespace: apidefaults.Namespace,
|
|
Labels: sEnd.DesktopLabels,
|
|
},
|
|
},
|
|
Spec: types.WindowsDesktopSpecV3{
|
|
Addr: sEnd.DesktopAddr,
|
|
Domain: sEnd.Domain,
|
|
},
|
|
}
|
|
case *apievents.AppSessionChunk:
|
|
if sEnd == nil {
|
|
return nil
|
|
}
|
|
return &types.AppV3{
|
|
Kind: types.KindApp,
|
|
Version: types.V3,
|
|
Metadata: types.Metadata{
|
|
Name: sEnd.AppName,
|
|
Namespace: apidefaults.Namespace,
|
|
Labels: sEnd.AppLabels,
|
|
},
|
|
Spec: types.AppSpecV3{
|
|
URI: sEnd.AppURI,
|
|
PublicAddr: sEnd.AppPublicAddr,
|
|
},
|
|
}
|
|
case *apievents.DatabaseSessionEnd:
|
|
if sEnd == nil {
|
|
return nil
|
|
}
|
|
return &types.DatabaseV3{
|
|
Kind: types.KindDatabase,
|
|
Version: types.V3,
|
|
Metadata: types.Metadata{
|
|
Name: sEnd.DatabaseService,
|
|
Namespace: apidefaults.Namespace,
|
|
Labels: sEnd.DatabaseLabels,
|
|
},
|
|
Spec: types.DatabaseSpecV3{
|
|
Protocol: sEnd.DatabaseProtocol,
|
|
URI: sEnd.DatabaseURI,
|
|
},
|
|
}
|
|
}
|
|
return nil
|
|
}
|