Documentation
¶
Overview ¶
Package authz provides a plugin for implementing basic access controls. It uses the service descriptor to define the Authz, which is then enforced by a GRPC interceptor.
Authz Policies are defined in terms of roles and actions, both of which are application defined strings. For example, an "editor" role might be allowed to perform the "document.edit" action.
Roles are context dependent and determined by application provided functions called "Role Describers". Role Describers return a list of roles for a given authenticated identity and object. For example, a user may have the role "owner" for a specific document and "admin" for their workspace.
Role Describers can chose to restrict whether a role is granted, based on other attributes. For example, an "admin" role could only be granted if the request comes from a specific IP address.
Role Describers can also be configured to accept a `domain` from the request. This is optional and is intended to simplify the implementation of mutlti-tenant systems or systems where a user might be part of multiple workspaces or groups, each with different permissions.
To map an incoming request to a resource, the Authz plugin uses "Object Fetchers". Fetchers can be registered against a key, which can be an arbitrary string, or derived from `reflect.Type`. The fetcher is then called with the value of a request parameter, per the field option.
RPCs can be configured with a default effect of Allow. For example, a page might be configured to allow all users to view it, except those on mobile devices (this is a bit of a tenuous example, but you get the idea).
Index ¶
- Constants
- Variables
- func FieldOptions(req proto.Message) (any, string, error)
- func MethodOptions(info *grpc.UnaryServerInfo) (objectKey string, action Action, defaultEffect Effect)
- type Action
- type AuthorizeParams
- type AuthzOption
- type AuthzPlugin
- func (ap *AuthzPlugin) Authorize(ctx context.Context, cfg AuthorizeParams) error
- func (ap *AuthzPlugin) DebugHandler(resp http.ResponseWriter, req *http.Request)
- func (ap *AuthzPlugin) DefinePolicy(effect Effect, role Role, action Action)
- func (ap *AuthzPlugin) Deps() []string
- func (ap *AuthzPlugin) DetermineEffect(action Action, roles []Role, defaultEffect Effect) Effect
- func (ap *AuthzPlugin) Interceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, ...) (resp interface{}, err error)
- func (ap *AuthzPlugin) Name() string
- func (ap *AuthzPlugin) RegisterObjectFetcher(objectKey string, fn ObjectFetcher)
- func (ap *AuthzPlugin) RegisterRoleDescriber(objectKey string, fn RoleDescriber)
- func (ap *AuthzPlugin) RoleHierarchy(role Role) []Role
- func (ap *AuthzPlugin) RoleTree() map[Role][]Role
- func (ap *AuthzPlugin) ServerOptions() []prefab.ServerOption
- func (ap *AuthzPlugin) SetRoleHierarchy(roles ...Role)
- type Domain
- type Effect
- type ObjectFetcher
- type Role
- type RoleDescriber
Constants ¶
const PluginName = "authz"
Constant name for identifying the core Authz plugin.
Variables ¶
var ( // optional string action = 50011; E_Action = &file_plugins_authz_authz_proto_extTypes[0] // optional string resource = 50012; E_Resource = &file_plugins_authz_authz_proto_extTypes[1] // optional string default_effect = 50013; E_DefaultEffect = &file_plugins_authz_authz_proto_extTypes[2] )
Extension fields to descriptorpb.MethodOptions.
var ( // optional bool id = 50021; E_Id = &file_plugins_authz_authz_proto_extTypes[3] // optional bool domain = 50022; E_Domain = &file_plugins_authz_authz_proto_extTypes[4] )
Extension fields to descriptorpb.FieldOptions.
var ( ErrPermissionDenied = errors.Codef(codes.PermissionDenied, "you are not authorized to perform this action") ErrUnauthenticated = errors.Codef(codes.Unauthenticated, "the requested action requires authentication") )
var File_plugins_authz_authz_proto protoreflect.FileDescriptor
Functions ¶
func FieldOptions ¶
FieldOptions returns proto fields that are tagged with Authz related options.
func MethodOptions ¶
func MethodOptions(info *grpc.UnaryServerInfo) (objectKey string, action Action, defaultEffect Effect)
MethodOptions returns Authz related method options from the method descriptor associated with the given info.
Types ¶
type AuthorizeParams ¶
type AuthorizeParams struct {
ObjectKey string
ObjectID any
Domain string
Action Action
DefaultEffect Effect
Info string
}
Parameters for the Authorize method.
type AuthzOption ¶
type AuthzOption func(*AuthzPlugin)
Configuration options for the Authz Plugin.
func WithObjectFetcher ¶
func WithObjectFetcher(objectKey string, fn ObjectFetcher) AuthzOption
WithRoleDescriber adds a role describer to the plugin.
func WithPolicy ¶
func WithPolicy(effect Effect, role Role, action Action) AuthzOption
WithPolicy adds an Authz policy to the plugin.
func WithRoleDescriber ¶
func WithRoleDescriber(objectKey string, fn RoleDescriber) AuthzOption
WithRoleDescriber adds a role describer to the plugin.
func WithRoleHierarchy ¶
func WithRoleHierarchy(roles ...Role) AuthzOption
WithRoleHierarchy configures the plugin with a hierarchy of roles.
The first role is the most powerful, and the last role has no hierarchy from a single call. Multiple calls can be used to define a tree hierarchies.
Example:
WithRoleHierarchy("owner", "admin", "editor", "viewer", "member")
WithRoleHierarchy("suggester", "viewer")
In this example, the "owner" role is an "admin", "editor", "viewer", and "member". An "admin" is an "editor", "viewer", and "member". An "editor" is also a "viewer" and a "member".
A "suggester" is a "viewer" and a "member", since the ancestry of "viewer" was defined by the previous call.
type AuthzPlugin ¶
type AuthzPlugin struct {
// contains filtered or unexported fields
}
AuthzPlugin provides functionality for authorizing requests and access to resources.
func (*AuthzPlugin) Authorize ¶
func (ap *AuthzPlugin) Authorize(ctx context.Context, cfg AuthorizeParams) error
Authorize takes the configuration and verifies that the caller is authorized to perform the action on the object.
func (*AuthzPlugin) DebugHandler ¶
func (ap *AuthzPlugin) DebugHandler(resp http.ResponseWriter, req *http.Request)
DebugHandler renders information about registered policies and roles.
func (*AuthzPlugin) DefinePolicy ¶
func (ap *AuthzPlugin) DefinePolicy(effect Effect, role Role, action Action)
DefinePolicy defines an policy which allows/denies the given role to perform the action.
func (*AuthzPlugin) DetermineEffect ¶
func (ap *AuthzPlugin) DetermineEffect(action Action, roles []Role, defaultEffect Effect) Effect
DetermineEffect checks to see if there are any policies which explicitly apply to this role and action. If there are, then all roles must explicitly revert the default effect.
In otherwords, if an RPC is default deny and two roles explicitly match a policy, then both roles must allow access. This can be used to create exclusion groups: e.g. all admins, except nyc-admins.
func (*AuthzPlugin) Interceptor ¶
func (ap *AuthzPlugin) Interceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error)
Interceptor that enforces authorization policies configured on the GRPC service descriptors.
This interceptor: 1. Uses method options to get object key and action. 2. Uses proto field options to get an object id and optionally domain. 3. Fetches the object based on the object key and id (ObjectFetcher). 4. Gets the user's role relative to the object (RoleDescriber). 5. Checks if the role can perform the action on the object.
func (*AuthzPlugin) RegisterObjectFetcher ¶
func (ap *AuthzPlugin) RegisterObjectFetcher(objectKey string, fn ObjectFetcher)
RegisterObjectFetcher registers a function for fetching an object based on a request parameter that was specified in the proto descriptor. '*' can be used as a wildcard to match any key which doesn't have a more specific fetcher.
func (*AuthzPlugin) RegisterRoleDescriber ¶
func (ap *AuthzPlugin) RegisterRoleDescriber(objectKey string, fn RoleDescriber)
RegisterRoleDescriber registers a function for describing a role relative to an object. '*' can be used as a wildcard to match any key which doesn't have a more specific describer.
func (*AuthzPlugin) RoleHierarchy ¶
func (ap *AuthzPlugin) RoleHierarchy(role Role) []Role
RoleHierarchy returns the ancestry of a single role.
func (*AuthzPlugin) RoleTree ¶
func (ap *AuthzPlugin) RoleTree() map[Role][]Role
RoleTree returns the hierarchy of roles in tree form.
func (*AuthzPlugin) ServerOptions ¶
func (ap *AuthzPlugin) ServerOptions() []prefab.ServerOption
From prefab.OptionProvider, registers an additional interceptor.
func (*AuthzPlugin) SetRoleHierarchy ¶
func (ap *AuthzPlugin) SetRoleHierarchy(roles ...Role)
SetRoleHierarchy sets the hierarchy of roles.
type ObjectFetcher ¶
Fetches an object based on a request parameter.