Skip to content

Commit 293c43c

Browse files
craig[bot]Santamaura
craig[bot]
andcommitted
Merge #84198
84198: sql, server: observability replace role options with system privileges r=Santamaura a=Santamaura This patch introduces system privileges that exist currently as role options. For observability they are the following: VIEWACTIVITY, VIEWACTIVTYREDACTED, VIEWCLUSTERSETTING, CANCELQUERY and NOSQLLOGIN. Users should now do GRANT SYSTEM `privilege` TO `role`; instead of using role options. Brand new system privileges for observability will be introduced in a subsequent PR. Any additional gating with these system privileges beyond the basic ones made in this PR will be done in a subsequent PR. Resolves #83843 Release note (sql change): introduced VIEWACTIVITY, VIEWACTIVITYREDACTED, VIEWCLUSTERSETTING, CANCELQUERY, and NOSQLLOGIN as system privileges. Co-authored-by: Santamaura <[email protected]>
2 parents 658bf2b + be41f0a commit 293c43c

File tree

15 files changed

+414
-95
lines changed

15 files changed

+414
-95
lines changed

pkg/ccl/logictestccl/testdata/logic_test/crdb_internal_tenant

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ SELECT count(distinct(node_id)), count(*) FROM crdb_internal.node_runtime_info
88
query IT
99
SELECT node_id, name FROM crdb_internal.leases ORDER BY name
1010
----
11+
0 defaultdb
1112
0 eventlog
1213
0 jobs
1314
0 locations
15+
0 privileges
1416
0 protected_ts_meta
1517
0 protected_ts_records
1618
0 role_members

