Thanks to visit codestin.com
Credit goes to pkg.go.dev

rbac

package
v2.21.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 29, 2025 License: AGPL-3.0 Imports: 28 Imported by: 0

README

Authz

Package rbac implements Role-Based Access Control for Coder.

See USAGE.md for a hands-on approach to using this package.

Overview

Authorization defines what permission a subject has to perform actions to objects:

  • Permission is binary: yes (allowed) or no (denied).
  • Subject in this case is anything that implements interface rbac.Subject.
  • Action here is an enumerated list of actions. Actions can differ for each object type. They typically read like, Create, Read, Update, Delete, etc.
  • Object here is anything that implements rbac.Object.

Permission Structure

A permission is a rule that grants or denies access for a subject to perform an action on a object. A permission is always applied at a given level:

  • site level applies to all objects in a given Coder deployment.
  • org level applies to all objects that have an organization owner (org_owner)
  • user level applies to all objects that have an owner with the same ID as the subject.

Permissions at a higher level always override permissions at a lower level.

The effect of a permission can be:

  • positive (allows)
  • negative (denies)
  • abstain (neither allows or denies, not applicable)

Negative permissions always override positive permissions at the same level. Both negative and positive permissions override abstain at the same level.

This can be represented by the following truth table, where Y represents positive, N represents negative, and _ represents abstain:

Action Positive Negative Result
read Y _ Y
read Y N N
read _ _ _
read _ N N

Permission Representation

Permissions are represented in string format as <sign>?<level>.<object>.<id>.<action>, where:

  • negated can be either + or -. If it is omitted, sign is assumed to be +.
  • level is either site, org, or user.
  • object is any valid resource type.
  • id is any valid UUID v4.
  • id is included in the permission syntax, however only scopes may use id to specify a specific object.
  • action is typically create, read, modify, delete, but you can define other verbs as needed.

Example Permissions

  • +site.app.*.read: allowed to perform the read action against all objects of type app in a given Coder deployment.
  • -user.workspace.*.create: user is not allowed to create workspaces.

Roles

A role is a set of permissions. When evaluating a role's permission to form an action, all the relevant permissions for the role are combined at each level. Permissions at a higher level override permissions at a lower level.

The following table shows the per-level role evaluation. Y indicates that the role provides positive permissions, N indicates the role provides negative permissions, and indicates the role does not provide positive or negative permissions. YN indicates that the value in the cell does not matter for the access result.

Role (example) Site Org User Result
site-admin Y YN_ YN_ Y
no-permission N YN_ YN_ N
org-admin _ Y YN_ Y
non-org-member _ N YN_ N
user _ _ Y Y
_ _ N N
unauthenticated _ _ _ N

Scopes

Scopes can restrict a given set of permissions. The format of a scope matches a role with the addition of a list of resource ids. For a authorization call to be successful, the subject's roles and the subject's scopes must both allow the action. This means the resulting permissions is the intersection of the subject's roles and the subject's scopes.

An example to give a readonly token is to grant a readonly scope across all resources +site.*.*.read. The intersection with the user's permissions will be the readonly set of their permissions.

Resource IDs

There exists use cases that require specifying a specific resource. If resource IDs are allowed in the roles, then there is an unbounded set of resource IDs that be added to an "allow_list", as the number of roles a user can have is unbounded. This also adds a level of complexity to the role evaluation logic that has large costs at scale.

The use case for specifying this type of permission in a role is limited, and does not justify the extra cost. To solve this for the remaining cases (eg. workspace agent tokens), we can apply an allow_list on a scope. For most cases, the allow_list will just be ["*"] which means the scope is allowed to be applied to any resource. This adds negligible cost to the role evaluation logic and 0 cost to partial evaluations.

Example of a scope for a workspace agent token, using an allow_list containing a single resource id.

    "scope": {
      "name": "workspace_agent",
      "display_name": "Workspace_Agent",
      // The ID of the given workspace the agent token correlates to.
      "allow_list": ["10d03e62-7703-4df5-a358-4f76577d4e2f"],
      "site": [/* ... perms ... */],
      "org": {/* ... perms ... */},
      "user": [/* ... perms ... */]
    }

Testing

You can test outside of golang by using the opa cli.

Evaluation

opa eval --format=pretty "data.authz.allow" -d policy.rego -i input.json

Partial Evaluation

opa eval --partial --format=pretty 'data.authz.allow' -d policy.rego --unknowns input.object.owner --unknowns input.object.org_owner --unknowns input.object.acl_user_list --unknowns input.object.acl_group_list -i input.json

Documentation

Overview

