Skip to content

Commit

Permalink
Persist Join Attributes in X509 Cert
Browse files Browse the repository at this point in the history
  • Loading branch information
strideynet committed Jan 2, 2025
1 parent aecaf13 commit 58b98e4
Show file tree
Hide file tree
Showing 20 changed files with 443 additions and 216 deletions.
3 changes: 3 additions & 0 deletions api/gen/proto/go/teleport/machineid/v1/bot_instance.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions api/proto/teleport/machineid/v1/bot_instance.proto
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,16 @@ message BotInstanceStatusAuthentication {
// Server.
google.protobuf.Timestamp authenticated_at = 1;
// The join method used for this join or renewal.
// Deprecated: prefer using join_attrs.meta.join_method
string join_method = 2;
// The join token used for this join or renewal. This is only populated for
// delegated join methods as the value for `token` join methods is sensitive.
// Deprecated: prefer using join_attrs.meta.join_token_name
string join_token = 3;
// The metadata sourced from the join method.
// Deprecated: prefer using join_attrs.
google.protobuf.Struct metadata = 4;

// On each renewal, this generation is incremented. For delegated join
// methods, this counter is not checked during renewal. For the `token` join
// method, this counter is checked during renewal and the Bot is locked out if
Expand Down
7 changes: 6 additions & 1 deletion lib/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import (
headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
mfav1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/mfa/v1"
notificationsv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/notifications/v1"
workloadidentityv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/workloadidentity/v1"
"github.com/gravitational/teleport/api/internalutils/stream"
"github.com/gravitational/teleport/api/metadata"
"github.com/gravitational/teleport/api/types"
Expand Down Expand Up @@ -2286,6 +2287,9 @@ type certRequest struct {
// botInstanceID is the unique identifier of the bot instance associated
// with this cert, if any
botInstanceID string
// joinAttributes holds attributes derived from attested metadata from the
// join process, should any exist.
joinAttributes *workloadidentityv1pb.JoinAttrs
}

// check verifies the cert request is valid.
Expand Down Expand Up @@ -3366,7 +3370,8 @@ func generateCert(ctx context.Context, a *Server, req certRequest, caType types.
AssetTag: req.deviceExtensions.AssetTag,
CredentialID: req.deviceExtensions.CredentialID,
},
UserType: req.user.GetUserType(),
UserType: req.user.GetUserType(),
JoinAttributes: req.joinAttributes,
}

var signedTLSCert []byte
Expand Down
3 changes: 3 additions & 0 deletions lib/auth/auth_with_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -3397,6 +3397,9 @@ func (a *ServerWithRoles) generateUserCerts(ctx context.Context, req proto.UserC
// `updateBotInstance()` is called below, and this (empty) value will be
// overridden.
botInstanceID: a.context.Identity.GetIdentity().BotInstanceID,
// Propagate any join attributes from the current identity to the new
// identity.
joinAttributes: a.context.Identity.GetIdentity().JoinAttributes,
}

if user.GetName() != a.context.User.GetName() {
Expand Down
25 changes: 14 additions & 11 deletions lib/auth/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/gravitational/teleport/api/client/proto"
headerv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/header/v1"
machineidv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/machineid/v1"
workloadidentityv1pb "github.com/gravitational/teleport/api/gen/proto/go/teleport/workloadidentity/v1"
"github.com/gravitational/teleport/api/types"
apievents "github.com/gravitational/teleport/api/types/events"
apiutils "github.com/gravitational/teleport/api/utils"
Expand Down Expand Up @@ -315,7 +316,7 @@ func (a *Server) updateBotInstance(
if templateAuthRecord != nil {
authRecord.JoinToken = templateAuthRecord.JoinToken
authRecord.JoinMethod = templateAuthRecord.JoinMethod
authRecord.Metadata = templateAuthRecord.Metadata
authRecord.JoinAttrs = templateAuthRecord.JoinAttrs
}

// An empty bot instance most likely means a bot is rejoining after an
Expand Down Expand Up @@ -493,6 +494,7 @@ func (a *Server) generateInitialBotCerts(
expires time.Time, renewable bool,
initialAuth *machineidv1pb.BotInstanceStatusAuthentication,
existingInstanceID string, currentIdentityGeneration int32,
joinAttrs *workloadidentityv1pb.JoinAttrs,
) (*proto.Certs, string, error) {
var err error

Expand Down Expand Up @@ -535,16 +537,17 @@ func (a *Server) generateInitialBotCerts(

// Generate certificate
certReq := certRequest{
user: userState,
ttl: expires.Sub(a.GetClock().Now()),
sshPublicKey: sshPubKey,
tlsPublicKey: tlsPubKey,
checker: checker,
traits: accessInfo.Traits,
renewable: renewable,
includeHostCA: true,
loginIP: loginIP,
botName: botName,
user: userState,
ttl: expires.Sub(a.GetClock().Now()),
sshPublicKey: sshPubKey,
tlsPublicKey: tlsPubKey,
checker: checker,
traits: accessInfo.Traits,
renewable: renewable,
includeHostCA: true,
loginIP: loginIP,
botName: botName,
joinAttributes: joinAttrs,
}

if existingInstanceID == "" {
Expand Down
Loading

0 comments on commit 58b98e4

Please sign in to comment.