rbac

package
v0.18.1 Latest Latest
Warning

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

Go to latest
Published: Nov 22, 2023 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package rbac provides role-based access control for vtadmin API endpoints.

Functionality is split between two distinct components: the authenticator and the authorizer.

The authenticator is optional, and is responsible for extracting information from a request (gRPC or HTTP) to produce an Actor, which is added to the context by interceptors/middlewares and eventually checked by the authorizer.

The authorizer maintains a set of rules for each resource type, and, given a request context, action, resource, and cluster, checks its ruleset to see if the Actor in the context (set by some authenticator) has a rule allowing it to perform that <action, resource, cluster> tuple.

The design of package rbac is governed by the following principles:

1. Authentication is pluggable. Authorization is configurable.

VTAdmin will not be specific about how exactly you authenticate users for your setup. Instead, users can provide whatever implementation suits their needs that conforms to the expected Authenticator interface, and vtadmin will use that when setting up the interceptors/middlewares. Currently, authenticators may be registered at runtime via the rbac.RegisterAuthenticator method, or may be set as a Go plugin (built via `go build -buildmode=plugin`) by setting the authenticator name as a path ending in ".so" in the rbac config.

2. Permissions are additive. There is no concept of a negative permission (or revocation). To "revoke" a permission from a user or role, structure your rules such that they are never granted that permission.

3. Authentication is done at the gRPC/HTTP ingress boundaries.

4. Authorization is done at the API boundary. Individual clusters do not perform authorization checks, instead relying on the calling API method to perform that check before calling into the cluster.

5. Being unauthorized for an <action, resource> for a cluster does not fail the overall request. Instead, the action is simply not taken in that cluster, and is still taken in other clusters for which the actor is authorized.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnregisteredAuthenticationImpl is returned when an RBAC config
	// specifies an authenticator name that was not registered.
	ErrUnregisteredAuthenticationImpl = errors.New("unregistered Authenticator implementation")
)

Functions

func AuthenticationStreamInterceptor

func AuthenticationStreamInterceptor(authn Authenticator) grpc.StreamServerInterceptor

AuthenticationStreamInterceptor returns a grpc.StreamServerInterceptor that uses the given Authenticator create an Actor from the stream's context, which is then stored in the stream context for later use.

If the authenticator returns an error, the overall streaming rpc returns an UNAUTHENTICATED error.

func AuthenticationUnaryInterceptor

func AuthenticationUnaryInterceptor(authn Authenticator) grpc.UnaryServerInterceptor

AuthenticationUnaryInterceptor returns a grpc.UnaryServerInterceptor that uses the given Authenticator create an Actor from the request context, which is then stored in the request context for later use.

If the authenticator returns an error, the overall unary rpc returns an UNAUTHENTICATED error.

func NewContext

func NewContext(ctx context.Context, actor *Actor) context.Context

NewContext returns a context with the given actor stored in it. This is used to pass actor information from the authentication middleware and interceptors to the actual vtadmin api methods.

func RegisterAuthenticator

func RegisterAuthenticator(name string, f func() Authenticator)

RegisterAuthenticator registers an authenticator implementation by name. It is not safe for concurrent use.

Plugin-based authenticators are loaded separately, and need not call this function.

Types

type Action

type Action string

Action is an enum representing the possible actions that can be taken. Not every resource supports every possible action.

const (
	CreateAction Action = "create"
	DeleteAction Action = "delete"
	GetAction    Action = "get"
	PingAction   Action = "ping"
	PutAction    Action = "put"
	ReloadAction Action = "reload"

	EmergencyFailoverShardAction   Action = "emergency_failover_shard"
	PlannedFailoverShardAction     Action = "planned_failover_shard"
	TabletExternallyPromotedAction Action = "tablet_externally_promoted" // NOTE: even though "tablet" is in the name, this actually operates on the tablet's shard.

	ManageTabletReplicationAction        Action = "manage_tablet_replication" // Start/Stop Replication
	ManageTabletWritabilityAction        Action = "manage_tablet_writability" // SetRead{Only,Write}
	RefreshTabletReplicationSourceAction Action = "refresh_tablet_replication_source"
)

Action definitions.

type Actor

type Actor struct {
	Name  string   `json:"name"`
	Roles []string `json:"roles"`
}

Actor represents the subject in the "subject action resource" of an authorization check. It has a name and many roles.

func FromContext

func FromContext(ctx context.Context) (*Actor, bool)

FromContext extracts an actor from the context, if one exists.

type Authenticator