Code generated by typegen/main.go. DO NOT EDIT.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ResourceWildcard
	// Valid Actions
	ResourceWildcard = Object{
		Type: "*",
	}

	// ResourceApiKey
	// Valid Actions
	//  - "ActionCreate" :: create an api key
	//  - "ActionDelete" :: delete an api key
	//  - "ActionRead" :: read api key details (secrets are not stored)
	//  - "ActionUpdate" :: update an api key, eg expires
	ResourceApiKey = Object{
		Type: "api_key",
	}

	// ResourceAssignOrgRole
	// Valid Actions
	//  - "ActionAssign" :: assign org scoped roles
	//  - "ActionCreate" :: create/delete custom roles within an organization
	//  - "ActionDelete" :: delete roles within an organization
	//  - "ActionRead" :: view what roles are assignable within an organization
	//  - "ActionUnassign" :: unassign org scoped roles
	//  - "ActionUpdate" :: edit custom roles within an organization
	ResourceAssignOrgRole = Object{
		Type: "assign_org_role",
	}

	// ResourceAssignRole
	// Valid Actions
	//  - "ActionAssign" :: assign user roles
	//  - "ActionRead" :: view what roles are assignable
	//  - "ActionUnassign" :: unassign user roles
	ResourceAssignRole = Object{
		Type: "assign_role",
	}

	// ResourceAuditLog
	// Valid Actions
	//  - "ActionCreate" :: create new audit log entries
	//  - "ActionRead" :: read audit logs
	ResourceAuditLog = Object{
		Type: "audit_log",
	}

	// ResourceCryptoKey
	// Valid Actions
	//  - "ActionCreate" :: create crypto keys
	//  - "ActionDelete" :: delete crypto keys
	//  - "ActionRead" :: read crypto keys
	//  - "ActionUpdate" :: update crypto keys
	ResourceCryptoKey = Object{
		Type: "crypto_key",
	}

	// ResourceDebugInfo
	// Valid Actions
	//  - "ActionRead" :: access to debug routes
	ResourceDebugInfo = Object{
		Type: "debug_info",
	}

	// ResourceDeploymentConfig
	// Valid Actions
	//  - "ActionRead" :: read deployment config
	//  - "ActionUpdate" :: updating health information
	ResourceDeploymentConfig = Object{
		Type: "deployment_config",
	}

	// ResourceDeploymentStats
	// Valid Actions
	//  - "ActionRead" :: read deployment stats
	ResourceDeploymentStats = Object{
		Type: "deployment_stats",
	}

	// ResourceFile
	// Valid Actions
	//  - "ActionCreate" :: create a file
	//  - "ActionRead" :: read files
	ResourceFile = Object{
		Type: "file",
	}

	// ResourceGroup
	// Valid Actions
	//  - "ActionCreate" :: create a group
	//  - "ActionDelete" :: delete a group
	//  - "ActionRead" :: read groups
	//  - "ActionUpdate" :: update a group
	ResourceGroup = Object{
		Type: "group",
	}

	// ResourceGroupMember
	// Valid Actions
	//  - "ActionRead" :: read group members
	ResourceGroupMember = Object{
		Type: "group_member",
	}

	// ResourceIdpsyncSettings
	// Valid Actions
	//  - "ActionRead" :: read IdP sync settings
	//  - "ActionUpdate" :: update IdP sync settings
	ResourceIdpsyncSettings = Object{
		Type: "idpsync_settings",
	}

	// ResourceInboxNotification
	// Valid Actions
	//  - "ActionCreate" :: create inbox notifications
	//  - "ActionRead" :: read inbox notifications
	//  - "ActionUpdate" :: update inbox notifications
	ResourceInboxNotification = Object{
		Type: "inbox_notification",
	}

	// ResourceLicense
	// Valid Actions
	//  - "ActionCreate" :: create a license
	//  - "ActionDelete" :: delete license
	//  - "ActionRead" :: read licenses
	ResourceLicense = Object{
		Type: "license",
	}

	// ResourceNotificationMessage
	// Valid Actions
	//  - "ActionCreate" :: create notification messages
	//  - "ActionDelete" :: delete notification messages
	//  - "ActionRead" :: read notification messages
	//  - "ActionUpdate" :: update notification messages
	ResourceNotificationMessage = Object{
		Type: "notification_message",
	}

	// ResourceNotificationPreference
	// Valid Actions
	//  - "ActionRead" :: read notification preferences
	//  - "ActionUpdate" :: update notification preferences
	ResourceNotificationPreference = Object{
		Type: "notification_preference",
	}

	// ResourceNotificationTemplate
	// Valid Actions
	//  - "ActionRead" :: read notification templates
	//  - "ActionUpdate" :: update notification templates
	ResourceNotificationTemplate = Object{
		Type: "notification_template",
	}

	// ResourceOauth2App
	// Valid Actions
	//  - "ActionCreate" :: make an OAuth2 app
	//  - "ActionDelete" :: delete an OAuth2 app
	//  - "ActionRead" :: read OAuth2 apps
	//  - "ActionUpdate" :: update the properties of the OAuth2 app
	ResourceOauth2App = Object{
		Type: "oauth2_app",
	}

	// ResourceOauth2AppCodeToken
	// Valid Actions
	//  - "ActionCreate" :: create an OAuth2 app code token
	//  - "ActionDelete" :: delete an OAuth2 app code token
	//  - "ActionRead" :: read an OAuth2 app code token
	ResourceOauth2AppCodeToken = Object{
		Type: "oauth2_app_code_token",
	}

	// ResourceOauth2AppSecret
	// Valid Actions
	//  - "ActionCreate" :: create an OAuth2 app secret
	//  - "ActionDelete" :: delete an OAuth2 app secret
	//  - "ActionRead" :: read an OAuth2 app secret
	//  - "ActionUpdate" :: update an OAuth2 app secret
	ResourceOauth2AppSecret = Object{
		Type: "oauth2_app_secret",
	}

	// ResourceOrganization
	// Valid Actions
	//  - "ActionCreate" :: create an organization
	//  - "ActionDelete" :: delete an organization
	//  - "ActionRead" :: read organizations
	//  - "ActionUpdate" :: update an organization
	ResourceOrganization = Object{
		Type: "organization",
	}

	// ResourceOrganizationMember
	// Valid Actions
	//  - "ActionCreate" :: create an organization member
	//  - "ActionDelete" :: delete member
	//  - "ActionRead" :: read member
	//  - "ActionUpdate" :: update an organization member
	ResourceOrganizationMember = Object{
		Type: "organization_member",
	}

	// ResourceProvisionerDaemon
	// Valid Actions
	//  - "ActionCreate" :: create a provisioner daemon/key
	//  - "ActionDelete" :: delete a provisioner daemon/key
	//  - "ActionRead" :: read provisioner daemon
	//  - "ActionUpdate" :: update a provisioner daemon
	ResourceProvisionerDaemon = Object{
		Type: "provisioner_daemon",
	}

	// ResourceProvisionerJobs
	// Valid Actions
	//  - "ActionRead" :: read provisioner jobs
	ResourceProvisionerJobs = Object{
		Type: "provisioner_jobs",
	}

	// ResourceReplicas
	// Valid Actions
	//  - "ActionRead" :: read replicas
	ResourceReplicas = Object{
		Type: "replicas",
	}

	// ResourceSystem
	// Valid Actions
	//  - "ActionCreate" :: create system resources
	//  - "ActionDelete" :: delete system resources
	//  - "ActionRead" :: view system resources
	//  - "ActionUpdate" :: update system resources
	ResourceSystem = Object{
		Type: "system",
	}

	// ResourceTailnetCoordinator
	// Valid Actions
	//  - "ActionCreate" :: create a Tailnet coordinator
	//  - "ActionDelete" :: delete a Tailnet coordinator
	//  - "ActionRead" :: view info about a Tailnet coordinator
	//  - "ActionUpdate" :: update a Tailnet coordinator
	ResourceTailnetCoordinator = Object{
		Type: "tailnet_coordinator",
	}

	// ResourceTemplate
	// Valid Actions
	//  - "ActionCreate" :: create a template
	//  - "ActionDelete" :: delete a template
	//  - "ActionRead" :: read template
	//  - "ActionUpdate" :: update a template
	//  - "ActionUse" :: use the template to initially create a workspace, then workspace lifecycle permissions take over
	//  - "ActionViewInsights" :: view insights
	ResourceTemplate = Object{
		Type: "template",
	}

	// ResourceUser
	// Valid Actions
	//  - "ActionCreate" :: create a new user
	//  - "ActionDelete" :: delete an existing user
	//  - "ActionRead" :: read user data
	//  - "ActionReadPersonal" :: read personal user data like user settings and auth links
	//  - "ActionUpdate" :: update an existing user
	//  - "ActionUpdatePersonal" :: update personal data
	ResourceUser = Object{
		Type: "user",
	}

	// ResourceWebpushSubscription
	// Valid Actions
	//  - "ActionCreate" :: create webpush subscriptions
	//  - "ActionDelete" :: delete webpush subscriptions
	//  - "ActionRead" :: read webpush subscriptions
	ResourceWebpushSubscription = Object{
		Type: "webpush_subscription",
	}

	// ResourceWorkspace
	// Valid Actions
	//  - "ActionApplicationConnect" :: connect to workspace apps via browser
	//  - "ActionCreate" :: create a new workspace
	//  - "ActionDelete" :: delete workspace
	//  - "ActionRead" :: read workspace data to view on the UI
	//  - "ActionSSH" :: ssh into a given workspace
	//  - "ActionWorkspaceStart" :: allows starting a workspace
	//  - "ActionWorkspaceStop" :: allows stopping a workspace
	//  - "ActionUpdate" :: edit workspace settings (scheduling, permissions, parameters)
	ResourceWorkspace = Object{
		Type: "workspace",
	}

	// ResourceWorkspaceAgentDevcontainers
	// Valid Actions
	//  - "ActionCreate" :: create workspace agent devcontainers
	ResourceWorkspaceAgentDevcontainers = Object{
		Type: "workspace_agent_devcontainers",
	}

	// ResourceWorkspaceAgentResourceMonitor
	// Valid Actions
	//  - "ActionCreate" :: create workspace agent resource monitor
	//  - "ActionRead" :: read workspace agent resource monitor
	//  - "ActionUpdate" :: update workspace agent resource monitor
	ResourceWorkspaceAgentResourceMonitor = Object{
		Type: "workspace_agent_resource_monitor",
	}

	// ResourceWorkspaceDormant
	// Valid Actions
	//  - "ActionApplicationConnect" :: connect to workspace apps via browser
	//  - "ActionCreate" :: create a new workspace
	//  - "ActionDelete" :: delete workspace
	//  - "ActionRead" :: read workspace data to view on the UI
	//  - "ActionSSH" :: ssh into a given workspace
	//  - "ActionWorkspaceStart" :: allows starting a workspace
	//  - "ActionWorkspaceStop" :: allows stopping a workspace
	//  - "ActionUpdate" :: edit workspace settings (scheduling, permissions, parameters)
	ResourceWorkspaceDormant = Object{
		Type: "workspace_dormant",
	}

	// ResourceWorkspaceProxy
	// Valid Actions
	//  - "ActionCreate" :: create a workspace proxy
	//  - "ActionDelete" :: delete a workspace proxy
	//  - "ActionRead" :: read and use a workspace proxy
	//  - "ActionUpdate" :: update a workspace proxy
	ResourceWorkspaceProxy = Object{
		Type: "workspace_proxy",
	}
)

