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 ¶
- Variables
- func AuthenticationStreamInterceptor(authn Authenticator) grpc.StreamServerInterceptor
- func AuthenticationUnaryInterceptor(authn Authenticator) grpc.UnaryServerInterceptor
- func NewContext(ctx context.Context, actor *Actor) context.Context
- func RegisterAuthenticator(name string, f func() Authenticator)
- type Action
- type Actor
- type Authenticator
- type Authorizer
- type Config
- type Resource
- type Rule
Constants ¶
This section is empty.
Variables ¶
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 ¶
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 ¶
Actor represents the subject in the "subject action resource" of an authorization check. It has a name and many roles.
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 ¶
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 ¶
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.