mirror of
https://github.com/coder/coder.git
synced 2025-07-09 11:45:56 +00:00
chore: merge provisioner key and provisioner permissions (#16628)
Provisioner key permissions were never any different than provisioners. Merging them for a cleaner permission story until they are required (if ever) to be seperate. This removed `ResourceProvisionerKey` from RBAC and just uses the existing `ResourceProvisioner`.
This commit is contained in:
2
coderd/apidoc/docs.go
generated
2
coderd/apidoc/docs.go
generated
@ -13730,7 +13730,6 @@ const docTemplate = `{
|
|||||||
"organization_member",
|
"organization_member",
|
||||||
"provisioner_daemon",
|
"provisioner_daemon",
|
||||||
"provisioner_jobs",
|
"provisioner_jobs",
|
||||||
"provisioner_keys",
|
|
||||||
"replicas",
|
"replicas",
|
||||||
"system",
|
"system",
|
||||||
"tailnet_coordinator",
|
"tailnet_coordinator",
|
||||||
@ -13766,7 +13765,6 @@ const docTemplate = `{
|
|||||||
"ResourceOrganizationMember",
|
"ResourceOrganizationMember",
|
||||||
"ResourceProvisionerDaemon",
|
"ResourceProvisionerDaemon",
|
||||||
"ResourceProvisionerJobs",
|
"ResourceProvisionerJobs",
|
||||||
"ResourceProvisionerKeys",
|
|
||||||
"ResourceReplicas",
|
"ResourceReplicas",
|
||||||
"ResourceSystem",
|
"ResourceSystem",
|
||||||
"ResourceTailnetCoordinator",
|
"ResourceTailnetCoordinator",
|
||||||
|
2
coderd/apidoc/swagger.json
generated
2
coderd/apidoc/swagger.json
generated
@ -12419,7 +12419,6 @@
|
|||||||
"organization_member",
|
"organization_member",
|
||||||
"provisioner_daemon",
|
"provisioner_daemon",
|
||||||
"provisioner_jobs",
|
"provisioner_jobs",
|
||||||
"provisioner_keys",
|
|
||||||
"replicas",
|
"replicas",
|
||||||
"system",
|
"system",
|
||||||
"tailnet_coordinator",
|
"tailnet_coordinator",
|
||||||
@ -12455,7 +12454,6 @@
|
|||||||
"ResourceOrganizationMember",
|
"ResourceOrganizationMember",
|
||||||
"ResourceProvisionerDaemon",
|
"ResourceProvisionerDaemon",
|
||||||
"ResourceProvisionerJobs",
|
"ResourceProvisionerJobs",
|
||||||
"ResourceProvisionerKeys",
|
|
||||||
"ResourceReplicas",
|
"ResourceReplicas",
|
||||||
"ResourceSystem",
|
"ResourceSystem",
|
||||||
"ResourceTailnetCoordinator",
|
"ResourceTailnetCoordinator",
|
||||||
|
@ -324,7 +324,6 @@ var (
|
|||||||
rbac.ResourceOrganization.Type: {policy.ActionCreate, policy.ActionRead},
|
rbac.ResourceOrganization.Type: {policy.ActionCreate, policy.ActionRead},
|
||||||
rbac.ResourceOrganizationMember.Type: {policy.ActionCreate, policy.ActionDelete, policy.ActionRead},
|
rbac.ResourceOrganizationMember.Type: {policy.ActionCreate, policy.ActionDelete, policy.ActionRead},
|
||||||
rbac.ResourceProvisionerDaemon.Type: {policy.ActionCreate, policy.ActionRead, policy.ActionUpdate},
|
rbac.ResourceProvisionerDaemon.Type: {policy.ActionCreate, policy.ActionRead, policy.ActionUpdate},
|
||||||
rbac.ResourceProvisionerKeys.Type: {policy.ActionCreate, policy.ActionRead, policy.ActionDelete},
|
|
||||||
rbac.ResourceUser.Type: rbac.ResourceUser.AvailableActions(),
|
rbac.ResourceUser.Type: rbac.ResourceUser.AvailableActions(),
|
||||||
rbac.ResourceWorkspaceDormant.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStop},
|
rbac.ResourceWorkspaceDormant.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStop},
|
||||||
rbac.ResourceWorkspace.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStart, policy.ActionWorkspaceStop, policy.ActionSSH},
|
rbac.ResourceWorkspace.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStart, policy.ActionWorkspaceStop, policy.ActionSSH},
|
||||||
@ -3192,7 +3191,7 @@ func (q *querier) InsertProvisionerJobTimings(ctx context.Context, arg database.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (q *querier) InsertProvisionerKey(ctx context.Context, arg database.InsertProvisionerKeyParams) (database.ProvisionerKey, error) {
|
func (q *querier) InsertProvisionerKey(ctx context.Context, arg database.InsertProvisionerKeyParams) (database.ProvisionerKey, error) {
|
||||||
return insert(q.log, q.auth, rbac.ResourceProvisionerKeys.InOrg(arg.OrganizationID).WithID(arg.ID), q.db.InsertProvisionerKey)(ctx, arg)
|
return insert(q.log, q.auth, rbac.ResourceProvisionerDaemon.InOrg(arg.OrganizationID).WithID(arg.ID), q.db.InsertProvisionerKey)(ctx, arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *querier) InsertReplica(ctx context.Context, arg database.InsertReplicaParams) (database.Replica, error) {
|
func (q *querier) InsertReplica(ctx context.Context, arg database.InsertReplicaParams) (database.Replica, error) {
|
||||||
|
@ -277,8 +277,10 @@ func (p GetEligibleProvisionerDaemonsByProvisionerJobIDsRow) RBACObject() rbac.O
|
|||||||
return p.ProvisionerDaemon.RBACObject()
|
return p.ProvisionerDaemon.RBACObject()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RBACObject for a provisioner key is the same as a provisioner daemon.
|
||||||
|
// Keys == provisioners from a RBAC perspective.
|
||||||
func (p ProvisionerKey) RBACObject() rbac.Object {
|
func (p ProvisionerKey) RBACObject() rbac.Object {
|
||||||
return rbac.ResourceProvisionerKeys.
|
return rbac.ResourceProvisionerDaemon.
|
||||||
WithID(p.ID).
|
WithID(p.ID).
|
||||||
InOrg(p.OrganizationID)
|
InOrg(p.OrganizationID)
|
||||||
}
|
}
|
||||||
|
@ -206,8 +206,8 @@ var (
|
|||||||
|
|
||||||
// ResourceProvisionerDaemon
|
// ResourceProvisionerDaemon
|
||||||
// Valid Actions
|
// Valid Actions
|
||||||
// - "ActionCreate" :: create a provisioner daemon
|
// - "ActionCreate" :: create a provisioner daemon/key
|
||||||
// - "ActionDelete" :: delete a provisioner daemon
|
// - "ActionDelete" :: delete a provisioner daemon/key
|
||||||
// - "ActionRead" :: read provisioner daemon
|
// - "ActionRead" :: read provisioner daemon
|
||||||
// - "ActionUpdate" :: update a provisioner daemon
|
// - "ActionUpdate" :: update a provisioner daemon
|
||||||
ResourceProvisionerDaemon = Object{
|
ResourceProvisionerDaemon = Object{
|
||||||
@ -221,15 +221,6 @@ var (
|
|||||||
Type: "provisioner_jobs",
|
Type: "provisioner_jobs",
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceProvisionerKeys
|
|
||||||
// Valid Actions
|
|
||||||
// - "ActionCreate" :: create a provisioner key
|
|
||||||
// - "ActionDelete" :: delete a provisioner key
|
|
||||||
// - "ActionRead" :: read provisioner keys
|
|
||||||
ResourceProvisionerKeys = Object{
|
|
||||||
Type: "provisioner_keys",
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResourceReplicas
|
// ResourceReplicas
|
||||||
// Valid Actions
|
// Valid Actions
|
||||||
// - "ActionRead" :: read replicas
|
// - "ActionRead" :: read replicas
|
||||||
@ -355,7 +346,6 @@ func AllResources() []Objecter {
|
|||||||
ResourceOrganizationMember,
|
ResourceOrganizationMember,
|
||||||
ResourceProvisionerDaemon,
|
ResourceProvisionerDaemon,
|
||||||
ResourceProvisionerJobs,
|
ResourceProvisionerJobs,
|
||||||
ResourceProvisionerKeys,
|
|
||||||
ResourceReplicas,
|
ResourceReplicas,
|
||||||
ResourceSystem,
|
ResourceSystem,
|
||||||
ResourceTailnetCoordinator,
|
ResourceTailnetCoordinator,
|
||||||
|
@ -162,11 +162,11 @@ var RBACPermissions = map[string]PermissionDefinition{
|
|||||||
},
|
},
|
||||||
"provisioner_daemon": {
|
"provisioner_daemon": {
|
||||||
Actions: map[Action]ActionDefinition{
|
Actions: map[Action]ActionDefinition{
|
||||||
ActionCreate: actDef("create a provisioner daemon"),
|
ActionCreate: actDef("create a provisioner daemon/key"),
|
||||||
// TODO: Move to use?
|
// TODO: Move to use?
|
||||||
ActionRead: actDef("read provisioner daemon"),
|
ActionRead: actDef("read provisioner daemon"),
|
||||||
ActionUpdate: actDef("update a provisioner daemon"),
|
ActionUpdate: actDef("update a provisioner daemon"),
|
||||||
ActionDelete: actDef("delete a provisioner daemon"),
|
ActionDelete: actDef("delete a provisioner daemon/key"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"provisioner_jobs": {
|
"provisioner_jobs": {
|
||||||
@ -174,13 +174,6 @@ var RBACPermissions = map[string]PermissionDefinition{
|
|||||||
ActionRead: actDef("read provisioner jobs"),
|
ActionRead: actDef("read provisioner jobs"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"provisioner_keys": {
|
|
||||||
Actions: map[Action]ActionDefinition{
|
|
||||||
ActionCreate: actDef("create a provisioner key"),
|
|
||||||
ActionRead: actDef("read provisioner keys"),
|
|
||||||
ActionDelete: actDef("delete a provisioner key"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"organization": {
|
"organization": {
|
||||||
Actions: map[Action]ActionDefinition{
|
Actions: map[Action]ActionDefinition{
|
||||||
ActionCreate: actDef("create an organization"),
|
ActionCreate: actDef("create an organization"),
|
||||||
|
@ -556,15 +556,6 @@ func TestRolePermissions(t *testing.T) {
|
|||||||
false: {setOtherOrg, memberMe, userAdmin, orgUserAdmin, orgAuditor},
|
false: {setOtherOrg, memberMe, userAdmin, orgUserAdmin, orgAuditor},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Name: "ProvisionerKeys",
|
|
||||||
Actions: []policy.Action{policy.ActionCreate, policy.ActionRead, policy.ActionDelete},
|
|
||||||
Resource: rbac.ResourceProvisionerKeys.InOrg(orgID),
|
|
||||||
AuthorizeMap: map[bool][]hasAuthSubjects{
|
|
||||||
true: {owner, orgAdmin},
|
|
||||||
false: {setOtherOrg, memberMe, orgMemberMe, userAdmin, templateAdmin, orgTemplateAdmin, orgUserAdmin, orgAuditor},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Name: "ProvisionerJobs",
|
Name: "ProvisionerJobs",
|
||||||
Actions: []policy.Action{policy.ActionRead},
|
Actions: []policy.Action{policy.ActionRead},
|
||||||
|
@ -28,7 +28,6 @@ const (
|
|||||||
ResourceOrganizationMember RBACResource = "organization_member"
|
ResourceOrganizationMember RBACResource = "organization_member"
|
||||||
ResourceProvisionerDaemon RBACResource = "provisioner_daemon"
|
ResourceProvisionerDaemon RBACResource = "provisioner_daemon"
|
||||||
ResourceProvisionerJobs RBACResource = "provisioner_jobs"
|
ResourceProvisionerJobs RBACResource = "provisioner_jobs"
|
||||||
ResourceProvisionerKeys RBACResource = "provisioner_keys"
|
|
||||||
ResourceReplicas RBACResource = "replicas"
|
ResourceReplicas RBACResource = "replicas"
|
||||||
ResourceSystem RBACResource = "system"
|
ResourceSystem RBACResource = "system"
|
||||||
ResourceTailnetCoordinator RBACResource = "tailnet_coordinator"
|
ResourceTailnetCoordinator RBACResource = "tailnet_coordinator"
|
||||||
@ -85,7 +84,6 @@ var RBACResourceActions = map[RBACResource][]RBACAction{
|
|||||||
ResourceOrganizationMember: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
|
ResourceOrganizationMember: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
|
||||||
ResourceProvisionerDaemon: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
|
ResourceProvisionerDaemon: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
|
||||||
ResourceProvisionerJobs: {ActionRead},
|
ResourceProvisionerJobs: {ActionRead},
|
||||||
ResourceProvisionerKeys: {ActionCreate, ActionDelete, ActionRead},
|
|
||||||
ResourceReplicas: {ActionRead},
|
ResourceReplicas: {ActionRead},
|
||||||
ResourceSystem: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
|
ResourceSystem: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
|
||||||
ResourceTailnetCoordinator: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
|
ResourceTailnetCoordinator: {ActionCreate, ActionDelete, ActionRead, ActionUpdate},
|
||||||
|
5
docs/reference/api/members.md
generated
5
docs/reference/api/members.md
generated
@ -203,7 +203,6 @@ Status Code **200**
|
|||||||
| `resource_type` | `organization_member` |
|
| `resource_type` | `organization_member` |
|
||||||
| `resource_type` | `provisioner_daemon` |
|
| `resource_type` | `provisioner_daemon` |
|
||||||
| `resource_type` | `provisioner_jobs` |
|
| `resource_type` | `provisioner_jobs` |
|
||||||
| `resource_type` | `provisioner_keys` |
|
|
||||||
| `resource_type` | `replicas` |
|
| `resource_type` | `replicas` |
|
||||||
| `resource_type` | `system` |
|
| `resource_type` | `system` |
|
||||||
| `resource_type` | `tailnet_coordinator` |
|
| `resource_type` | `tailnet_coordinator` |
|
||||||
@ -366,7 +365,6 @@ Status Code **200**
|
|||||||
| `resource_type` | `organization_member` |
|
| `resource_type` | `organization_member` |
|
||||||
| `resource_type` | `provisioner_daemon` |
|
| `resource_type` | `provisioner_daemon` |
|
||||||
| `resource_type` | `provisioner_jobs` |
|
| `resource_type` | `provisioner_jobs` |
|
||||||
| `resource_type` | `provisioner_keys` |
|
|
||||||
| `resource_type` | `replicas` |
|
| `resource_type` | `replicas` |
|
||||||
| `resource_type` | `system` |
|
| `resource_type` | `system` |
|
||||||
| `resource_type` | `tailnet_coordinator` |
|
| `resource_type` | `tailnet_coordinator` |
|
||||||
@ -529,7 +527,6 @@ Status Code **200**
|
|||||||
| `resource_type` | `organization_member` |
|
| `resource_type` | `organization_member` |
|
||||||
| `resource_type` | `provisioner_daemon` |
|
| `resource_type` | `provisioner_daemon` |
|
||||||
| `resource_type` | `provisioner_jobs` |
|
| `resource_type` | `provisioner_jobs` |
|
||||||
| `resource_type` | `provisioner_keys` |
|
|
||||||
| `resource_type` | `replicas` |
|
| `resource_type` | `replicas` |
|
||||||
| `resource_type` | `system` |
|
| `resource_type` | `system` |
|
||||||
| `resource_type` | `tailnet_coordinator` |
|
| `resource_type` | `tailnet_coordinator` |
|
||||||
@ -661,7 +658,6 @@ Status Code **200**
|
|||||||
| `resource_type` | `organization_member` |
|
| `resource_type` | `organization_member` |
|
||||||
| `resource_type` | `provisioner_daemon` |
|
| `resource_type` | `provisioner_daemon` |
|
||||||
| `resource_type` | `provisioner_jobs` |
|
| `resource_type` | `provisioner_jobs` |
|
||||||
| `resource_type` | `provisioner_keys` |
|
|
||||||
| `resource_type` | `replicas` |
|
| `resource_type` | `replicas` |
|
||||||
| `resource_type` | `system` |
|
| `resource_type` | `system` |
|
||||||
| `resource_type` | `tailnet_coordinator` |
|
| `resource_type` | `tailnet_coordinator` |
|
||||||
@ -925,7 +921,6 @@ Status Code **200**
|
|||||||
| `resource_type` | `organization_member` |
|
| `resource_type` | `organization_member` |
|
||||||
| `resource_type` | `provisioner_daemon` |
|
| `resource_type` | `provisioner_daemon` |
|
||||||
| `resource_type` | `provisioner_jobs` |
|
| `resource_type` | `provisioner_jobs` |
|
||||||
| `resource_type` | `provisioner_keys` |
|
|
||||||
| `resource_type` | `replicas` |
|
| `resource_type` | `replicas` |
|
||||||
| `resource_type` | `system` |
|
| `resource_type` | `system` |
|
||||||
| `resource_type` | `tailnet_coordinator` |
|
| `resource_type` | `tailnet_coordinator` |
|
||||||
|
1
docs/reference/api/schemas.md
generated
1
docs/reference/api/schemas.md
generated
@ -5121,7 +5121,6 @@ Git clone makes use of this by parsing the URL from: 'Username for "https://gith
|
|||||||
| `organization_member` |
|
| `organization_member` |
|
||||||
| `provisioner_daemon` |
|
| `provisioner_daemon` |
|
||||||
| `provisioner_jobs` |
|
| `provisioner_jobs` |
|
||||||
| `provisioner_keys` |
|
|
||||||
| `replicas` |
|
| `replicas` |
|
||||||
| `system` |
|
| `system` |
|
||||||
| `tailnet_coordinator` |
|
| `tailnet_coordinator` |
|
||||||
|
@ -147,9 +147,13 @@ func (api *API) putOrgRoles(rw http.ResponseWriter, r *http.Request) {
|
|||||||
UUID: organization.ID,
|
UUID: organization.ID,
|
||||||
Valid: true,
|
Valid: true,
|
||||||
},
|
},
|
||||||
SitePermissions: db2sdk.List(req.SitePermissions, sdkPermissionToDB),
|
// Invalid permissions are filtered out. If this is changed
|
||||||
OrgPermissions: db2sdk.List(req.OrganizationPermissions, sdkPermissionToDB),
|
// to throw an error, then the story of a previously valid role
|
||||||
UserPermissions: db2sdk.List(req.UserPermissions, sdkPermissionToDB),
|
// now being invalid has to be addressed. Coder can change permissions,
|
||||||
|
// objects, and actions at any time.
|
||||||
|
SitePermissions: db2sdk.List(filterInvalidPermissions(req.SitePermissions), sdkPermissionToDB),
|
||||||
|
OrgPermissions: db2sdk.List(filterInvalidPermissions(req.OrganizationPermissions), sdkPermissionToDB),
|
||||||
|
UserPermissions: db2sdk.List(filterInvalidPermissions(req.UserPermissions), sdkPermissionToDB),
|
||||||
})
|
})
|
||||||
if httpapi.Is404Error(err) {
|
if httpapi.Is404Error(err) {
|
||||||
httpapi.ResourceNotFound(rw)
|
httpapi.ResourceNotFound(rw)
|
||||||
@ -247,6 +251,23 @@ func (api *API) deleteOrgRole(rw http.ResponseWriter, r *http.Request) {
|
|||||||
httpapi.Write(ctx, rw, http.StatusNoContent, nil)
|
httpapi.Write(ctx, rw, http.StatusNoContent, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func filterInvalidPermissions(permissions []codersdk.Permission) []codersdk.Permission {
|
||||||
|
// Filter out any invalid permissions
|
||||||
|
var validPermissions []codersdk.Permission
|
||||||
|
for _, permission := range permissions {
|
||||||
|
err := rbac.Permission{
|
||||||
|
Negate: permission.Negate,
|
||||||
|
ResourceType: string(permission.ResourceType),
|
||||||
|
Action: policy.Action(permission.Action),
|
||||||
|
}.Valid()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
validPermissions = append(validPermissions, permission)
|
||||||
|
}
|
||||||
|
return validPermissions
|
||||||
|
}
|
||||||
|
|
||||||
func sdkPermissionToDB(p codersdk.Permission) database.CustomRolePermission {
|
func sdkPermissionToDB(p codersdk.Permission) database.CustomRolePermission {
|
||||||
return database.CustomRolePermission{
|
return database.CustomRolePermission{
|
||||||
Negate: p.Negate,
|
Negate: p.Negate,
|
||||||
|
@ -114,19 +114,14 @@ export const RBACResourceActions: Partial<
|
|||||||
update: "update an organization member",
|
update: "update an organization member",
|
||||||
},
|
},
|
||||||
provisioner_daemon: {
|
provisioner_daemon: {
|
||||||
create: "create a provisioner daemon",
|
create: "create a provisioner daemon/key",
|
||||||
delete: "delete a provisioner daemon",
|
delete: "delete a provisioner daemon/key",
|
||||||
read: "read provisioner daemon",
|
read: "read provisioner daemon",
|
||||||
update: "update a provisioner daemon",
|
update: "update a provisioner daemon",
|
||||||
},
|
},
|
||||||
provisioner_jobs: {
|
provisioner_jobs: {
|
||||||
read: "read provisioner jobs",
|
read: "read provisioner jobs",
|
||||||
},
|
},
|
||||||
provisioner_keys: {
|
|
||||||
create: "create a provisioner key",
|
|
||||||
delete: "delete a provisioner key",
|
|
||||||
read: "read provisioner keys",
|
|
||||||
},
|
|
||||||
replicas: {
|
replicas: {
|
||||||
read: "read replicas",
|
read: "read replicas",
|
||||||
},
|
},
|
||||||
|
2
site/src/api/typesGenerated.ts
generated
2
site/src/api/typesGenerated.ts
generated
@ -1896,7 +1896,6 @@ export type RBACResource =
|
|||||||
| "organization_member"
|
| "organization_member"
|
||||||
| "provisioner_daemon"
|
| "provisioner_daemon"
|
||||||
| "provisioner_jobs"
|
| "provisioner_jobs"
|
||||||
| "provisioner_keys"
|
|
||||||
| "replicas"
|
| "replicas"
|
||||||
| "system"
|
| "system"
|
||||||
| "tailnet_coordinator"
|
| "tailnet_coordinator"
|
||||||
@ -1932,7 +1931,6 @@ export const RBACResources: RBACResource[] = [
|
|||||||
"organization_member",
|
"organization_member",
|
||||||
"provisioner_daemon",
|
"provisioner_daemon",
|
||||||
"provisioner_jobs",
|
"provisioner_jobs",
|
||||||
"provisioner_keys",
|
|
||||||
"replicas",
|
"replicas",
|
||||||
"system",
|
"system",
|
||||||
"tailnet_coordinator",
|
"tailnet_coordinator",
|
||||||
|
@ -101,11 +101,6 @@ export const MockRoles: (AssignableRoles | Role)[] = [
|
|||||||
resource_type: "provisioner_daemon",
|
resource_type: "provisioner_daemon",
|
||||||
action: "*" as RBACAction,
|
action: "*" as RBACAction,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
negate: false,
|
|
||||||
resource_type: "provisioner_keys",
|
|
||||||
action: "*" as RBACAction,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
negate: false,
|
negate: false,
|
||||||
resource_type: "replicas",
|
resource_type: "replicas",
|
||||||
|
Reference in New Issue
Block a user