Functions

func AllActions

func AllActions() []policy.Action

func CanAssignRole

func CanAssignRole(subjectHasRoles ExpandableRoles, assignedRole RoleIdentifier) bool

CanAssignRole is a helper function that returns true if the user can assign the specified role. This also can be used for removing a role. This is a simple implementation for now.

func ChangeRoleSet

func ChangeRoleSet(from []RoleIdentifier, to []RoleIdentifier) (added []RoleIdentifier, removed []RoleIdentifier)

ChangeRoleSet is a helper function that finds the difference of 2 sets of roles. When setting a user's new roles, it is equivalent to adding and removing roles. This set determines the changes, so that the appropriate RBAC checks can be applied using "ActionCreate" and "ActionDelete" for "added" and "removed" roles respectively.

func ConfigWithACL

func ConfigWithACL() regosql.ConvertConfig

ConfigWithACL is the basic configuration for converting rego to SQL when the object has group and user ACL fields.

func ConfigWithoutACL

func ConfigWithoutACL() regosql.ConvertConfig

ConfigWithoutACL is the basic configuration for converting rego to SQL when the object has no ACL fields.

func ConfigWorkspaces added in v2.8.0

func ConfigWorkspaces() regosql.ConvertConfig

func Filter

func Filter[O Objecter](ctx context.Context, auth Authorizer, subject Subject, action policy.Action, objects []O) ([]O, error)

