Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/types/wrappers/wrappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ func (l Traits) Clone() Traits {
}
clone := make(Traits, len(l))
for key, vals := range l {
if len(vals) == 0 || len(vals) == 1 && vals[0] == "" {
continue
}
clone[key] = slices.Clone(vals)
}
return clone
Expand Down
9 changes: 9 additions & 0 deletions lib/bpf/bpf.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"embed"
"encoding/binary"
"net"
"slices"
"strconv"
"sync"
"time"
Expand Down Expand Up @@ -413,6 +414,8 @@ func (s *Service) emitCommandEvent(eventBytes []byte) {
User: ctx.User,
Login: ctx.Login,
UserClusterName: ctx.UserOriginClusterName,
UserRoles: slices.Clone(ctx.UserRoles),
UserTraits: ctx.UserTraits.Clone(),
},
BPFMetadata: apievents.BPFMetadata{
CgroupID: event.CgroupID,
Expand Down Expand Up @@ -473,6 +476,8 @@ func (s *Service) emitDiskEvent(eventBytes []byte) {
User: ctx.User,
Login: ctx.Login,
UserClusterName: ctx.UserOriginClusterName,
UserRoles: slices.Clone(ctx.UserRoles),
UserTraits: ctx.UserTraits.Clone(),
},
BPFMetadata: apievents.BPFMetadata{
CgroupID: event.CgroupID,
Expand Down Expand Up @@ -529,6 +534,8 @@ func (s *Service) emit4NetworkEvent(eventBytes []byte) {
User: ctx.User,
Login: ctx.Login,
UserClusterName: ctx.UserOriginClusterName,
UserRoles: slices.Clone(ctx.UserRoles),
UserTraits: ctx.UserTraits.Clone(),
},
BPFMetadata: apievents.BPFMetadata{
CgroupID: event.CgroupID,
Expand Down Expand Up @@ -587,6 +594,8 @@ func (s *Service) emit6NetworkEvent(eventBytes []byte) {
User: ctx.User,
Login: ctx.Login,
UserClusterName: ctx.UserOriginClusterName,
UserRoles: slices.Clone(ctx.UserRoles),
UserTraits: ctx.UserTraits.Clone(),
},
BPFMetadata: apievents.BPFMetadata{
CgroupID: event.CgroupID,
Expand Down
6 changes: 6 additions & 0 deletions lib/bpf/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/gravitational/trace"

apievents "github.com/gravitational/teleport/api/types/events"
"github.com/gravitational/teleport/api/types/wrappers"
"github.com/gravitational/teleport/lib/utils"
)

Expand Down Expand Up @@ -84,6 +85,11 @@ type SessionContext struct {
// Events is the set of events (command, disk, or network) to record for
// this session.
Events map[string]bool

// UserRoles are the roles assigned to the user.
UserRoles []string
// UserTraits are the traits assigned to the user.
UserTraits wrappers.Traits
}

// NOP is used on either non-Linux systems or when BPF support is not enabled.
Expand Down
2 changes: 2 additions & 0 deletions lib/srv/authhandlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ func (h *AuthHandlers) CreateIdentityContext(sconn *ssh.ServerConn) (IdentityCon
JoinToken: unmappedIdentity.JoinToken,
PreviousIdentityExpires: unmappedIdentity.PreviousIdentityExpires,
OriginClusterName: certAuthority.GetClusterName(),
MappedRoles: accessInfo.Roles,
Traits: accessInfo.Traits,
}, nil
}

Expand Down
11 changes: 11 additions & 0 deletions lib/srv/ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"log/slog"
"net"
"os"
"slices"
"strconv"
"strings"
"sync"
Expand All @@ -42,6 +43,7 @@ import (
tracessh "github.com/gravitational/teleport/api/observability/tracing/ssh"
"github.com/gravitational/teleport/api/types"
apievents "github.com/gravitational/teleport/api/types/events"
"github.com/gravitational/teleport/api/types/wrappers"
"github.com/gravitational/teleport/lib/auth/authclient"
"github.com/gravitational/teleport/lib/auth/moderation"
"github.com/gravitational/teleport/lib/bpf"
Expand Down Expand Up @@ -241,6 +243,13 @@ type IdentityContext struct {
// trusted-cluster-related role mapping being applied.
UnmappedRoles []string

// MappedRoles lists the final roles of this Teleport user after
// trusted-cluster-related role mapping has been applied.
MappedRoles []string

// Traits are the identity traits derived from the certificate.
Traits wrappers.Traits

// CertValidBefore is set to the expiry time of a certificate, or
// empty, if cert does not expire
CertValidBefore time.Time
Expand Down Expand Up @@ -1112,6 +1121,8 @@ func (id *IdentityContext) GetUserMetadata() apievents.UserMetadata {
BotName: id.BotName,
BotInstanceID: id.BotInstanceID,
UserClusterName: id.OriginClusterName,
UserRoles: slices.Clone(id.MappedRoles),
UserTraits: id.Traits.Clone(),
}
}

Expand Down
11 changes: 11 additions & 0 deletions lib/srv/ctx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1"
"github.com/gravitational/teleport/api/types"
apievents "github.com/gravitational/teleport/api/types/events"
"github.com/gravitational/teleport/api/types/wrappers"
"github.com/gravitational/teleport/lib/services"
rsession "github.com/gravitational/teleport/lib/session"
"github.com/gravitational/teleport/lib/sshca"
Expand Down Expand Up @@ -148,13 +149,23 @@ func TestIdentityContext_GetUserMetadata(t *testing.T) {
Impersonator: "llama",
Login: "alpaca1",
ActiveRequests: []string{"access-req1", "access-req2"},
MappedRoles: []string{"role1", "role2"},
Traits: wrappers.Traits{
"trait1": []string{"value1", "value2"},
"trait2": []string{"value3"},
},
},
want: apievents.UserMetadata{
User: "alpaca",
Login: "alpaca1",
Impersonator: "llama",
AccessRequests: []string{"access-req1", "access-req2"},
UserKind: apievents.UserKind_USER_KIND_HUMAN,
UserRoles: []string{"role1", "role2"},
UserTraits: wrappers.Traits{
"trait1": []string{"value1", "value2"},
"trait2": []string{"value3"},
},
},
},
{
Expand Down
2 changes: 2 additions & 0 deletions lib/srv/sess.go
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,8 @@ func (s *session) startInteractive(ctx context.Context, scx *ServerContext, p *p
Login: scx.Identity.Login,
User: scx.Identity.TeleportUser,
UserOriginClusterName: scx.Identity.OriginClusterName,
UserRoles: scx.Identity.MappedRoles,
UserTraits: scx.Identity.Traits,
Events: eventsMap,
}

Expand Down
2 changes: 2 additions & 0 deletions lib/srv/session_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ func WebSessionController(controller *SessionController) func(ctx context.Contex
Impersonator: unmappedIdentity.Impersonator,
// Web sessions are always local to the cluster they authenticated to.
OriginClusterName: clusterName.GetClusterName(),
MappedRoles: accessChecker.RoleNames(),
Traits: accessChecker.Traits(),
}
ctx, err = controller.AcquireSessionContext(ctx, identity, localAddr, remoteAddr)
return ctx, trace.Wrap(err)
Expand Down
Loading