mirror of
https://github.com/gravitational/teleport.git
synced 2026-08-31 01:50:50 +08:00
ed40e1c66d
* Add `mobile_device` kind for `mobile_device.create_enroll_token` permission * Update preset-roles.json * Add `mobile_device.create_enroll_token` to user ACL * Make boombuler/barcode a direct dep It's used in teleport.e to generate the QR code that's going to be consumed by the mobile app. * Enable defaultAllowRules to return roles which need `buildType` * Backfill device-admin role * Add `mobile_device.create_enroll_token` to admin role
351 lines
16 KiB
Go
351 lines
16 KiB
Go
/*
|
|
* Teleport
|
|
* Copyright (C) 2023 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 (
|
|
"github.com/gravitational/teleport/api/client/proto"
|
|
apidefaults "github.com/gravitational/teleport/api/defaults"
|
|
"github.com/gravitational/teleport/api/types"
|
|
"github.com/gravitational/teleport/entitlements"
|
|
"github.com/gravitational/teleport/lib/modules"
|
|
)
|
|
|
|
type ResourceAccess struct {
|
|
List bool `json:"list"`
|
|
Read bool `json:"read"`
|
|
Edit bool `json:"edit"`
|
|
Create bool `json:"create"`
|
|
Delete bool `json:"remove"`
|
|
Use bool `json:"use"`
|
|
}
|
|
|
|
// MobileDeviceAccess defines permissions for the mobile_device resource.
|
|
// It uses a dedicated shape rather than ResourceAccess because mobile_device
|
|
// exposes a custom verb, not the standard list/read/edit/create/delete/use set.
|
|
type MobileDeviceAccess struct {
|
|
// CreateEnrollToken reflects the mobile_device.create_enroll_token verb,
|
|
// which gates a user's ability to start mobile device enrollment.
|
|
CreateEnrollToken bool `json:"createEnrollToken"`
|
|
}
|
|
|
|
// UserACL is derived from a user's role set and includes
|
|
// information as to what features the user is allowed to use.
|
|
type UserACL struct {
|
|
// RecordedSessions defines access to recorded sessions.
|
|
RecordedSessions ResourceAccess `json:"recordedSessions"`
|
|
// ActiveSessions defines access to active sessions.
|
|
ActiveSessions ResourceAccess `json:"activeSessions"`
|
|
// AuthConnectors defines access to auth.connectors.
|
|
AuthConnectors ResourceAccess `json:"authConnectors"`
|
|
// Roles defines access to roles.
|
|
Roles ResourceAccess `json:"roles"`
|
|
// Users defines access to users.
|
|
Users ResourceAccess `json:"users"`
|
|
// TrustedClusters defines access to trusted clusters.
|
|
TrustedClusters ResourceAccess `json:"trustedClusters"`
|
|
// Events defines access to audit logs.
|
|
Events ResourceAccess `json:"events"`
|
|
// Tokens defines access to tokens.
|
|
Tokens ResourceAccess `json:"tokens"`
|
|
// Nodes defines access to nodes.
|
|
Nodes ResourceAccess `json:"nodes"`
|
|
// AppServers defines access to application servers
|
|
AppServers ResourceAccess `json:"appServers"`
|
|
// DBServers defines access to database servers.
|
|
DBServers ResourceAccess `json:"dbServers"`
|
|
// DB defines access to database resource.
|
|
DB ResourceAccess `json:"db"`
|
|
// KubeServers defines access to kubernetes servers.
|
|
KubeServers ResourceAccess `json:"kubeServers"`
|
|
// Desktops defines access to desktops.
|
|
Desktops ResourceAccess `json:"desktops"`
|
|
// AccessRequests defines access to access requests.
|
|
AccessRequests ResourceAccess `json:"accessRequests"`
|
|
// Billing defines access to billing information.
|
|
Billing ResourceAccess `json:"billing"`
|
|
// ConnectionDiagnostic defines access to connection diagnostics.
|
|
ConnectionDiagnostic ResourceAccess `json:"connectionDiagnostic"`
|
|
// Clipboard defines whether the user can use a shared clipboard during windows desktop sessions.
|
|
Clipboard bool `json:"clipboard"`
|
|
// DesktopSessionRecording defines whether the user's desktop sessions are being recorded.
|
|
DesktopSessionRecording bool `json:"desktopSessionRecording"`
|
|
// DirectorySharing defines whether a user is permitted to share a directory during windows desktop sessions.
|
|
DirectorySharing bool `json:"directorySharing"`
|
|
// Download defines whether the user has access to download Teleport Enterprise Binaries
|
|
Download ResourceAccess `json:"download"`
|
|
// Download defines whether the user has access to download the license
|
|
License ResourceAccess `json:"license"`
|
|
// Plugins defines whether the user has access to manage hosted plugin instances
|
|
Plugins ResourceAccess `json:"plugins"`
|
|
// Integrations defines whether the user has access to manage integrations.
|
|
Integrations ResourceAccess `json:"integrations"`
|
|
// UserTasks defines whether the user has access to manage UserTasks.
|
|
UserTasks ResourceAccess `json:"userTasks"`
|
|
// DeviceTrust defines access to device trust.
|
|
DeviceTrust ResourceAccess `json:"deviceTrust"`
|
|
// Locks defines access to locking resources.
|
|
Locks ResourceAccess `json:"lock"`
|
|
// SAMLIdpServiceProvider defines access to `saml_idp_service_provider` objects.
|
|
SAMLIdpServiceProvider ResourceAccess `json:"samlIdpServiceProvider"`
|
|
// AccessList defines access to access list management.
|
|
AccessList ResourceAccess `json:"accessList"`
|
|
// DiscoveryConfig defines whether the user has access to manage DiscoveryConfigs.
|
|
DiscoveryConfig ResourceAccess `json:"discoverConfigs"`
|
|
// AuditQuery defines access to audit query management.
|
|
AuditQuery ResourceAccess `json:"auditQuery"`
|
|
// SecurityReport defines access to security reports.
|
|
SecurityReport ResourceAccess `json:"securityReport"`
|
|
// ExternalAuditStorage defines access to manage ExternalAuditStorage
|
|
ExternalAuditStorage ResourceAccess `json:"externalAuditStorage"`
|
|
// AccessGraph defines access to access graph.
|
|
AccessGraph ResourceAccess `json:"accessGraph"`
|
|
// Bots defines access to manage Bots.
|
|
Bots ResourceAccess `json:"bots"`
|
|
// BotInstances defines access to manage bot instances
|
|
BotInstances ResourceAccess `json:"botInstances"`
|
|
// Instances defines access to manage instances
|
|
Instances ResourceAccess `json:"instances"`
|
|
// AccessMonitoringRule defines access to manage access monitoring rule resources.
|
|
AccessMonitoringRule ResourceAccess `json:"accessMonitoringRule"`
|
|
// CrownJewel defines access to manage CrownJewel resources.
|
|
CrownJewel ResourceAccess `json:"crownJewel"`
|
|
// AccessGraphSettings defines access to manage access graph settings.
|
|
AccessGraphSettings ResourceAccess `json:"accessGraphSettings"`
|
|
// ReviewRequests defines the ability to review requests
|
|
ReviewRequests bool `json:"reviewRequests"`
|
|
// Contact defines the ability to manage contacts
|
|
Contact ResourceAccess `json:"contact"`
|
|
// FileTransferAccess defines the ability to perform remote file operations via SCP or SFTP
|
|
FileTransferAccess bool `json:"fileTransferAccess"`
|
|
// WebTerminalClipboardMode determines clipboard behavior in the Web UI terminal.
|
|
WebTerminalClipboardMode types.WebTerminalClipboardMode `json:"webTerminalClipboardMode,omitempty"`
|
|
// GitServers defines access to Git servers.
|
|
GitServers ResourceAccess `json:"gitServers"`
|
|
// WorkloadIdentity defines access to Workload Identity
|
|
WorkloadIdentity ResourceAccess `json:"workloadIdentity"`
|
|
// ClientIPRestriction defines access to Cloud IP Restrictions
|
|
ClientIPRestriction ResourceAccess `json:"clientIpRestriction"`
|
|
// InferenceModel defines access to session summaries inference model.
|
|
InferenceModel ResourceAccess `json:"inferenceModel"`
|
|
// InferencePolicy defines access to session summaries inference policy.
|
|
InferencePolicy ResourceAccess `json:"inferencePolicy"`
|
|
// InferenceSecret defines access to session summaries inference secret.
|
|
InferenceSecret ResourceAccess `json:"inferenceSecret"`
|
|
// Classifier defines access to session summarization classifiers.
|
|
Classifier ResourceAccess `json:"classifier"`
|
|
// AutoUpdateConfig defines access to autoupdate config.
|
|
AutoUpdateConfig ResourceAccess `json:"autoUpdateConfig"`
|
|
// AutoUpdateVersion defines access to autoupdate version.
|
|
AutoUpdateVersion ResourceAccess `json:"autoUpdateVersion"`
|
|
// AutoUpdateAgentRollout defines access to autoupdate agent rollout.
|
|
AutoUpdateAgentRollout ResourceAccess `json:"autoUpdateAgentRollout"`
|
|
// AutoUpdateAgentReport defines access to autoupdate agent reports.
|
|
AutoUpdateAgentReport ResourceAccess `json:"autoUpdateAgentReport"`
|
|
// Beam defines access to Beams
|
|
Beam ResourceAccess `json:"beam"`
|
|
// MobileDevice defines permissions for the mobile_device resource.
|
|
MobileDevice MobileDeviceAccess `json:"mobileDevice"`
|
|
}
|
|
|
|
func hasAccess(roleSet RoleSet, ctx *Context, kind string, verbs ...string) bool {
|
|
for _, verb := range verbs {
|
|
// Since this check occurs often and does not imply the caller is trying to
|
|
// ResourceAccess any resource, silence any logging done on the proxy.
|
|
if err := roleSet.GuessIfAccessIsPossible(ctx, apidefaults.Namespace, kind, verb); err != nil {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func newAccess(roleSet RoleSet, ctx *Context, kind string) ResourceAccess {
|
|
return ResourceAccess{
|
|
List: hasAccess(roleSet, ctx, kind, types.VerbList),
|
|
Read: hasAccess(roleSet, ctx, kind, types.VerbRead),
|
|
Edit: hasAccess(roleSet, ctx, kind, types.VerbUpdate),
|
|
Create: hasAccess(roleSet, ctx, kind, types.VerbCreate),
|
|
Delete: hasAccess(roleSet, ctx, kind, types.VerbDelete),
|
|
Use: hasAccess(roleSet, ctx, kind, types.VerbUse),
|
|
}
|
|
}
|
|
|
|
// NewUserACL builds an ACL for a user based on their roles.
|
|
func NewUserACL(user types.User, userRoles RoleSet, features proto.Features, desktopRecordingEnabled, accessMonitoringEnabled bool) UserACL {
|
|
ctx := &Context{User: user}
|
|
recordedSessionAccess := newAccess(userRoles, ctx, types.KindSession)
|
|
roleAccess := newAccess(userRoles, ctx, types.KindRole)
|
|
authConnectors := newAccess(userRoles, ctx, types.KindAuthConnector)
|
|
trustedClusterAccess := newAccess(userRoles, ctx, types.KindTrustedCluster)
|
|
eventAccess := newAccess(userRoles, ctx, types.KindEvent)
|
|
userAccess := newAccess(userRoles, ctx, types.KindUser)
|
|
tokenAccess := newAccess(userRoles, ctx, types.KindToken)
|
|
nodeAccess := newAccess(userRoles, ctx, types.KindNode)
|
|
appServerAccess := newAccess(userRoles, ctx, types.KindAppServer)
|
|
dbServerAccess := newAccess(userRoles, ctx, types.KindDatabaseServer)
|
|
dbAccess := newAccess(userRoles, ctx, types.KindDatabase)
|
|
kubeServerAccess := newAccess(userRoles, ctx, types.KindKubeServer)
|
|
requestAccess := newAccess(userRoles, ctx, types.KindAccessRequest)
|
|
accessMonitoringRules := newAccess(userRoles, ctx, types.KindAccessMonitoringRule)
|
|
desktopAccess := newAccess(userRoles, ctx, types.KindWindowsDesktop)
|
|
cnDiagnosticAccess := newAccess(userRoles, ctx, types.KindConnectionDiagnostic)
|
|
samlIdpServiceProviderAccess := newAccess(userRoles, ctx, types.KindSAMLIdPServiceProvider)
|
|
gitServersAccess := newAccess(userRoles, ctx, types.KindGitServer)
|
|
|
|
// active sessions are a special case - if a user's role set has any join_sessions
|
|
// policies then the ACL must permit showing active sessions
|
|
activeSessionAccess := newAccess(userRoles, ctx, types.KindSSHSession)
|
|
if userRoles.CanJoinSessions() {
|
|
activeSessionAccess.List = true
|
|
activeSessionAccess.Read = true
|
|
}
|
|
|
|
// The billing dashboards are available in: cloud clusters &
|
|
// usage-based self-hosted non-stripe dashboards.
|
|
var billingAccess ResourceAccess
|
|
isDashboard := IsDashboard(features)
|
|
isUsageBased := features.IsUsageBased
|
|
isStripeManaged := features.IsStripeManaged
|
|
|
|
if features.Cloud || (isDashboard && isUsageBased && !isStripeManaged) {
|
|
billingAccess = newAccess(userRoles, ctx, types.KindBilling)
|
|
}
|
|
|
|
var pluginsAccess ResourceAccess
|
|
if features.Plugins {
|
|
pluginsAccess = newAccess(userRoles, ctx, types.KindPlugin)
|
|
}
|
|
|
|
var accessGraphAccess ResourceAccess
|
|
var accessGraphSettings ResourceAccess
|
|
if features.AccessGraph {
|
|
accessGraphAccess = newAccess(userRoles, ctx, types.KindAccessGraph)
|
|
}
|
|
// accessGraphSettings should always be enabled for users to interact with demo mode
|
|
accessGraphSettings = newAccess(userRoles, ctx, types.KindAccessGraphSettings)
|
|
|
|
clipboard := userRoles.DesktopClipboard()
|
|
desktopSessionRecording := desktopRecordingEnabled && userRoles.RecordDesktopSession()
|
|
directorySharing := userRoles.DesktopDirectorySharing()
|
|
download := newAccess(userRoles, ctx, types.KindDownload)
|
|
license := newAccess(userRoles, ctx, types.KindLicense)
|
|
deviceTrust := newAccess(userRoles, ctx, types.KindDevice)
|
|
integrationsAccess := newAccess(userRoles, ctx, types.KindIntegration)
|
|
discoveryConfigsAccess := newAccess(userRoles, ctx, types.KindDiscoveryConfig)
|
|
lockAccess := newAccess(userRoles, ctx, types.KindLock)
|
|
accessListAccess := newAccess(userRoles, ctx, types.KindAccessList)
|
|
externalAuditStorage := newAccess(userRoles, ctx, types.KindExternalAuditStorage)
|
|
bots := newAccess(userRoles, ctx, types.KindBot)
|
|
botInstances := newAccess(userRoles, ctx, types.KindBotInstance)
|
|
instances := newAccess(userRoles, ctx, types.KindInstance)
|
|
crownJewelAccess := newAccess(userRoles, ctx, types.KindCrownJewel)
|
|
userTasksAccess := newAccess(userRoles, ctx, types.KindUserTask)
|
|
reviewRequests := userRoles.MaybeCanReviewRequests()
|
|
fileTransferAccess := userRoles.CanCopyFiles()
|
|
workloadIdentity := newAccess(userRoles, ctx, types.KindWorkloadIdentity)
|
|
|
|
var auditQuery ResourceAccess
|
|
var securityReports ResourceAccess
|
|
if accessMonitoringEnabled {
|
|
auditQuery = newAccess(userRoles, ctx, types.KindAuditQuery)
|
|
securityReports = newAccess(userRoles, ctx, types.KindSecurityReport)
|
|
}
|
|
|
|
contact := newAccess(userRoles, ctx, types.KindContact)
|
|
|
|
var clientIPRestrictions ResourceAccess
|
|
if features.Cloud {
|
|
clientIPRestrictions = newAccess(userRoles, ctx, types.KindClientIPRestriction)
|
|
}
|
|
|
|
autoUpdateConfig := newAccess(userRoles, ctx, types.KindAutoUpdateConfig)
|
|
autoUpdateVersion := newAccess(userRoles, ctx, types.KindAutoUpdateVersion)
|
|
autoUpdateAgentRollout := newAccess(userRoles, ctx, types.KindAutoUpdateAgentRollout)
|
|
autoUpdateAgentReport := newAccess(userRoles, ctx, types.KindAutoUpdateAgentReport)
|
|
|
|
beamsEntitlement := modules.GetProtoEntitlement(&features, entitlements.Beams)
|
|
var beam ResourceAccess
|
|
if beamsEntitlement.Enabled {
|
|
beam = newAccess(userRoles, ctx, types.KindBeam)
|
|
}
|
|
|
|
mobileDevice := MobileDeviceAccess{
|
|
CreateEnrollToken: hasAccess(userRoles, ctx, types.KindMobileDevice, types.VerbCreateEnrollToken),
|
|
}
|
|
|
|
return UserACL{
|
|
AccessRequests: requestAccess,
|
|
AppServers: appServerAccess,
|
|
DBServers: dbServerAccess,
|
|
DB: dbAccess,
|
|
ReviewRequests: reviewRequests,
|
|
KubeServers: kubeServerAccess,
|
|
Desktops: desktopAccess,
|
|
AuthConnectors: authConnectors,
|
|
TrustedClusters: trustedClusterAccess,
|
|
RecordedSessions: recordedSessionAccess,
|
|
ActiveSessions: activeSessionAccess,
|
|
Roles: roleAccess,
|
|
Events: eventAccess,
|
|
Users: userAccess,
|
|
Tokens: tokenAccess,
|
|
Nodes: nodeAccess,
|
|
Billing: billingAccess,
|
|
ConnectionDiagnostic: cnDiagnosticAccess,
|
|
Clipboard: clipboard,
|
|
DesktopSessionRecording: desktopSessionRecording,
|
|
DirectorySharing: directorySharing,
|
|
Download: download,
|
|
License: license,
|
|
Plugins: pluginsAccess,
|
|
Integrations: integrationsAccess,
|
|
UserTasks: userTasksAccess,
|
|
DiscoveryConfig: discoveryConfigsAccess,
|
|
DeviceTrust: deviceTrust,
|
|
Locks: lockAccess,
|
|
SAMLIdpServiceProvider: samlIdpServiceProviderAccess,
|
|
AccessList: accessListAccess,
|
|
AuditQuery: auditQuery,
|
|
SecurityReport: securityReports,
|
|
ExternalAuditStorage: externalAuditStorage,
|
|
AccessGraph: accessGraphAccess,
|
|
Bots: bots,
|
|
BotInstances: botInstances,
|
|
Instances: instances,
|
|
AccessMonitoringRule: accessMonitoringRules,
|
|
CrownJewel: crownJewelAccess,
|
|
AccessGraphSettings: accessGraphSettings,
|
|
Contact: contact,
|
|
FileTransferAccess: fileTransferAccess,
|
|
WebTerminalClipboardMode: userRoles.GetWebTerminalClipboardMode(),
|
|
GitServers: gitServersAccess,
|
|
WorkloadIdentity: workloadIdentity,
|
|
ClientIPRestriction: clientIPRestrictions,
|
|
InferenceModel: newAccess(userRoles, ctx, types.KindInferenceModel),
|
|
InferencePolicy: newAccess(userRoles, ctx, types.KindInferencePolicy),
|
|
InferenceSecret: newAccess(userRoles, ctx, types.KindInferenceSecret),
|
|
Classifier: newAccess(userRoles, ctx, types.KindClassifier),
|
|
AutoUpdateConfig: autoUpdateConfig,
|
|
AutoUpdateVersion: autoUpdateVersion,
|
|
AutoUpdateAgentRollout: autoUpdateAgentRollout,
|
|
AutoUpdateAgentReport: autoUpdateAgentReport,
|
|
Beam: beam,
|
|
MobileDevice: mobileDevice,
|
|
}
|
|
}
|