Filter takes in a list of objects, and will filter the list removing all the elements the subject does not have permission for. All objects must be of the same type.

Ideally the 'CompileToSQL' is used instead for large sets. This cost scales linearly with the number of objects passed in.

func IsUnauthorizedError

func IsUnauthorizedError(err error) bool

IsUnauthorizedError is a convenience function to check if err is UnauthorizedError. It is equivalent to errors.As(err, &UnauthorizedError{}).

func ReloadBuiltinRoles

func ReloadBuiltinRoles(opts *RoleOptions)

ReloadBuiltinRoles loads the static roles into the builtInRoles map. This can be called again with a different config to change the behavior.

TODO: @emyrk This would be great if it was instanced to a coderd rather than a global. But that is a much larger refactor right now. Essentially we did not foresee different deployments needing slightly different role permissions.

func ReservedRoleName added in v2.13.0

func ReservedRoleName(name string) bool

ReservedRoleName exists because the database should only allow unique role names, but some roles are built in. So these names are reserved

func RoleOrgAdmin

func RoleOrgAdmin() string

func RoleOrgAuditor added in v2.14.0

func RoleOrgAuditor() string

func RoleOrgMember

func RoleOrgMember() string

func RoleOrgTemplateAdmin added in v2.14.0

func RoleOrgTemplateAdmin() string