pkg/server/BUILD.bazel

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ go_library(
182182
"//pkg/sql/pgwire/pgerror",
183183
"//pkg/sql/pgwire/pgwirecancel",
184184
"//pkg/sql/physicalplan",
185+
"//pkg/sql/privilege",
185186
"//pkg/sql/querycache",
186187
"//pkg/sql/rangeprober",
187188
"//pkg/sql/roleoption",
@@ -205,6 +206,7 @@ go_library(
205206
"//pkg/sql/sqlutil",
206207
"//pkg/sql/stats",
207208
"//pkg/sql/stmtdiagnostics",
209+
"//pkg/sql/syntheticprivilege",
208210
"//pkg/sql/ttl/ttljob",
209211
"//pkg/sql/ttl/ttlschedule",
210212
"//pkg/sql/types",
@@ -416,6 +418,7 @@ go_test(
416418
"//pkg/sql/sem/catconstants",
417419
"//pkg/sql/sem/tree",
418420
"//pkg/sql/sessiondata",
421+
"//pkg/sql/sessiondatapb",
419422
"//pkg/sql/sqlstats",
420423
"//pkg/sql/sqlstats/persistedsqlstats",
421424
"//pkg/sql/tests",

pkg/server/admin.go

Lines changed: 81 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
"github.com/cockroachdb/apd/v3"
2626
"github.com/cockroachdb/cockroach/pkg/base"
27+
"github.com/cockroachdb/cockroach/pkg/clusterversion"
2728
"github.com/cockroachdb/cockroach/pkg/config/zonepb"
2829
"github.com/cockroachdb/cockroach/pkg/jobs"
2930
"github.com/cockroachdb/cockroach/pkg/jobs/jobspb"
@@ -46,10 +47,12 @@ import (
4647
"github.com/cockroachdb/cockroach/pkg/sql/catalog/colinfo"
4748
"github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb"
4849
"github.com/cockroachdb/cockroach/pkg/sql/parser"
50+
"github.com/cockroachdb/cockroach/pkg/sql/privilege"
4951
"github.com/cockroachdb/cockroach/pkg/sql/roleoption"
5052
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
5153
"github.com/cockroachdb/cockroach/pkg/sql/sessiondata"
5254
"github.com/cockroachdb/cockroach/pkg/sql/sqlutil"
55+
"github.com/cockroachdb/cockroach/pkg/sql/syntheticprivilege"
5356
"github.com/cockroachdb/cockroach/pkg/ts/catalog"
5457
"github.com/cockroachdb/cockroach/pkg/util/contextutil"
5558
"github.com/cockroachdb/cockroach/pkg/util/envutil"
@@ -1828,20 +1831,27 @@ func (s *adminServer) Settings(
18281831
// Non-root access cannot see the values in any case.
18291832
lookupPurpose = settings.LookupForReporting
18301833

1831-
hasView, err := s.hasRoleOption(ctx, user, roleoption.VIEWCLUSTERSETTING)
1832-
if err != nil {
1833-
return nil, err
1834-
}
1835-
1836-
hasModify, err := s.hasRoleOption(ctx, user, roleoption.MODIFYCLUSTERSETTING)
1837-
if err != nil {
1838-
return nil, err
1834+
hasView := false
1835+
hasModify := false
1836+
if s.st.Version.IsActive(ctx, clusterversion.SystemPrivilegesTable) {
1837+
hasView = s.checkHasSystemPrivilege(ctx, user, privilege.VIEWCLUSTERSETTING)
1838+
hasModify = s.checkHasSystemPrivilege(ctx, user, privilege.MODIFYCLUSTERSETTING)
18391839
}
1840-
18411840
if !hasModify && !hasView {
1842-
return nil, status.Errorf(
1843-
codes.PermissionDenied, "this operation requires either %s or %s role options",
1844-
roleoption.VIEWCLUSTERSETTING, roleoption.MODIFYCLUSTERSETTING)
1841+
hasView, err := s.hasRoleOption(ctx, user, roleoption.VIEWCLUSTERSETTING)
1842+
if err != nil {
1843+
return nil, err
1844+
}
1845+
1846+
hasModify, err := s.hasRoleOption(ctx, user, roleoption.MODIFYCLUSTERSETTING)
1847+
if err != nil {
1848+
return nil, err
1849+
}
1850+
if !hasModify && !hasView {
1851+
return nil, status.Errorf(
1852+
codes.PermissionDenied, "this operation requires either %s or %s system privileges",
1853+
privilege.VIEWCLUSTERSETTING, privilege.MODIFYCLUSTERSETTING)
1854+
}
18451855
}
18461856
}
18471857

@@ -3410,7 +3420,9 @@ func (s *adminServer) dialNode(
34103420
// adminPrivilegeChecker is a helper struct to check whether given usernames
34113421
// have admin privileges.
34123422
type adminPrivilegeChecker struct {
3413-
ie *sql.InternalExecutor
3423+
ie *sql.InternalExecutor
3424+
st *cluster.Settings
3425+
makePlanner func(opName string) (interface{}, func())
34143426
}
34153427

34163428
// requireAdminUser's error return is a gRPC error.
@@ -3434,15 +3446,20 @@ func (c *adminPrivilegeChecker) requireViewActivityPermission(ctx context.Contex
34343446
return serverError(ctx, err)
34353447
}
34363448
if !isAdmin {
3437-
hasViewActivity, err := c.hasRoleOption(ctx, userName, roleoption.VIEWACTIVITY)
3438-
if err != nil {
3439-
return serverError(ctx, err)
3449+
hasView := false
3450+
if c.st.Version.IsActive(ctx, clusterversion.SystemPrivilegesTable) {
3451+
hasView = c.checkHasSystemPrivilege(ctx, userName, privilege.VIEWACTIVITY)
34403452
}
3441-
3442-
if !hasViewActivity {
3443-
return status.Errorf(
3444-
codes.PermissionDenied, "this operation requires the %s role option",
3445-
roleoption.VIEWACTIVITY)
3453+
if !hasView {
3454+
hasView, err := c.hasRoleOption(ctx, userName, roleoption.VIEWACTIVITY)
3455+
if err != nil {
3456+
return serverError(ctx, err)
3457+
}
3458+
if !hasView {
3459+
return status.Errorf(
3460+
codes.PermissionDenied, "this operation requires the %s system privilege",
3461+
roleoption.VIEWACTIVITY)
3462+
}
34463463
}
34473464
}
34483465
return nil
@@ -3457,20 +3474,24 @@ func (c *adminPrivilegeChecker) requireViewActivityOrViewActivityRedactedPermiss
34573474
return serverError(ctx, err)
34583475
}
34593476
if !isAdmin {
3460-
hasViewActivity, err := c.hasRoleOption(ctx, userName, roleoption.VIEWACTIVITY)
3461-
if err != nil {
3462-
return serverError(ctx, err)
3463-
}
3464-
3465-
if !hasViewActivity {
3466-
hasViewActivityRedacted, err := c.hasRoleOption(ctx, userName, roleoption.VIEWACTIVITYREDACTED)
3477+
hasView := false
3478+
hasViewRedacted := false
3479+
if c.st.Version.IsActive(ctx, clusterversion.SystemPrivilegesTable) {
3480+
hasView = c.checkHasSystemPrivilege(ctx, userName, privilege.VIEWACTIVITY)
3481+
hasViewRedacted = c.checkHasSystemPrivilege(ctx, userName, privilege.VIEWACTIVITYREDACTED)
3482+
}
3483+
if !hasView && !hasViewRedacted {
3484+
hasView, err := c.hasRoleOption(ctx, userName, roleoption.VIEWACTIVITY)
34673485
if err != nil {
34683486
return serverError(ctx, err)
34693487
}
3470-
3471-
if !hasViewActivityRedacted {
3488+
hasViewRedacted, err := c.hasRoleOption(ctx, userName, roleoption.VIEWACTIVITYREDACTED)
3489+
if err != nil {
3490+
return serverError(ctx, err)
3491+
}
3492+
if !hasView && !hasViewRedacted {
34723493
return status.Errorf(
3473-
codes.PermissionDenied, "this operation requires the %s or %s role options",
3494+
codes.PermissionDenied, "this operation requires the %s or %s system privileges",
34743495
roleoption.VIEWACTIVITY, roleoption.VIEWACTIVITYREDACTED)
34753496
}
34763497
}
@@ -3490,14 +3511,24 @@ func (c *adminPrivilegeChecker) requireViewActivityAndNoViewActivityRedactedPerm
34903511
}
34913512

34923513
if !isAdmin {
3493-
hasViewActivityRedacted, err := c.hasRoleOption(ctx, userName, roleoption.VIEWACTIVITYREDACTED)
3494-
if err != nil {
3495-
return serverError(ctx, err)
3514+
hasViewRedacted := false
3515+
if c.st.Version.IsActive(ctx, clusterversion.SystemPrivilegesTable) {
3516+
hasViewRedacted = c.checkHasSystemPrivilege(ctx, userName, privilege.VIEWACTIVITYREDACTED)
34963517
}
3497-
if hasViewActivityRedacted {
3518+
if !hasViewRedacted {
3519+
hasViewRedacted, err := c.hasRoleOption(ctx, userName, roleoption.VIEWACTIVITYREDACTED)
3520+
if err != nil {
3521+
return serverError(ctx, err)
3522+
}
3523+
if hasViewRedacted {
3524+
return status.Errorf(
3525+
codes.PermissionDenied, "this operation requires %s role option and is not allowed for %s role option",
3526+
roleoption.VIEWACTIVITY, roleoption.VIEWACTIVITYREDACTED)
3527+
}
3528+
} else {
34983529
return status.Errorf(
3499-
codes.PermissionDenied, "this operation requires %s role option and is not allowed for %s role option",
3500-
roleoption.VIEWACTIVITY, roleoption.VIEWACTIVITYREDACTED)
3530+
codes.PermissionDenied, "this operation requires %s system privilege and is not allowed for %s system privilege",
3531+
privilege.VIEWACTIVITY, privilege.VIEWACTIVITYREDACTED)
35013532
}
35023533
return c.requireViewActivityPermission(ctx)
35033534
}
@@ -3575,6 +3606,19 @@ func (c *adminPrivilegeChecker) hasRoleOption(
35753606
return bool(dbDatum), nil
35763607
}
35773608

3609+
// checkHasSystemPrivilege is a helper function which calls
3610+
// CheckPrivilege and returns a true/false based on the returned
3611+
// result.
3612+
func (c *adminPrivilegeChecker) checkHasSystemPrivilege(
3613+
ctx context.Context, user username.SQLUsername, privilege privilege.Kind,
3614+
) bool {
3615+
planner, cleanup := c.makePlanner("check-system-privilege")
3616+
defer cleanup()
3617+
aa := planner.(sql.AuthorizationAccessor)
3618+
err := aa.CheckPrivilegeForUser(ctx, syntheticprivilege.GlobalPrivilegeObject, privilege, user)
3619+
return err == nil
3620+
}
3621+
35783622
var errRequiresAdmin = status.Error(codes.PermissionDenied, "this operation requires admin privilege")
35793623

35803624
func errRequiresRoleOption(option roleoption.Option) error {

pkg/server/admin_test.go

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"time"
2929

3030
"github.com/cockroachdb/cockroach/pkg/base"
31+
"github.com/cockroachdb/cockroach/pkg/clusterversion"
3132
"github.com/cockroachdb/cockroach/pkg/config/zonepb"
3233
"github.com/cockroachdb/cockroach/pkg/jobs"
3334
"github.com/cockroachdb/cockroach/pkg/jobs/jobspb"
@@ -48,6 +49,7 @@ import (
4849
"github.com/cockroachdb/cockroach/pkg/sql/catalog/descpb"
4950
"github.com/cockroachdb/cockroach/pkg/sql/idxusage"
5051
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
52+
"github.com/cockroachdb/cockroach/pkg/sql/sessiondatapb"
5153
"github.com/cockroachdb/cockroach/pkg/testutils"
5254
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
5355
"github.com/cockroachdb/cockroach/pkg/testutils/skip"
@@ -2748,7 +2750,7 @@ func TestAdminPrivilegeChecker(t *testing.T) {
27482750
defer log.Scope(t).Close(t)
27492751

27502752
ctx := context.Background()
2751-
s, db, _ := serverutils.StartServer(t, base.TestServerArgs{
2753+
s, db, kvDB := serverutils.StartServer(t, base.TestServerArgs{
27522754
// Disable the default test tenant for now as this tests fails
27532755
// with it enabled. Tracked with #81590.
27542756
DisableDefaultTestTenant: true,
@@ -2767,8 +2769,26 @@ func TestAdminPrivilegeChecker(t *testing.T) {
27672769
sqlDB.Exec(t, "ALTER ROLE withvaandredacted WITH VIEWACTIVITYREDACTED")
27682770
sqlDB.Exec(t, "CREATE USER withoutprivs")
27692771

2772+
execCfg := s.ExecutorConfig().(sql.ExecutorConfig)
2773+
2774+
plannerFn := func(opName string) (interface{}, func()) {
2775+
// This is a hack to get around a Go package dependency cycle. See comment
2776+
// in sql/jobs/registry.go on planHookMaker.
2777+
txn := kvDB.NewTxn(ctx, "test")
2778+
return sql.NewInternalPlanner(
2779+
opName,
2780+
txn,
2781+
username.RootUserName(),
2782+
&sql.MemoryMetrics{},
2783+
&execCfg,
2784+
sessiondatapb.SessionData{},
2785+
)
2786+
}
2787+
27702788
underTest := &adminPrivilegeChecker{
2771-
ie: s.InternalExecutor().(*sql.InternalExecutor),
2789+
ie: s.InternalExecutor().(*sql.InternalExecutor),
2790+
st: s.ClusterSettings(),
2791+
makePlanner: plannerFn,
27722792
}
27732793

27742794
withAdmin, err := username.MakeSQLUsernameFromPreNormalizedStringChecked("withadmin")
@@ -2809,6 +2829,31 @@ func TestAdminPrivilegeChecker(t *testing.T) {
28092829
},
28102830
},
28112831
}
2832+
// test system privileges if valid version
2833+
if s.ClusterSettings().Version.IsActive(ctx, clusterversion.SystemPrivilegesTable) {
2834+
sqlDB.Exec(t, "CREATE USER withvasystemprivilege")
2835+
sqlDB.Exec(t, "GRANT SYSTEM VIEWACTIVITY TO withvasystemprivilege")
2836+
sqlDB.Exec(t, "CREATE USER withvaredactedsystemprivilege")
2837+
sqlDB.Exec(t, "GRANT SYSTEM VIEWACTIVITYREDACTED TO withvaredactedsystemprivilege")
2838+
sqlDB.Exec(t, "CREATE USER withvaandredactedsystemprivilege")
2839+
sqlDB.Exec(t, "GRANT SYSTEM VIEWACTIVITY TO withvaandredactedsystemprivilege")
2840+
sqlDB.Exec(t, "GRANT SYSTEM VIEWACTIVITYREDACTED TO withvaandredactedsystemprivilege")
2841+
2842+
withVaSystemPrivilege := username.MakeSQLUsernameFromPreNormalizedString("withvasystemprivilege")
2843+
withVaRedactedSystemPrivilege := username.MakeSQLUsernameFromPreNormalizedString("withvaredactedsystemprivilege")
2844+
withVaAndRedactedSystemPrivilege := username.MakeSQLUsernameFromPreNormalizedString("withvaandredactedsystemprivilege")
2845+
2846+
tests[0].usernameWantErr[withVaSystemPrivilege] = false
2847+
tests[1].usernameWantErr[withVaSystemPrivilege] = false
2848+
tests[2].usernameWantErr[withVaSystemPrivilege] = false
2849+
tests[0].usernameWantErr[withVaRedactedSystemPrivilege] = true
2850+
tests[1].usernameWantErr[withVaRedactedSystemPrivilege] = false
2851+
tests[2].usernameWantErr[withVaRedactedSystemPrivilege] = true
2852+
tests[0].usernameWantErr[withVaAndRedactedSystemPrivilege] = false
2853+
tests[1].usernameWantErr[withVaAndRedactedSystemPrivilege] = false
2854+
tests[2].usernameWantErr[withVaAndRedactedSystemPrivilege] = true
2855+
2856+
}
28122857
for _, tt := range tests {
28132858
for userName, wantErr := range tt.usernameWantErr {
28142859
t.Run(fmt.Sprintf("%s-%s", tt.name, userName), func(t *testing.T) {

pkg/server/server.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import (
4545
"github.com/cockroachdb/cockroach/pkg/roachpb"
4646
"github.com/cockroachdb/cockroach/pkg/rpc"
4747
"github.com/cockroachdb/cockroach/pkg/rpc/nodedialer"
48+
"github.com/cockroachdb/cockroach/pkg/security/username"
4849
"github.com/cockroachdb/cockroach/pkg/server/debug"
4950
"github.com/cockroachdb/cockroach/pkg/server/diagnostics"
5051
"github.com/cockroachdb/cockroach/pkg/server/serverpb"
@@ -67,8 +68,9 @@ import (
6768
"github.com/cockroachdb/cockroach/pkg/sql/optionalnodeliveness"
6869
"github.com/cockroachdb/cockroach/pkg/sql/pgwire"
6970
_ "github.com/cockroachdb/cockroach/pkg/sql/schemachanger/scjob" // register jobs declared outside of pkg/sql
70-
_ "github.com/cockroachdb/cockroach/pkg/sql/ttl/ttljob" // register jobs declared outside of pkg/sql
71-
_ "github.com/cockroachdb/cockroach/pkg/sql/ttl/ttlschedule" // register schedules declared outside of pkg/sql
71+
"github.com/cockroachdb/cockroach/pkg/sql/sessiondatapb"
72+
_ "github.com/cockroachdb/cockroach/pkg/sql/ttl/ttljob" // register jobs declared outside of pkg/sql
73+
_ "github.com/cockroachdb/cockroach/pkg/sql/ttl/ttlschedule" // register schedules declared outside of pkg/sql
7274
"github.com/cockroachdb/cockroach/pkg/storage/enginepb"
7375
"github.com/cockroachdb/cockroach/pkg/ts"
7476
"github.com/cockroachdb/cockroach/pkg/util"
@@ -714,7 +716,7 @@ func NewServer(cfg Config, stopper *stop.Stopper) (*Server, error) {
714716

715717
lateBoundServer := &Server{}
716718
// TODO(tbg): give adminServer only what it needs (and avoid circular deps).
717-
adminAuthzCheck := &adminPrivilegeChecker{ie: internalExecutor}
719+
adminAuthzCheck := &adminPrivilegeChecker{ie: internalExecutor, st: st}
718720
sAdmin := newAdminServer(lateBoundServer, adminAuthzCheck, internalExecutor)
719721

720722
// These callbacks help us avoid a dependency on gossip in httpServer.
@@ -814,6 +816,20 @@ func NewServer(cfg Config, stopper *stop.Stopper) (*Server, error) {
814816
return nil, err
815817
}
816818

819+
adminAuthzCheck.makePlanner = func(opName string) (interface{}, func()) {
820+
// This is a hack to get around a Go package dependency cycle. See comment
821+
// in sql/jobs/registry.go on planHookMaker.
822+
txn := db.NewTxn(ctx, "check-system-privilege")
823+
return sql.NewInternalPlanner(
824+
opName,
825+
txn,
826+
username.RootUserName(),
827+
&sql.MemoryMetrics{},
828+
sqlServer.execCfg,
829+
sessiondatapb.SessionData{},
830+
)
831+
}
832+
817833
sAuth := newAuthenticationServer(cfg.Config, sqlServer)
818834
for i, gw := range []grpcGatewayServer{sAdmin, sStatus, sAuth, &sTS} {
819835
if reflect.ValueOf(gw).IsNil() {

pkg/server/status.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232

3333
"github.com/cockroachdb/cockroach/pkg/base"
3434
"github.com/cockroachdb/cockroach/pkg/build"
35+
"github.com/cockroachdb/cockroach/pkg/clusterversion"
3536
"github.com/cockroachdb/cockroach/pkg/gossip"
3637
"github.com/cockroachdb/cockroach/pkg/jobs"
3738
"github.com/cockroachdb/cockroach/pkg/jobs/jobspb"
@@ -59,6 +60,7 @@ import (
5960
"github.com/cockroachdb/cockroach/pkg/sql/contentionpb"
6061
"github.com/cockroachdb/cockroach/pkg/sql/flowinfra"
6162
"github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgwirecancel"
63+
"github.com/cockroachdb/cockroach/pkg/sql/privilege"
6264
"github.com/cockroachdb/cockroach/pkg/sql/roleoption"
6365
"github.com/cockroachdb/cockroach/pkg/sql/sem/catconstants"
6466
"github.com/cockroachdb/cockroach/pkg/util"
@@ -322,12 +324,18 @@ func (b *baseStatusServer) checkCancelPrivilege(
322324
if sessionUser != reqUser {
323325
// Must have CANCELQUERY privilege to cancel other users'
324326
// sessions/queries.
325-
ok, err := b.privilegeChecker.hasRoleOption(ctx, reqUser, roleoption.CANCELQUERY)
326-
if err != nil {
327-
return serverError(ctx, err)
327+
hasCancelQuery := false
328+
if b.privilegeChecker.st.Version.IsActive(ctx, clusterversion.SystemPrivilegesTable) {
329+
hasCancelQuery = b.privilegeChecker.checkHasSystemPrivilege(ctx, reqUser, privilege.CANCELQUERY)
328330
}
329-
if !ok {
330-
return errRequiresRoleOption(roleoption.CANCELQUERY)
331+
if !hasCancelQuery {
332+
ok, err := b.privilegeChecker.hasRoleOption(ctx, reqUser, roleoption.CANCELQUERY)
333+
if err != nil {
334+
return serverError(ctx, err)
335+
}
336+
if !ok {
337+
return errRequiresRoleOption(roleoption.CANCELQUERY)
338+
}
331339
}
332340
// Non-admins cannot cancel admins' sessions/queries.
333341
isAdminSession, err := b.privilegeChecker.hasAdminRole(ctx, sessionUser)

0 commit comments

Comments
 (0)