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
8 changes: 8 additions & 0 deletions constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,14 @@ const (
// credentials using any workload_identity resource. This exists to simplify
// Day 0 UX experience with workload identity.
PresetWildcardWorkloadIdentityIssuerRoleName = "wildcard-workload-identity-issuer"

// PresetAccessPluginRoleName is a name of a preset role that includes
// permissions required by self-hosted access request plugin.
PresetAccessPluginRoleName = "access-plugin"

// PresetListAccessRequestResourcesRoleName is a name of a preset role that
// includes permissions to read access request resources.
PresetListAccessRequestResourcesRoleName = "list-access-request-resources"
)

var PresetRoles = []string{PresetEditorRoleName, PresetAccessRoleName, PresetAuditorRoleName}
Expand Down
4 changes: 3 additions & 1 deletion docs/pages/includes/preset-roles-table.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
| `access`| Allows access to cluster resources. | |
| `editor` | Allows editing of cluster configuration settings. | |
| `auditor`| Allows reading cluster events, audit logs, and playing back session records. | |
| `access-plugin` | Enables self-hosted access request plugin features. | |
| `list-access-request-resources` | Allows reading access request resources. | |
| `requester`| Allows a user to create Access Requests. | ✔ |
| `reviewer`| Allows review of Access Requests. | ✔ |
| `group-access`| Allows access to all user groups. | ✔ |
| `device-admin`| Used to manage trusted devices. | ✔ |
| `device-enroll`| Used to grant device enrollment powers to users. | ✔ |
| `require-trusted-device`| Requires trusted device access to resources. | ✔ |
| `terraform-provider`| Allows the Teleport Terraform provider to configure all of its supported Teleport resources. | |
| `terraform-provider`| Allows the Teleport Terraform provider to configure all of its supported Teleport resources. | |

2 changes: 2 additions & 0 deletions lib/auth/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,8 @@ func GetPresetRoles() []types.Role {
services.NewPresetTerraformProviderRole(),
services.NewSystemIdentityCenterAccessRole(),
services.NewPresetWildcardWorkloadIdentityIssuerRole(),
services.NewPresetAccessPluginRole(),
services.NewPresetListAccessRequestResourcesRole(),
}

// Certain `New$FooRole()` functions will return a nil role if the
Expand Down
2 changes: 2 additions & 0 deletions lib/auth/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,8 @@ func TestPresets(t *testing.T) {
teleport.PresetAuditorRoleName,
teleport.PresetTerraformProviderRoleName,
teleport.PresetWildcardWorkloadIdentityIssuerRoleName,
teleport.PresetAccessPluginRoleName,
teleport.PresetListAccessRequestResourcesRoleName,
}