func RoleOrgUserAdmin added in v2.14.0

func RoleOrgUserAdmin() string

func RoleOrgWorkspaceCreationBan added in v2.20.0

func RoleOrgWorkspaceCreationBan() string

Types

type AuthCall

type AuthCall struct {
	Actor  Subject
	Action policy.Action
	Object Object
}

type AuthorizeFilter

type AuthorizeFilter interface {
	SQLString() string
}

AuthorizeFilter is a compiled partial query that can be converted to SQL. This allows enforcing the policy on the database side in a WHERE clause.

type Authorizer

type Authorizer interface {
	// Authorize will authorize the given subject to perform the given action
	// on the given object. Authorize is pure and deterministic with respect to
	// its arguments and the surrounding object.
	Authorize(ctx context.Context, subject Subject, action policy.Action, object Object) error
	Prepare(ctx context.Context, subject Subject, action policy.Action, objectType string) (PreparedAuthorized, error)
}

func Cacher

func Cacher(authz Authorizer) Authorizer

Cacher returns an Authorizer that can use a cache to short circuit duplicate calls to the Authorizer. This is useful when multiple calls are made to the Authorizer for the same subject, action, and object. This is a GLOBAL cache shared between all requests. If no cache is found on the context, the Authorizer is called as normal.

Cacher is safe for multiple actors.

func NewCachingAuthorizer

func NewCachingAuthorizer(registry prometheus.Registerer) Authorizer

NewCachingAuthorizer returns a new RegoAuthorizer that supports context based caching. To utilize the caching, the context passed to Authorize() must be created with 'WithCacheCtx(ctx)'.

func NewStrictCachingAuthorizer added in v2.12.0

func NewStrictCachingAuthorizer(registry prometheus.Registerer) Authorizer

NewStrictCachingAuthorizer is mainly just for testing.

type ExpandableRoles

type ExpandableRoles interface {
	Expand() ([]Role, error)
	// Names is for logging and tracing purposes, we want to know the human
	// names of the expanded roles.
	Names() []RoleIdentifier
}

ExpandableRoles is any type that can be expanded into a []Role. This is implemented as an interface so we can have RoleIdentifiers for user defined roles, and implement custom ExpandableRoles for system type users (eg autostart/autostop system role). We want a clear divide between the two types of roles so users have no codepath to interact or assign system roles.

Note: We may also want to do the same thing with scopes to allow custom scope support unavailable to the user. Eg: Scope to a single resource.

type ExpandableScope

type ExpandableScope interface {
	Expand() (Scope, error)
	// Name is for logging and tracing purposes, we want to know the human
	// name of the scope.
	Name() RoleIdentifier
}

type Object

type Object struct {
	// ID is the resource's uuid
	ID    string `json:"id"`
	Owner string `json:"owner"`
	// OrgID specifies which org the object is a part of.
	OrgID string `json:"org_owner"`
	// AnyOrgOwner will disregard the org_owner when checking for permissions
	// Use this to ask, "Can the actor do this action on any org?" when
	// the exact organization is not important or known.
	// E.g: The UI should show a "create template" button if the user
	// can create a template in any org.
	AnyOrgOwner bool `json:"any_org"`

	// Type is "workspace", "project", "app", etc
	Type string `json:"type"`

	ACLUserList  map[string][]policy.Action ` json:"acl_user_list"`
	ACLGroupList map[string][]policy.Action ` json:"acl_group_list"`
}

Object is used to create objects for authz checks when you have none in hand to run the check on. An example is if you want to list all workspaces, you can create a Object that represents the set of workspaces you are trying to get access too. Do not export this type, as it can be created from a resource type constant.

func ResourceUserObject

func ResourceUserObject(userID uuid.UUID) Object

ResourceUserObject is a helper function to create a user object for authz checks.

func (Object) All

func (z Object) All() Object

All returns an object matching all resources of the same type.

func (Object) AnyOrganization added in v2.14.0

func (z Object) AnyOrganization() Object

func (Object) AvailableActions added in v2.12.0

func (z Object) AvailableActions() []policy.Action

AvailableActions returns all available actions for a given object. Wildcard is omitted.

func (Object) Equal

func (z Object) Equal(b Object) bool

func (Object) InOrg

func (z Object) InOrg(orgID uuid.UUID) Object

InOrg adds an org OwnerID to the resource

func (Object) RBACObject

func (z Object) RBACObject() Object

func (Object) String added in v2.21.1

func (z Object) String() string

String is not perfect, but decent enough for human display

func (Object) ValidAction added in v2.12.0

func (z Object) ValidAction(action policy.Action) error

