Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(v9) Allow setting additional traits in tctl users add command #12133

Merged
merged 1 commit into from
Apr 20, 2022
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
8 changes: 8 additions & 0 deletions constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,10 @@ const (
// allowed database users.
TraitDBUsers = "db_users"

// TraitAWSRoleARNs is the name of the role variable used to store
// allowed AWS role ARNs.
TraitAWSRoleARNs = "aws_role_arns"

// TraitTeams is the name of the role variable use to store team
// membership information
TraitTeams = "github_teams"
Expand Down Expand Up @@ -554,6 +558,10 @@ const (
// TraitInternalDBUsersVariable is the variable used to store allowed
// database users for local accounts.
TraitInternalDBUsersVariable = "{{internal.db_users}}"

// TraitInternalAWSRoleARNs is the variable used to store allowed AWS
// role ARNs for local accounts.
TraitInternalAWSRoleARNs = "{{internal.aws_role_arns}}"
)

// SCP is Secure Copy.
Expand Down
1 change: 1 addition & 0 deletions lib/services/presets.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func NewPresetAccessRole() types.Role {
role.SetWindowsLogins(types.Allow, []string{teleport.TraitInternalWindowsLoginsVariable})
role.SetKubeUsers(types.Allow, []string{teleport.TraitInternalKubeUsersVariable})
role.SetKubeGroups(types.Allow, []string{teleport.TraitInternalKubeGroupsVariable})
role.SetAWSRoleARNs(types.Allow, []string{teleport.TraitInternalAWSRoleARNs})
return role
}

Expand Down
15 changes: 3 additions & 12 deletions lib/services/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,17 +292,7 @@ func ApplyTraits(r types.Role, traits map[string][]string) types.Role {
r.SetWindowsLogins(condition, apiutils.Deduplicate(outWindowsLogins))

inRoleARNs := r.GetAWSRoleARNs(condition)
var outRoleARNs []string
for _, arn := range inRoleARNs {
variableValues, err := ApplyValueTraits(arn, traits)
if err != nil {
if !trace.IsNotFound(err) {
log.Debugf("Skipping AWS role ARN %v: %v.", arn, err)
}
continue
}
outRoleARNs = append(outRoleARNs, variableValues...)
}
outRoleARNs := applyValueTraitsSlice(inRoleARNs, traits, "AWS role ARN")
r.SetAWSRoleARNs(condition, apiutils.Deduplicate(outRoleARNs))

// apply templates to kubernetes groups
Expand Down Expand Up @@ -454,7 +444,8 @@ func ApplyValueTraits(val string, traits map[string][]string) ([]string, error)
switch variable.Name() {
case teleport.TraitLogins, teleport.TraitWindowsLogins,
teleport.TraitKubeGroups, teleport.TraitKubeUsers,
teleport.TraitDBNames, teleport.TraitDBUsers:
teleport.TraitDBNames, teleport.TraitDBUsers,
teleport.TraitAWSRoleARNs:
default:
return nil, trace.BadParameter("unsupported variable %q", variable.Name())
}
Expand Down
15 changes: 9 additions & 6 deletions lib/services/role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"testing"
"time"

"github.com/gravitational/teleport"
"github.com/gravitational/teleport/api/constants"
apidefaults "github.com/gravitational/teleport/api/defaults"
"github.com/gravitational/teleport/api/types"
Expand Down Expand Up @@ -1897,21 +1898,23 @@ func TestApplyTraits(t *testing.T) {
{
comment: "AWS role ARN substitute in allow rule",
inTraits: map[string][]string{
"foo": {"bar"},
"foo": {"bar"},
teleport.TraitAWSRoleARNs: {"baz"},
},
allow: rule{
inRoleARNs: []string{"{{external.foo}}"},
outRoleARNs: []string{"bar"},
inRoleARNs: []string{"{{external.foo}}", teleport.TraitInternalAWSRoleARNs},
outRoleARNs: []string{"bar", "baz"},
},
},
{
comment: "AWS role ARN substitute in deny rule",
inTraits: map[string][]string{
"foo": {"bar"},
"foo": {"bar"},
teleport.TraitAWSRoleARNs: {"baz"},
},
deny: rule{
inRoleARNs: []string{"{{external.foo}}"},
outRoleARNs: []string{"bar"},
inRoleARNs: []string{"{{external.foo}}", teleport.TraitInternalAWSRoleARNs},
outRoleARNs: []string{"bar", "baz"},
},
},
{
Expand Down
20 changes: 16 additions & 4 deletions tool/tctl/common/user_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ type UserCommand struct {
login string
allowedLogins []string
allowedWindowsLogins []string
allowedKubeUsers []string
allowedKubeGroups []string
allowedDatabaseUsers []string
allowedDatabaseNames []string
allowedAWSRoleARNs []string
createRoles []string
kubeUsers string
kubeGroups string

ttl time.Duration

Expand Down Expand Up @@ -72,6 +75,12 @@ func (u *UserCommand) Initialize(app *kingpin.Application, config *service.Confi

u.userAdd.Flag("logins", "List of allowed SSH logins for the new user").StringsVar(&u.allowedLogins)
u.userAdd.Flag("windows-logins", "List of allowed Windows logins for the new user").StringsVar(&u.allowedWindowsLogins)
u.userAdd.Flag("kubernetes-users", "List of allowed Kubernetes users for the new user").StringsVar(&u.allowedKubeUsers)
u.userAdd.Flag("kubernetes-groups", "List of allowed Kubernetes groups for the new user").StringsVar(&u.allowedKubeGroups)
u.userAdd.Flag("db-users", "List of allowed database users for the new user").StringsVar(&u.allowedDatabaseUsers)
u.userAdd.Flag("db-names", "List of allowed database names for the new user").StringsVar(&u.allowedDatabaseNames)
u.userAdd.Flag("aws-role-arns", "List of allowed AWS role ARNs for the new user").StringsVar(&u.allowedAWSRoleARNs)

u.userAdd.Flag("roles", "List of roles for the new user to assume").Required().StringsVar(&u.createRoles)

u.userAdd.Flag("ttl", fmt.Sprintf("Set expiration time for token, default is %v, maximum is %v",
Expand Down Expand Up @@ -200,8 +209,11 @@ func (u *UserCommand) Add(client auth.ClientI) error {
traits := map[string][]string{
teleport.TraitLogins: u.allowedLogins,
teleport.TraitWindowsLogins: u.allowedWindowsLogins,
teleport.TraitKubeUsers: flattenSlice([]string{u.kubeUsers}),
teleport.TraitKubeGroups: flattenSlice([]string{u.kubeGroups}),
teleport.TraitKubeUsers: flattenSlice(u.allowedKubeUsers),
teleport.TraitKubeGroups: flattenSlice(u.allowedKubeGroups),
teleport.TraitDBUsers: flattenSlice(u.allowedDatabaseUsers),
teleport.TraitDBNames: flattenSlice(u.allowedDatabaseNames),
teleport.TraitAWSRoleARNs: flattenSlice(u.allowedAWSRoleARNs),
}

user, err := types.NewUser(u.login)
Expand Down