acls

package
v0.0.0-...-04fcbae Latest Latest
Warning

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

Go to latest
Published: Dec 3, 2024 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package acls implements access control checks for Swarming APIs.

Index

Constants

This section is empty.

Variables

View Source
var (
	// PermServersPeek controls who can see information about the server.
	PermServersPeek = realms.RegisterPermission("swarming.servers.peek")
	// PermTasksGet controls who can see the task known by its ID.
	PermTasksGet = realms.RegisterPermission("swarming.tasks.get")
	// PermTasksCancel controls who can cancel the task known by its ID.
	PermTasksCancel = realms.RegisterPermission("swarming.tasks.cancel")
	// PermTasksActAs controls what service accounts the task can run as.
	PermTasksActAs = realms.RegisterPermission("swarming.tasks.actAs")
	// PermTasksCreateInRealm controls who can associate tasks with the realm.
	PermTasksCreateInRealm = realms.RegisterPermission("swarming.tasks.createInRealm")
	// PermPoolsListBots controls who can see bots in the pool.
	PermPoolsListBots = realms.RegisterPermission("swarming.pools.listBots")
	// PermPoolsListTasks controls who can see tasks in the pool.
	PermPoolsListTasks = realms.RegisterPermission("swarming.pools.listTasks")
	// PermPoolsCreateBot controls who can add bots to the pool.
	PermPoolsCreateBot = realms.RegisterPermission("swarming.pools.createBot")
	// PermPoolsDeleteBot controls who can remove bots from the pool.
	PermPoolsDeleteBot = realms.RegisterPermission("swarming.pools.deleteBot")
	// PermPoolsTerminateBot controls who can terminate bots in the pool.
	PermPoolsTerminateBot = realms.RegisterPermission("swarming.pools.terminateBot")
	// PermPoolsCreateTask controls who can submit tasks into the pool.
	PermPoolsCreateTask = realms.RegisterPermission("swarming.pools.createTask")
	// PermPoolsCancelTask controls who can cancel tasks in the pool.
	PermPoolsCancelTask = realms.RegisterPermission("swarming.pools.cancelTask")
	// PermPoolsCreateHighPriorityTask controls who can submit high priority (<20) tasks into the pool.
	PermPoolsCreateHighPriorityTask = realms.RegisterPermission("swarming.pools.createHighPriorityTask")
)

Functions

This section is empty.

Types

type CheckResult

type CheckResult struct {
	// Permitted is true if the permission check passed successfully.
	//
	// It is false if the caller doesn't have the requested permission or the
	// check itself failed. Look at InternalError field to distinguish these cases
	// if necessary.
	//
	// Use ToGrpcErr to convert a failure to a gRPC error. Note that CheckResult
	// explicitly **does not** implement `error` interface to make sure callers
	// are aware they need to return the gRPC error without any additional
	// wrapping via `return nil, res.ToGrpcErr()`.
	Permitted bool

	// InternalError indicates there were some internal error checking ACLs.
	//
	// An internal error means the check itself failed due to internal errors,
	// such as a timeout contacting the backend. This should abort the request
	// handler ASAP with Internal gRPC error. Use ToGrpcErr to get such error.
	//
	// If both Permitted and InternalError are false, it means the caller has no
	// requested permission. Use ToGrpcErr to get the error that must be returned
	// to the caller in that case.
	InternalError bool
	// contains filtered or unexported fields
}

CheckResult is returned by all Checker methods.

func (*CheckResult) ToGrpcErr

func (res *CheckResult) ToGrpcErr() error

ToGrpcErr converts this failure to a gRPC error.

To avoid accidentally leaking private information or implementation details, this error should be returned to the gRPC caller as is, without any additional wrapping. It is constructed to have all necessary information about the call already.

If the check succeeded and the access is permitted, returns nil.

func (*CheckResult) ToTaggedError

func (res *CheckResult) ToTaggedError() error

ToTaggedError converts this failure to a generic tagged error.

If the check succeeded, returns nil. If the check failed due to an internal error, returns an error tagged with Transient tag. If the check failed due to lack of permissions, returns an error without Transient tag.

To avoid accidentally leaking private information or implementation details, this error should be returned to the caller as is, without any additional wrapping. It is constructed to have all necessary information about the call already.

Use only from non-gRPC handlers.

type Checker

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

Checker knows how to check Swarming ACLs inside a single RPC call.

Its lifetime is scoped to a single request. It caches checks done within this request to avoid doing redundant work. This cache never expires, thus it is important to **drop** this checker once the request is finished, to avoid using stale cached data.

Resources are organized hierarchically: Server => Pool => Task and Bot. Permissions can potentially be granted on any level of this hierarchy, e.g. permissions granted on a pool level apply to all tasks and bots the belong to this pool.