ValidAction checks if the action is valid for the given object type.

func (Object) WithACLUserList

func (z Object) WithACLUserList(acl map[string][]policy.Action) Object

WithACLUserList adds an ACL list to a given object

func (Object) WithGroupACL

func (z Object) WithGroupACL(groups map[string][]policy.Action) Object

func (Object) WithID

func (z Object) WithID(id uuid.UUID) Object

func (Object) WithIDString

func (z Object) WithIDString(id string) Object

func (Object) WithOwner

func (z Object) WithOwner(ownerID string) Object

WithOwner adds an OwnerID to the resource

type Objecter

type Objecter interface {
	RBACObject() Object
}

Objecter returns the RBAC object for itself.

func AllResources

func AllResources() []Objecter

type PartialAuthorizer

type PartialAuthorizer struct {
	// contains filtered or unexported fields
}

PartialAuthorizer is a prepared authorizer with the subject, action, and resource type fields already filled in. This speeds up authorization when authorizing the same type of object numerous times. See rbac.Filter for example usage.

func (*PartialAuthorizer) Authorize

func (pa *PartialAuthorizer) Authorize(ctx context.Context, object Object) error

func (*PartialAuthorizer) CompileToSQL

func (pa *PartialAuthorizer) CompileToSQL(ctx context.Context, cfg regosql.ConvertConfig) (string, error)

CompileToSQL converts the remaining rego queries into SQL WHERE clauses.

type Permission

type Permission struct {
	// Negate makes this a negative permission
	Negate       bool          `json:"negate"`
	ResourceType string        `json:"resource_type"`
	Action       policy.Action `json:"action"`
}

Permission is the format passed into the rego.

func Permissions

func Permissions(perms map[string][]policy.Action) []Permission

Permissions is just a helper function to make building roles that list out resources and actions a bit easier.

func (Permission) Valid added in v2.12.0

func (perm Permission) Valid() error

type PreparedAuthorized

type PreparedAuthorized interface {
	Authorize(ctx context.Context, object Object) error
	CompileToSQL(ctx context.Context, cfg regosql.ConvertConfig) (string, error)
}

type RegoAuthorizer

type RegoAuthorizer struct {
	// contains filtered or unexported fields
}

RegoAuthorizer will use a prepared rego query for performing authorize()

func NewAuthorizer

func NewAuthorizer(registry prometheus.Registerer) *RegoAuthorizer

func (RegoAuthorizer) Authorize

func (a RegoAuthorizer) Authorize(ctx context.Context, subject Subject, action policy.Action, object Object) error

Authorize is the intended function to be used outside this package. It returns `nil` if the subject is authorized to perform the action on the object. If an error is returned, the authorization is denied.

func (RegoAuthorizer) Prepare

func (a RegoAuthorizer) Prepare(ctx context.Context, subject Subject, action policy.Action, objectType string) (PreparedAuthorized, error)

Prepare will partially execute the rego policy leaving the object fields unknown (except for the type). This will vastly speed up performance if batch authorization on the same type of objects is needed.

type Role

type Role struct {
	Identifier RoleIdentifier `json:"name"`
	// DisplayName is used for UI purposes. If the role has no display name,
	// that means the UI should never display it.
	DisplayName string       `json:"display_name"`
	Site        []Permission `json:"site"`
	// Org is a map of orgid to permissions. We represent orgid as a string.
	// We scope the organizations in the role so we can easily combine all the
	// roles.
	Org  map[string][]Permission `json:"org"`
	User []Permission            `json:"user"`
	// contains filtered or unexported fields
}

Role is a set of permissions at multiple levels: - Site level permissions apply EVERYWHERE - Org level permissions apply to EVERYTHING in a given ORG - User level permissions are the lowest This is the type passed into the rego as a json payload. Users of this package should instead **only** use the role names, and this package will expand the role names into their json payloads.

func OrganizationRoles

func OrganizationRoles(organizationID uuid.UUID) []Role

OrganizationRoles lists all roles that can be applied to an organization user in the given organization. This is the list of available roles, and specific to an organization.

This should be a list in a database, but until then we build the list from the builtins.

func RoleByName

func RoleByName(name RoleIdentifier) (Role, error)

RoleByName returns the permissions associated with a given role name. This allows just the role names to be stored and expanded when required.

This function is exported so that the Display name can be returned to the api. We should maybe make an exported function that returns just the human-readable content of the Role struct (name + display name).

func SiteRoles

func SiteRoles() []Role

SiteRoles lists all roles that can be applied to a user. This is the list of available roles, and not specific to a user

This should be a list in a database, but until then we build the list from the builtins.

func (Role) Valid added in v2.12.0

func (role Role) Valid() error

