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
9 changes: 9 additions & 0 deletions central/role/accessscope_ids.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package role

// Postgres IDs for access scopes
// The values are UUIDs taken in descending order from ffffffff-ffff-fff4-f5ff-ffffffffffff
// Next ID: ffffffff-ffff-fff4-f5ff-fffffffffffd
const (
unrestrictedAccessScopeID = "ffffffff-ffff-fff4-f5ff-ffffffffffff"
denyAllAccessScopeID = "ffffffff-ffff-fff4-f5ff-fffffffffffe"
)
16 changes: 16 additions & 0 deletions central/role/datastore/permissionset_ids.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package datastore

// Postgres IDs for permission sets
// The values are UUIDs taken in descending order from ffffffff-ffff-fff4-f5ff-ffffffffffff
// Next ID: ffffffff-ffff-fff4-f5ff-fffffffffff6
const (
adminPermissionSetID = "ffffffff-ffff-fff4-f5ff-ffffffffffff"
analystPermissionSetID = "ffffffff-ffff-fff4-f5ff-fffffffffffe"
continuousIntegrationPermissionSetID = "ffffffff-ffff-fff4-f5ff-fffffffffffd"
nonePermissionSetID = "ffffffff-ffff-fff4-f5ff-fffffffffffc"
scopeManagerPermissionSetID = "ffffffff-ffff-fff4-f5ff-fffffffffffb"
sensorCreatorPermissionSetID = "ffffffff-ffff-fff4-f5ff-fffffffffffa"
vulnMgmtApproverPermissionSetID = "ffffffff-ffff-fff4-f5ff-fffffffffff9"
vulnMgmtRequesterPermissionSetID = "ffffffff-ffff-fff4-f5ff-fffffffffff8"
vulnReporterPermissionSetID = "ffffffff-ffff-fff4-f5ff-fffffffffff7"
)
19 changes: 18 additions & 1 deletion central/role/datastore/singleton.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,34 @@ func Singleton() DataStore {

type roleAttributes struct {
idSuffix string
postgresID string // postgresID should be populated with valid UUID values.
description string
resourceWithAccess []permissions.ResourceWithAccess
}

func (attributes *roleAttributes) getID() string {
if env.PostgresDatastoreEnabled.BooleanSetting() {
return attributes.postgresID
}
return rolePkg.EnsureValidPermissionSetID(attributes.idSuffix)
}

var defaultRoles = map[string]roleAttributes{
rolePkg.Admin: {
idSuffix: "admin",
postgresID: adminPermissionSetID,
description: "For users: use it to provide read and write access to all the resources",
resourceWithAccess: resources.AllResourcesModifyPermissions(),
},
rolePkg.Analyst: {
idSuffix: "analyst",
postgresID: analystPermissionSetID,
resourceWithAccess: rolePkg.GetAnalystPermissions(),
description: "For users: use it to give read-only access to all the resources",
},
rolePkg.ContinuousIntegration: {
idSuffix: "continuousintegration",
postgresID: continuousIntegrationPermissionSetID,
description: "For automation: it includes the permissions required to enforce deployment policies",
resourceWithAccess: []permissions.ResourceWithAccess{
permissions.View(resources.Detection),
Expand All @@ -92,10 +103,12 @@ var defaultRoles = map[string]roleAttributes{
},
rolePkg.None: {
idSuffix: "none",
postgresID: nonePermissionSetID,
description: "For users: use it to provide no read and write access to any resource",
},
rolePkg.ScopeManager: {
idSuffix: "scopemanager",
postgresID: scopeManagerPermissionSetID,
description: "For users: use it to create and modify scopes for the purpose of access control or vulnerability reporting",
resourceWithAccess: []permissions.ResourceWithAccess{
permissions.View(resources.Access),
Expand All @@ -107,6 +120,7 @@ var defaultRoles = map[string]roleAttributes{
},
rolePkg.SensorCreator: {
idSuffix: "sensorcreator",
postgresID: sensorCreatorPermissionSetID,
description: "For automation: it consists of the permissions to create Sensors in secured clusters",
resourceWithAccess: []permissions.ResourceWithAccess{
permissions.View(resources.Cluster),
Expand All @@ -117,6 +131,7 @@ var defaultRoles = map[string]roleAttributes{
},
rolePkg.VulnMgmtApprover: {
idSuffix: "vulnmgmtapprover",
postgresID: vulnMgmtApproverPermissionSetID,
description: "For users: use it to provide access to approve vulnerability deferrals or false positive requests",
resourceWithAccess: []permissions.ResourceWithAccess{
permissions.View(resources.VulnerabilityManagementApprovals),
Expand All @@ -125,6 +140,7 @@ var defaultRoles = map[string]roleAttributes{
},
rolePkg.VulnMgmtRequester: {
idSuffix: "vulnmgmtrequester",
postgresID: vulnMgmtRequesterPermissionSetID,
description: "For users: use it to provide access to request vulnerability deferrals or false positives",
resourceWithAccess: []permissions.ResourceWithAccess{
permissions.View(resources.VulnerabilityManagementRequests),
Expand All @@ -136,6 +152,7 @@ var defaultRoles = map[string]roleAttributes{
var vulnReportingDefaultRoles = map[string]roleAttributes{
rolePkg.VulnReporter: {
idSuffix: "vulnreporter",
postgresID: vulnReporterPermissionSetID,
description: "For users: use it to create and manage vulnerability reporting configurations for scheduled vulnerability reports",
resourceWithAccess: []permissions.ResourceWithAccess{
permissions.View(resources.VulnerabilityReports), // required for vuln report configurations
Expand All @@ -161,7 +178,7 @@ func getDefaultObjects() ([]*storage.Role, []*storage.PermissionSet, []*storage.
}

permissionSet := &storage.PermissionSet{
Id: rolePkg.EnsureValidPermissionSetID(attributes.idSuffix),
Id: attributes.getID(),
Name: role.Name,
Description: role.Description,
ResourceToAccess: resourceToAccess,
Expand Down
19 changes: 17 additions & 2 deletions central/role/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/stackrox/rox/central/role/resources"
"github.com/stackrox/rox/generated/storage"
"github.com/stackrox/rox/pkg/auth/permissions"
"github.com/stackrox/rox/pkg/env"
"github.com/stackrox/rox/pkg/grpc/authn"
"github.com/stackrox/rox/pkg/set"
)
Expand Down Expand Up @@ -48,7 +49,7 @@ var (
// AccessScopeExcludeAll has empty rules and hence excludes all
// scoped resources. Global resources must be unaffected.
AccessScopeExcludeAll = &storage.SimpleAccessScope{
Id: EnsureValidAccessScopeID("denyall"),
Id: getAccessScopeExcludeAllID(),
Name: "Deny All",
Description: "No access to scoped resources",
Rules: &storage.SimpleAccessScope_Rules{},
Expand All @@ -57,12 +58,26 @@ var (
// AccessScopeIncludeAll gives access to all resources. It is checked by ID, as
// Rules cannot represent unrestricted scope.
AccessScopeIncludeAll = &storage.SimpleAccessScope{
Id: EnsureValidAccessScopeID("unrestricted"),
Id: getAccessScopeIncludeAllID(),
Name: "Unrestricted",
Description: "Access to all clusters and namespaces",
}
)

func getAccessScopeExcludeAllID() string {
if env.PostgresDatastoreEnabled.BooleanSetting() {
return denyAllAccessScopeID
}
return EnsureValidAccessScopeID("denyall")
}

func getAccessScopeIncludeAllID() string {
if env.PostgresDatastoreEnabled.BooleanSetting() {
return unrestrictedAccessScopeID
}
return EnsureValidAccessScopeID("unrestricted")
}

// IsDefaultRoleName checks if a given role name corresponds to a default role.
func IsDefaultRoleName(name string) bool {
return DefaultRoleNames.Contains(name)
Expand Down
4 changes: 2 additions & 2 deletions central/role/store/permissionset/postgres/store.go

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

4 changes: 2 additions & 2 deletions central/role/store/simpleaccessscope/postgres/store.go

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

42 changes: 37 additions & 5 deletions central/role/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/stackrox/rox/central/role/resources"
"github.com/stackrox/rox/generated/storage"
"github.com/stackrox/rox/pkg/auth/permissions"
"github.com/stackrox/rox/pkg/env"
"github.com/stackrox/rox/pkg/sac/effectiveaccessscope"
"github.com/stackrox/rox/pkg/uuid"
"k8s.io/apimachinery/pkg/labels"
Expand All @@ -25,34 +26,60 @@ const (
accessScopeIDPrefix = "io.stackrox.authz.accessscope."
)

func generateIdentifier(prefix string) string {
generatedIDSuffix := uuid.NewV4().String()
if env.PostgresDatastoreEnabled.BooleanSetting() {
return generatedIDSuffix
}
return prefix + generatedIDSuffix
}

func isValidIdentifier(prefix string, id string) bool {
if env.PostgresDatastoreEnabled.BooleanSetting() {
_, parseErr := uuid.FromString(id)
return parseErr == nil
}
return strings.HasPrefix(id, prefix)
}

// GeneratePermissionSetID returns a random valid permission set ID.
func GeneratePermissionSetID() string {
return permissionSetIDPrefix + uuid.NewV4().String()
return generateIdentifier(permissionSetIDPrefix)
}

// EnsureValidPermissionSetID converts id to the correct format if necessary.
func EnsureValidPermissionSetID(id string) string {
if strings.HasPrefix(id, permissionSetIDPrefix) {
if isValidIdentifier(permissionSetIDPrefix, id) {
return id
}
if env.PostgresDatastoreEnabled.BooleanSetting() {
return generateIdentifier(permissionSetIDPrefix)
}
return permissionSetIDPrefix + id
}

// GenerateAccessScopeID returns a random valid access scope ID.
func GenerateAccessScopeID() string {
return accessScopeIDPrefix + uuid.NewV4().String()
return generateIdentifier(accessScopeIDPrefix)
}

// EnsureValidAccessScopeID converts id to the correct format if necessary.
func EnsureValidAccessScopeID(id string) string {
if strings.HasPrefix(id, accessScopeIDPrefix) {
if isValidIdentifier(accessScopeIDPrefix, id) {
return id
}
if env.PostgresDatastoreEnabled.BooleanSetting() {
return generateIdentifier(accessScopeIDPrefix)
}
return accessScopeIDPrefix + id
}

// ValidateAccessScopeID returns an error if the scope ID prefix is not correct.
func ValidateAccessScopeID(scope *storage.SimpleAccessScope) error {
if env.PostgresDatastoreEnabled.BooleanSetting() {
_, parseErr := uuid.FromString(scope.GetId())
return parseErr
}
if !strings.HasPrefix(scope.GetId(), accessScopeIDPrefix) {
return errors.Errorf("id field must be in '%s*' format", accessScopeIDPrefix)
}
Expand Down Expand Up @@ -92,7 +119,12 @@ func ValidateRole(role *storage.Role) error {
func ValidatePermissionSet(ps *storage.PermissionSet) error {
var multiErr error

if !strings.HasPrefix(ps.GetId(), permissionSetIDPrefix) {
if env.PostgresDatastoreEnabled.BooleanSetting() {
_, parseErr := uuid.FromString(ps.GetId())
if parseErr != nil {
multiErr = multierror.Append(multiErr, errors.Wrap(parseErr, "id field must be a valid UUID"))
}
} else if !strings.HasPrefix(ps.GetId(), permissionSetIDPrefix) {
multiErr = multierror.Append(multiErr, errors.Errorf("id field must be in '%s*' format", permissionSetIDPrefix))
}
if ps.GetName() == "" {
Expand Down
Loading