t.Run("EmptyCluster", func(t *testing.T) {
Expand Down
90 changes: 86 additions & 4 deletions lib/services/presets.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,76 @@ func NewPresetWildcardWorkloadIdentityIssuerRole() types.Role {
return role
}

// NewPresetAccessPluginRole returns a new pre-defined role for self-hosted
// access request plugins.
func NewPresetAccessPluginRole() types.Role {
role := &types.RoleV6{
Kind: types.KindRole,
Version: types.V7,
Metadata: types.Metadata{
Name: teleport.PresetAccessPluginRoleName,
Namespace: apidefaults.Namespace,
Description: "Default access plugin role",
Labels: map[string]string{
types.TeleportInternalResourceType: types.PresetResource,
},
},
Spec: types.RoleSpecV6{
Allow: types.RoleConditions{
Rules: []types.Rule{
types.NewRule(types.KindAccessRequest, RO()),
types.NewRule(types.KindAccessPluginData, RW()),
types.NewRule(types.KindAccessMonitoringRule, RO()),
types.NewRule(types.KindAccessList, RO()),
types.NewRule(types.KindRole, RO()),
types.NewRule(types.KindUser, RO()),
},
ReviewRequests: &types.AccessReviewConditions{
PreviewAsRoles: []string{
teleport.PresetListAccessRequestResourcesRoleName,
},
},
},
},
}
return role
}

// NewPresetListAccessRequestResourcesRole returns a new pre-defined role that
// allows reading access request resources.
func NewPresetListAccessRequestResourcesRole() types.Role {
role := &types.RoleV6{
Kind: types.KindRole,
Version: types.V7,
Metadata: types.Metadata{
Name: teleport.PresetListAccessRequestResourcesRoleName,
Namespace: apidefaults.Namespace,
Description: "Default list access request resources role",
Labels: map[string]string{
types.TeleportInternalResourceType: types.PresetResource,
},
},
Spec: types.RoleSpecV6{
Allow: types.RoleConditions{
Rules: []types.Rule{
types.NewRule(types.KindNode, RO()),
types.NewRule(types.KindApp, RO()),
types.NewRule(types.KindDatabase, RO()),
types.NewRule(types.KindKubernetesCluster, RO()),
},
// To enable all access plugin features, the role requires read
// access to all of the following resources.
AppLabels: types.Labels{types.Wildcard: []string{types.Wildcard}},
DatabaseLabels: types.Labels{types.Wildcard: []string{types.Wildcard}},
GroupLabels: types.Labels{types.Wildcard: []string{types.Wildcard}},
KubernetesLabels: types.Labels{types.Wildcard: []string{types.Wildcard}},
NodeLabels: types.Labels{types.Wildcard: []string{types.Wildcard}},
},
},
}
return role
}

// SystemOktaAccessRoleName is the name of the system role that allows
// access to Okta resources. This will be used by the Okta requester role to
// search for Okta resources.
Expand Down Expand Up @@ -770,10 +840,12 @@ func bootstrapRoleMetadataLabels() map[string]map[string]string {
}

var defaultAllowRulesMap = map[string][]types.Rule{
teleport.PresetAuditorRoleName: NewPresetAuditorRole().GetRules(types.Allow),
teleport.PresetEditorRoleName: NewPresetEditorRole().GetRules(types.Allow),
teleport.PresetAccessRoleName: NewPresetAccessRole().GetRules(types.Allow),
teleport.PresetTerraformProviderRoleName: NewPresetTerraformProviderRole().GetRules(types.Allow),
teleport.PresetAuditorRoleName: NewPresetAuditorRole().GetRules(types.Allow),
teleport.PresetEditorRoleName: NewPresetEditorRole().GetRules(types.Allow),
teleport.PresetAccessRoleName: NewPresetAccessRole().GetRules(types.Allow),
teleport.PresetTerraformProviderRoleName: NewPresetTerraformProviderRole().GetRules(types.Allow),
teleport.PresetAccessPluginRoleName: NewPresetAccessPluginRole().GetRules(types.Allow),
teleport.PresetListAccessRequestResourcesRoleName: NewPresetListAccessRequestResourcesRole().GetRules(types.Allow),
}

// defaultAllowRules has the Allow rules that should be set as default when
Expand Down Expand Up @@ -804,6 +876,13 @@ func defaultAllowLabels(enterprise bool) map[string]types.RoleConditions {
NodeLabels: wildcardLabels,
WindowsDesktopLabels: wildcardLabels,
},
teleport.PresetListAccessRequestResourcesRoleName: {
AppLabels: wildcardLabels,
DatabaseLabels: wildcardLabels,
GroupLabels: wildcardLabels,
KubernetesLabels: wildcardLabels,
NodeLabels: wildcardLabels,
},
}

if enterprise {
Expand Down Expand Up @@ -954,6 +1033,7 @@ func AddRoleDefaults(role types.Role) (types.Role, error) {
types.KindNode,
types.KindUserGroup,
types.KindWindowsDesktop,
types.KindKubernetesCluster,
} {
var labels types.Labels
switch kind {
Expand All @@ -969,6 +1049,8 @@ func AddRoleDefaults(role types.Role) (types.Role, error) {
labels = defaultLabels.GroupLabels
case types.KindWindowsDesktop:
labels = defaultLabels.WindowsDesktopLabels
case types.KindKubernetesCluster:
labels = defaultLabels.KubernetesLabels
}
labelsUpdated, err := updateAllowLabels(role, kind, labels)
if err != nil {
Expand Down
84 changes: 84 additions & 0 deletions lib/services/presets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,90 @@ func TestAddRoleDefaults(t *testing.T) {
},
},
},
{
name: "access-plugin (default roles match preset rules)",
role: &types.RoleV6{
Kind: types.KindRole,
Version: types.V7,
Metadata: types.Metadata{
Name: teleport.PresetAccessPluginRoleName,
Namespace: apidefaults.Namespace,
Description: "Default access plugin role",
Labels: map[string]string{
types.TeleportInternalResourceType: types.PresetResource,
},
},
},
expectedErr: require.NoError,
expected: &types.RoleV6{
Kind: types.KindRole,
Version: types.V7,
Metadata: types.Metadata{
Name: teleport.PresetAccessPluginRoleName,
Namespace: apidefaults.Namespace,
Description: "Default access plugin role",
Labels: map[string]string{
types.TeleportInternalResourceType: types.PresetResource,
},
},
Spec: types.RoleSpecV6{
Allow: types.RoleConditions{
Rules: []types.Rule{
// The missing resources got added as individual rules
types.NewRule(types.KindAccessRequest, RO()),
types.NewRule(types.KindAccessPluginData, RW()),
types.NewRule(types.KindAccessMonitoringRule, RO()),
types.NewRule(types.KindAccessList, RO()),
types.NewRule(types.KindRole, RO()),
types.NewRule(types.KindUser, RO()),
},
},
},
},
},
{
name: "list-access-request-resources (default roles match preset rules)",
role: &types.RoleV6{
Kind: types.KindRole,
Version: types.V7,
Metadata: types.Metadata{
Name: teleport.PresetListAccessRequestResourcesRoleName,
Namespace: apidefaults.Namespace,
Description: "Default list access request resources role",
Labels: map[string]string{
types.TeleportInternalResourceType: types.PresetResource,
},
},
},
expectedErr: require.NoError,
expected: &types.RoleV6{
Kind: types.KindRole,
Version: types.V7,
Metadata: types.Metadata{
Name: teleport.PresetListAccessRequestResourcesRoleName,
Namespace: apidefaults.Namespace,
Description: "Default list access request resources role",
Labels: map[string]string{
types.TeleportInternalResourceType: types.PresetResource,
},
},
Spec: types.RoleSpecV6{
Allow: types.RoleConditions{
Rules: []types.Rule{
types.NewRule(types.KindNode, RO()),
types.NewRule(types.KindApp, RO()),
types.NewRule(types.KindDatabase, RO()),
types.NewRule(types.KindKubernetesCluster, RO()),
},
AppLabels: types.Labels{types.Wildcard: []string{types.Wildcard}},
DatabaseLabels: types.Labels{types.Wildcard: []string{types.Wildcard}},
GroupLabels: types.Labels{types.Wildcard: []string{types.Wildcard}},
KubernetesLabels: types.Labels{types.Wildcard: []string{types.Wildcard}},
NodeLabels: types.Labels{types.Wildcard: []string{types.Wildcard}},
},
},
},
},
}

for _, test := range tests {
Expand Down
Loading