Valid will check all it's permissions and ensure they are all correct according to the policy. This verifies every action specified make sense for the given resource.

type RoleIdentifier added in v2.13.0

type RoleIdentifier struct {
	Name string
	// OrganizationID is uuid.Nil for unscoped roles (aka deployment wide)
	OrganizationID uuid.UUID
}

RoleIdentifier contains both the name of the role, and any organizational scope. Both fields are required to be globally unique and identifiable.

func CustomOrganizationRole added in v2.13.0

func CustomOrganizationRole(orgID uuid.UUID) RoleIdentifier

func CustomSiteRole added in v2.12.0

func CustomSiteRole() RoleIdentifier

func RoleAuditor added in v2.13.0

func RoleAuditor() RoleIdentifier

func RoleMember

func RoleMember() RoleIdentifier

func RoleNameFromString added in v2.13.0

func RoleNameFromString(input string) (RoleIdentifier, error)

RoleNameFromString takes a formatted string '<role_name>[:org_id]'.

func RoleOwner

func RoleOwner() RoleIdentifier

func RoleTemplateAdmin

func RoleTemplateAdmin() RoleIdentifier

func RoleUserAdmin

func RoleUserAdmin() RoleIdentifier

func ScopedRoleOrgAdmin added in v2.13.0

func ScopedRoleOrgAdmin(organizationID uuid.UUID) RoleIdentifier

ScopedRoleOrgAdmin is the org role with the organization ID

func ScopedRoleOrgAuditor added in v2.14.0

func ScopedRoleOrgAuditor(organizationID uuid.UUID) RoleIdentifier

func ScopedRoleOrgMember added in v2.13.0

func ScopedRoleOrgMember(organizationID uuid.UUID) RoleIdentifier

ScopedRoleOrgMember is the org role with the organization ID

func ScopedRoleOrgTemplateAdmin added in v2.14.0

func ScopedRoleOrgTemplateAdmin(organizationID uuid.UUID) RoleIdentifier

func ScopedRoleOrgUserAdmin added in v2.14.0

func ScopedRoleOrgUserAdmin(organizationID uuid.UUID) RoleIdentifier

func ScopedRoleOrgWorkspaceCreationBan added in v2.20.0

func ScopedRoleOrgWorkspaceCreationBan(organizationID uuid.UUID) RoleIdentifier

func (RoleIdentifier) IsOrgRole added in v2.13.0

func (r RoleIdentifier) IsOrgRole() bool

func (*RoleIdentifier) MarshalJSON added in v2.13.0

func (r *RoleIdentifier) MarshalJSON() ([]byte, error)

func (RoleIdentifier) String added in v2.13.0

func (r RoleIdentifier) String() string

func (RoleIdentifier) UniqueName added in v2.13.0

func (r RoleIdentifier) UniqueName() string

func (*RoleIdentifier) UnmarshalJSON added in v2.13.0

func (r *RoleIdentifier) UnmarshalJSON(data []byte) error

type RoleIdentifiers added in v2.13.0

type RoleIdentifiers []RoleIdentifier

RoleIdentifiers is a list of user assignable role names. The role names must be in the builtInRoles map. Any non-user assignable roles will generate an error on Expand.

func (RoleIdentifiers) Expand added in v2.13.0

func (names RoleIdentifiers) Expand() ([]Role, error)

func (RoleIdentifiers) Names added in v2.13.0

func (names RoleIdentifiers) Names() []RoleIdentifier

type RoleOptions

type RoleOptions struct {
	NoOwnerWorkspaceExec bool
}

type Roles

type Roles []Role

func (Roles) Expand

func (roles Roles) Expand() ([]Role, error)

func (Roles) Names

func (roles Roles) Names() []RoleIdentifier

type Scope

type Scope struct {
	Role
	AllowIDList []string `json:"allow_list"`
}

Scope acts the exact same as a Role with the addition that is can also apply an AllowIDList. Any resource being checked against a Scope will reject any resource that is not in the AllowIDList. To not use an AllowIDList to reject authorization, use a wildcard for the AllowIDList. Eg: 'AllowIDList: []string{WildcardSymbol}'

func ExpandScope

func ExpandScope(scope ScopeName) (Scope, error)

func WorkspaceAgentScope

func WorkspaceAgentScope(params WorkspaceAgentScopeParams) Scope

WorkspaceAgentScope returns a scope that is the same as ScopeAll but can only affect resources in the allow list. Only a scope is returned as the roles should come from the workspace owner.

func (Scope) Expand

func (s Scope) Expand() (Scope, error)

func (Scope) Name

func (s Scope) Name() RoleIdentifier

type ScopeName

type ScopeName string
const (
	ScopeAll                ScopeName = "all"
	ScopeApplicationConnect ScopeName = "application_connect"
)