RPCs concerned with a specific task or bot should just check permission on the task/bot layer using CheckTaskPerm/CheckBotPerm.

RPCs that do listing or other operations that touch many tasks and bots may use CheckPoolPerm and CheckServerPerm to do "prefiltering". They should also be used if RPCs results are an aggregation over a pool, and thus explicitly require pool-level permissions.

Not safe for concurrent use without external synchronization.

func NewChecker

func NewChecker(ctx context.Context, cfg *cfg.Config) *Checker

NewChecker constructs an ACL checker that uses the given config snapshot.

func (*Checker) Caller

func (chk *Checker) Caller() identity.Identity

Caller returns the identity of the caller.

func (*Checker) CheckAllPoolsPerm

func (chk *Checker) CheckAllPoolsPerm(ctx context.Context, pools []string, perm realms.Permission) CheckResult

CheckAllPoolsPerm checks if the caller has a permission in *all* given pools.

The list of pools must not be empty. Panics if it is.

func (*Checker) CheckAnyPoolsPerm

func (chk *Checker) CheckAnyPoolsPerm(ctx context.Context, pools []string, perm realms.Permission) CheckResult

CheckAnyPoolsPerm checks if the caller has a permission in *any* given pool.

The list of pools must not be empty. Panics if it is.

func (*Checker) CheckBotPerm

func (chk *Checker) CheckBotPerm(ctx context.Context, botID string, perm realms.Permission) CheckResult

CheckBotPerm checks if the caller has a permission in a specific bot.

It looks up a realm the bot belong to (based on "pool" dimension) and then checks the caller has the required permission in this realm.

func (*Checker) CheckNewTaskAllowed

func (chk *Checker) CheckNewTaskAllowed(ctx context.Context, taskRealm, serviceAccount string) CheckResult

CheckNewTaskAllowed checks permissions to create a task in a realm.

It checks * if the caller has the permissions to create a task in the task realm; * if the provided service account is allowed to run in the task realm.

Assume the provided taskRealm, serviceAccount have been validated.

func (*Checker) CheckPoolPerm

func (chk *Checker) CheckPoolPerm(ctx context.Context, pool string, perm realms.Permission) CheckResult

CheckPoolPerm checks if the caller has a permission on a pool level.

Having a permission on a pool level means it applies for all tasks and bots in that pool. CheckPoolPerm implicitly calls CheckServerPerm.

func (*Checker) CheckServerPerm

func (chk *Checker) CheckServerPerm(ctx context.Context, perm realms.Permission) CheckResult

CheckServerPerm checks if the caller has a permission on a server level.

Having a permission on a server level means it applies to all pools, tasks and bots in this instance of Swarming. Server level permissions are defined via "auth { ... }" stanza with group names in the server's settings.cfg.

func (*Checker) CheckTaskPerm

func (chk *Checker) CheckTaskPerm(ctx context.Context, task Task, perm realms.Permission) CheckResult

CheckTaskPerm checks if the caller has a permission in a specific task.

Only accepts permissions targeting a single existing task: PermTasksGet and PermTasksCancel. Panics if asked to check any other permission.

It checks individual task ACL (based on task realm), as well as task's pool ACL. The idea is that the caller can either "own" the task or "own" the bot pool it was scheduled to run on. E.g. for a task to be visible, the caller either needs PermTasksGet in the task's realm, or PermPoolsListTasks in the bot pool realm. This function checks both.

func (*Checker) FilterPoolsByPerm

func (chk *Checker) FilterPoolsByPerm(ctx context.Context, pools []string, perm realms.Permission) ([]string, error)

FilterPoolsByPerm filters the list of pools keeping only ones in which the caller has the permission.

If the caller doesn't have the permission in any of the pools, returns nil slice and no error. Returns a gRPC status error if the check failed due to some internal issues.

type Task

type Task interface {
	// TaskAuthInfo returns properties of a task that affect who can access it.
	//
	// Any error here is treated as an internal server error.
	TaskAuthInfo(ctx context.Context) (*TaskAuthInfo, error)
}

Task can produce TaskAuthInfo on demand.

type TaskAuthInfo

type TaskAuthInfo struct {
	// TaskID is ID of the task. Only for error messages and logs!
	TaskID string
	// Realm is the realm the task belongs to, as "<project>:<realm>" string.
	Realm string
	// Pool is task's pool extracted from "pool" dimension.
	Pool string
	// BotID is a bot the task is targeting via "id" dimension or "" if none.
	BotID string
	// Submitter is whoever submitted the task.
	Submitter identity.Identity
}

TaskAuthInfo are properties of a task that affect who can access it.

Extracted either from TaskRequest or from TaskResultSummary. All fields except TaskID are optional. Most of them are unset for internal tasks like TerminateBot tasks.

Jump to

Keyboard shortcuts

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