type Authenticator interface {
	// Authenticate returns an Actor given a context. This method is called
	// from the stream and unary grpc server interceptors, and are passed the
	// stream and request contexts, respectively.
	//
	// Returning an error from the authenticator will fail the request. To
	// denote an authenticated request, return (nil, nil) instead.
	Authenticate(ctx context.Context) (*Actor, error)
	// AuthenticateHTTP returns an actor given an http.Request.
	//
	// Returning an error from the authenticator will fail the request. To
	// denote an authenticated request, return (nil, nil) instead.
	AuthenticateHTTP(r *http.Request) (*Actor, error)
}

Authenticator defines the interface vtadmin authentication plugins must implement. Authenticators are installed at the grpc interceptor and http middleware layers.

type Authorizer

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

Authorizer contains a set of rules that determine which actors may take which actions on which resources in which clusters.

func NewAuthorizer

func NewAuthorizer(cfg *Config) (*Authorizer, error)

NewAuthorizer returns a new Authorizer based on the given Config, which typically comes from a marshaled yaml/json/toml file.

To get an authorizer that permits all access, including from unauthenticated actors, provide the following:

authz, err := rbac.NewAuthorizer(&rbac.Config{
	Rules: []*struct {
		Resource string
		Actions  []string
		Subjects []string
		Clusters []string
	}{
		{
			Resource: "*",
			Actions:  []string{"*"},
			Subjects: []string{"*"},
			Clusters: []string{"*"},
		},
	},
})

func (*Authorizer) IsAuthorized

func (authz *Authorizer) IsAuthorized(ctx context.Context, clusterID string, resource Resource, action Action) bool

IsAuthorized returns whether an Actor (from the context) is permitted to take the given action on the given resource in the given cluster.

type Config

type Config struct {
	Authenticator string
	Rules         []*struct {
		Resource string
		Actions  []string
		Subjects []string
		Clusters []string
	}
	// contains filtered or unexported fields
}

Config is the RBAC configuration representation. The public fields are populated by viper during LoadConfig, and the private fields are set during cfg.Reify. A config must be reified before first use.

func DefaultConfig added in v0.14.0

func DefaultConfig() *Config

DefaultConfig returns a default config that allows all actions on all resources It is mainly used in the case where users explicitly pass --no-rbac flag.

func LoadConfig

func LoadConfig(path string) (*Config, error)

LoadConfig reads the file at path into a Config struct, and then reifies the config so its autheticator and authorizer may be used. Errors during loading/parsing, or validation errors during reification are returned to the caller.

Any file format supported by viper is supported. Currently this is yaml, json or toml.

func (*Config) GetAuthenticator

func (c *Config) GetAuthenticator() Authenticator

GetAuthenticator returns the Authenticator implementation specified by the config. It returns nil if the Authenticator string field is the empty string, or if a call to Reify has not been made.

func (*Config) GetAuthorizer

func (c *Config) GetAuthorizer() *Authorizer

GetAuthorizer returns the Authorizer using the rules specified in the config. It returns nil if a call to Reify has not been made.

func (*Config) Reify

func (c *Config) Reify() error

Reify makes a config that was loaded from a file usable, by validating the rules and constructing its (optional) authenticator and authorizer. A config must be reified before first use. Calling Reify multiple times has no effect after the first call. Reify is called by LoadConfig, so a config loaded that way does not need to be manually reified.

type Resource

type Resource string

Resource is an enum representing all resources managed by vtadmin.

const (
	ClusterResource  Resource = "Cluster"
	TopologyResource Resource = "Topology"

	CellInfoResource   Resource = "CellInfo"
	CellsAliasResource Resource = "CellsAlias"
	KeyspaceResource   Resource = "Keyspace"
	ShardResource      Resource = "Shard"
	TabletResource     Resource = "Tablet"
	VTGateResource     Resource = "VTGate"
	VtctldResource     Resource = "Vtctld"

	VSchemaResource Resource = "VSchema"

	SrvKeyspaceResource Resource = "SrvKeyspace"
	SrvVSchemaResource  Resource = "SrvVSchema"

	BackupResource                   Resource = "Backup"
	SchemaResource                   Resource = "Schema"
	ShardReplicationPositionResource Resource = "ShardReplicationPosition"
	WorkflowResource                 Resource = "Workflow"

	VTExplainResource Resource = "VTExplain"

	TabletFullStatusResource Resource = "TabletFullStatus"
)

Resource definitions.

type Rule

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

Rule is a single rule governing access to a particular resource.

func (*Rule) Allows

func (r *Rule) Allows(clusterID string, action Action, actor *Actor) bool

Allows returns true if the actor is allowed to take the specified action in the specified cluster.

A nil actor signifies the unauthenticated state, and is only allowed access if the rule contains the wildcard ("*") subject.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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