func (ScopeName) Expand

func (name ScopeName) Expand() (Scope, error)

func (ScopeName) Name

func (name ScopeName) Name() RoleIdentifier

type Subject

type Subject struct {
	// FriendlyName is entirely optional and is used for logging and debugging
	// It is not used in any functional way.
	// It is usually the "username" of the user, but it can be the name of the
	// external workspace proxy or other service type actor.
	FriendlyName string

	// Email is entirely optional and is used for logging and debugging
	// It is not used in any functional way.
	Email string

	// Type indicates what kind of subject this is (user, system, provisioner, etc.)
	// It is not used in any functional way, only for logging.
	Type SubjectType

	ID     string
	Roles  ExpandableRoles
	Groups []string
	Scope  ExpandableScope
	// contains filtered or unexported fields
}

Subject is a struct that contains all the elements of a subject in an rbac authorize.

func (Subject) Equal

func (s Subject) Equal(b Subject) bool

func (Subject) RegoValueOk added in v2.13.0

func (s Subject) RegoValueOk() error

RegoValueOk is only used for unit testing. There is no easy way to get the error for the unexported method, and this is intentional. Failed rego values can default to the backup json marshal method, so errors are not fatal. Unit tests should be aware when the custom rego marshaller fails.

func (Subject) SafeRoleNames

func (s Subject) SafeRoleNames() []RoleIdentifier

SafeRoleNames prevent nil pointer dereference.

func (Subject) SafeScopeName

func (s Subject) SafeScopeName() string

SafeScopeName prevent nil pointer dereference.

func (Subject) WithCachedASTValue

func (s Subject) WithCachedASTValue() Subject

WithCachedASTValue can be called if the subject is static. This will compute the ast value once and cache it for future calls.

type SubjectType added in v2.19.2

type SubjectType string

SubjectType represents the type of subject in the RBAC system.

const (
	SubjectTypeUser                         SubjectType = "user"
	SubjectTypeProvisionerd                 SubjectType = "provisionerd"
	SubjectTypeAutostart                    SubjectType = "autostart"
	SubjectTypeHangDetector                 SubjectType = "hang_detector"
	SubjectTypeResourceMonitor              SubjectType = "resource_monitor"
	SubjectTypeCryptoKeyRotator             SubjectType = "crypto_key_rotator"
	SubjectTypeCryptoKeyReader              SubjectType = "crypto_key_reader"
	SubjectTypePrebuildsOrchestrator        SubjectType = "prebuilds_orchestrator"
	SubjectTypeSystemReadProvisionerDaemons SubjectType = "system_read_provisioner_daemons"
	SubjectTypeSystemRestricted             SubjectType = "system_restricted"
	SubjectTypeNotifier                     SubjectType = "notifier"
)

type UnauthorizedError

type UnauthorizedError struct {
	// contains filtered or unexported fields
}

UnauthorizedError is the error type for authorization errors

func ForbiddenWithInternal

func ForbiddenWithInternal(internal error, subject Subject, action policy.Action, object Object, output rego.ResultSet) *UnauthorizedError

ForbiddenWithInternal creates a new error that will return a simple "forbidden" to the client, logging internally the more detailed message provided.

func (*UnauthorizedError) As

func (*UnauthorizedError) As(target interface{}) bool

As implements the errors.As interface.

func (UnauthorizedError) Error

func (e UnauthorizedError) Error() string

Error implements the error interface.

func (*UnauthorizedError) Input

func (e *UnauthorizedError) Input() map[string]interface{}

func (*UnauthorizedError) Internal

func (e *UnauthorizedError) Internal() error

Internal allows the internal error message to be logged.

func (UnauthorizedError) IsUnauthorized added in v2.1.5

func (UnauthorizedError) IsUnauthorized() bool

IsUnauthorized implements the IsUnauthorized interface.

func (*UnauthorizedError) Output

func (e *UnauthorizedError) Output() rego.ResultSet

Output contains the results of the Rego query for debugging.

func (*UnauthorizedError) SetInternal

func (e *UnauthorizedError) SetInternal(err error)

func (UnauthorizedError) Unwrap

func (e UnauthorizedError) Unwrap() error

type WorkspaceAgentScopeParams added in v2.6.0

type WorkspaceAgentScopeParams struct {
	WorkspaceID uuid.UUID
	OwnerID     uuid.UUID
	TemplateID  uuid.UUID
	VersionID   uuid.UUID
}

Directories

Path Synopsis
Package regosql converts rego queries into SQL WHERE clauses.
Package regosql converts rego queries into SQL WHERE clauses.
sqltypes
Package sqltypes contains the types used to convert rego queries into SQL.
Package sqltypes contains the types used to convert rego queries into SQL.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL