Documentation
¶
Overview ¶
Package authz provides a pluggable authorization interface for CoreForge applications.
The package defines a core Authorizer interface that applications use for access control, with multiple backend implementations available:
- simple: Role hierarchy and permission mappings (no external dependencies)
- spicedb: SpiceDB-based ReBAC (Zanzibar-style relationship-based access control)
Applications depend only on the Authorizer interface, allowing backends to be swapped without changing application code.
Index ¶
- Variables
- type Action
- type Authorizer
- type Decision
- type DecisionAuthorizer
- type ErrorResponse
- type FeatureAuthorizer
- type Middleware
- func (m *Middleware) RequireAction(resourceType ResourceType, action Action) func(http.Handler) http.Handler
- func (m *Middleware) RequireAllActions(resourceType ResourceType, actions ...Action) func(http.Handler) http.Handler
- func (m *Middleware) RequireAnyAction(resourceType ResourceType, actions ...Action) func(http.Handler) http.Handler
- func (m *Middleware) RequireResourceAction(extractor ResourceExtractor, action Action) func(http.Handler) http.Handler
- type OrgAuthorizer
- type OrgMiddleware
- type PlatformAuthorizer
- type PlatformMiddleware
- type Principal
- type PrincipalType
- type RelationshipSyncer
- type Resource
- type ResourceExtractor
- type ResourceType
- type RoleHierarchy
- type RolePermissions
- type SyncMode
Constants ¶
This section is empty.
Variables ¶
var ( ErrMissingResourceID = &middlewareError{msg: "missing resource ID"} ErrInvalidResourceID = &middlewareError{msg: "invalid resource ID"} )
Error types for resource extraction.
var DefaultRoleHierarchy = RoleHierarchy{
"owner": 100,
"admin": 80,
"editor": 60,
"member": 40,
"viewer": 20,
"guest": 10,
}
DefaultRoleHierarchy provides a common role hierarchy for multi-tenant SaaS apps.
var DefaultRolePermissions = RolePermissions{
"owner": {
"org.delete", "org.manage", "org.settings",
"member.invite", "member.remove", "member.role.change", "member.list",
"resource.create", "resource.read", "resource.update", "resource.delete",
},
"admin": {
"org.settings",
"member.invite", "member.remove", "member.role.change", "member.list",
"resource.create", "resource.read", "resource.update", "resource.delete",
},
"editor": {
"member.list",
"resource.create", "resource.read", "resource.update", "resource.delete",
},
"member": {
"member.list",
"resource.create", "resource.read", "resource.update",
},
"viewer": {
"resource.read",
},
}
DefaultRolePermissions provides a common permission mapping.
Functions ¶
This section is empty.
Types ¶
type Authorizer ¶
type Authorizer interface {
// Can checks if a principal can perform an action on a resource.
// This is the primary authorization method.
Can(ctx context.Context, principal Principal, action Action, resource Resource) (bool, error)
// CanAll checks if a principal can perform all specified actions on a resource.
CanAll(ctx context.Context, principal Principal, actions []Action, resource Resource) (bool, error)
// CanAny checks if a principal can perform any of the specified actions on a resource.
CanAny(ctx context.Context, principal Principal, actions []Action, resource Resource) (bool, error)
// Filter returns only the resources the principal can access with the given action.
Filter(ctx context.Context, principal Principal, action Action, resources []Resource) ([]Resource, error)
}
Authorizer defines the core authorization interface. All authorization backends must implement this interface.
type Decision ¶
type Decision struct {
// Allowed indicates whether the action is permitted.
Allowed bool
// Reason provides context for the decision (useful for debugging/auditing).
Reason string
// PolicyID identifies which policy made the decision (if applicable).
PolicyID string
}
Decision represents an authorization decision with optional explanation.
type DecisionAuthorizer ¶
type DecisionAuthorizer interface {
Authorizer
// Decide returns a detailed authorization decision.
Decide(ctx context.Context, principal Principal, action Action, resource Resource) (Decision, error)
}
DecisionAuthorizer provides detailed authorization decisions.
type ErrorResponse ¶
ErrorResponse represents an error response body.
type FeatureAuthorizer ¶
type FeatureAuthorizer interface {
Authorizer
// CanWithFeature checks both permission and feature flag.
CanWithFeature(ctx context.Context, principal Principal, action Action, resource Resource, feature string) (bool, error)
}
FeatureAuthorizer extends authorization with feature flag awareness.
type Middleware ¶
type Middleware struct {
// contains filtered or unexported fields
}
Middleware wraps an Authorizer for HTTP middleware use.
func NewMiddleware ¶
func NewMiddleware(authorizer Authorizer) *Middleware
NewMiddleware creates a new authorization middleware.
func (*Middleware) RequireAction ¶
func (m *Middleware) RequireAction(resourceType ResourceType, action Action) func(http.Handler) http.Handler
RequireAction returns middleware that checks if the user can perform an action on a resource type.
func (*Middleware) RequireAllActions ¶
func (m *Middleware) RequireAllActions(resourceType ResourceType, actions ...Action) func(http.Handler) http.Handler
RequireAllActions returns middleware that checks if the user can perform all of the specified actions on a resource type.
func (*Middleware) RequireAnyAction ¶
func (m *Middleware) RequireAnyAction(resourceType ResourceType, actions ...Action) func(http.Handler) http.Handler
RequireAnyAction returns middleware that checks if the user can perform any of the specified actions on a resource type.
func (*Middleware) RequireResourceAction ¶
func (m *Middleware) RequireResourceAction(extractor ResourceExtractor, action Action) func(http.Handler) http.Handler
RequireResourceAction returns middleware that extracts a resource from the request and checks if the user can perform an action on it.
type OrgAuthorizer ¶
type OrgAuthorizer interface {
Authorizer
// CanForOrg checks permission scoped to a specific organization.
CanForOrg(ctx context.Context, principal Principal, orgID uuid.UUID, action Action, resource Resource) (bool, error)
// GetRole returns the principal's role in an organization.
GetRole(ctx context.Context, principal Principal, orgID uuid.UUID) (string, error)
// IsMember checks if a principal is a member of an organization.
IsMember(ctx context.Context, principal Principal, orgID uuid.UUID) (bool, error)
}
OrgAuthorizer extends Authorizer with organization-scoped methods. Use this for multi-tenant SaaS applications.
type OrgMiddleware ¶
type OrgMiddleware struct {
// contains filtered or unexported fields
}
OrgMiddleware wraps an OrgAuthorizer for organization-scoped middleware.
func NewOrgMiddleware ¶
func NewOrgMiddleware(authorizer OrgAuthorizer) *OrgMiddleware
NewOrgMiddleware creates a new organization-scoped authorization middleware.
func (*OrgMiddleware) RequireMembership ¶
func (m *OrgMiddleware) RequireMembership() func(http.Handler) http.Handler
RequireMembership returns middleware that requires the user to be a member of the current organization.
func (*OrgMiddleware) RequireRole ¶
func (m *OrgMiddleware) RequireRole(role string, hierarchy RoleHierarchy) func(http.Handler) http.Handler
RequireRole returns middleware that requires a specific role in the current organization.
type PlatformAuthorizer ¶
type PlatformAuthorizer interface {
OrgAuthorizer
// IsPlatformAdmin checks if a principal has platform-wide admin access.
IsPlatformAdmin(ctx context.Context, principal Principal) (bool, error)
}
PlatformAuthorizer extends OrgAuthorizer with platform-level checks.
type PlatformMiddleware ¶
type PlatformMiddleware struct {
// contains filtered or unexported fields
}
PlatformMiddleware wraps a PlatformAuthorizer for platform-level middleware.
func NewPlatformMiddleware ¶
func NewPlatformMiddleware(authorizer PlatformAuthorizer) *PlatformMiddleware
NewPlatformMiddleware creates a new platform-level authorization middleware.
func (*PlatformMiddleware) RequirePlatformAdmin ¶
func (m *PlatformMiddleware) RequirePlatformAdmin() func(http.Handler) http.Handler
RequirePlatformAdmin returns middleware that requires platform admin status.
type Principal ¶
type Principal struct {
// ID is the unique identifier of the principal.
ID uuid.UUID
// Type identifies the kind of principal (user, service, api_key, etc.).
Type PrincipalType
// Attributes contains additional principal attributes for ABAC.
Attributes map[string]any
}
Principal represents an entity requesting access (user, service, etc.).
func NewServicePrincipal ¶
NewServicePrincipal creates a Principal for a service.
func NewUserPrincipal ¶
NewUserPrincipal creates a Principal for a user.
func NewUserPrincipalWithAttrs ¶
NewUserPrincipalWithAttrs creates a Principal for a user with attributes.
type PrincipalType ¶
type PrincipalType string
PrincipalType identifies the kind of principal.
const ( PrincipalTypeUser PrincipalType = "user" PrincipalTypeService PrincipalType = "service" PrincipalTypeAPIKey PrincipalType = "api_key" PrincipalTypeSystem PrincipalType = "system" )
type RelationshipSyncer ¶ added in v0.2.0
type RelationshipSyncer interface {
// AddOrgMembership registers a principal's membership in an organization with a specific role.
// Called when a user joins an organization or is invited.
AddOrgMembership(ctx context.Context, principalID, orgID uuid.UUID, role string) error
// RemoveOrgMembership removes a principal's membership from an organization.
// Called when a user leaves or is removed from an organization.
RemoveOrgMembership(ctx context.Context, principalID, orgID uuid.UUID, role string) error
// UpdateOrgMembership changes a principal's role in an organization.
// Implemented as remove old role + add new role atomically.
UpdateOrgMembership(ctx context.Context, principalID, orgID uuid.UUID, oldRole, newRole string) error
// RegisterPrincipal creates a principal entity in the authorization system.
// Called when a new user, application, agent, or service principal is created.
RegisterPrincipal(ctx context.Context, principalID uuid.UUID) error
// UnregisterPrincipal removes a principal and all its relationships from the authorization system.
// Called when a principal is deleted.
UnregisterPrincipal(ctx context.Context, principalID uuid.UUID) error
// RegisterOrganization creates an organization in the authorization system with an initial owner.
// Called when a new organization is created.
RegisterOrganization(ctx context.Context, orgID, ownerID uuid.UUID) error
// UnregisterOrganization removes an organization and all its relationships from the authorization system.
// Called when an organization is deleted.
UnregisterOrganization(ctx context.Context, orgID uuid.UUID) error
// SetPlatformAdmin grants or revokes platform admin privileges for a principal.
SetPlatformAdmin(ctx context.Context, principalID uuid.UUID, isAdmin bool) error
}
RelationshipSyncer defines the interface for syncing identity changes to an authorization backend. Identity services use this interface to keep the authorization layer in sync with membership and principal lifecycle events.
type Resource ¶
type Resource struct {
// Type identifies the kind of resource (course, organization, etc.).
Type ResourceType
// ID is the unique identifier of the resource (nil for type-level checks).
ID *uuid.UUID
// OwnerID is the owner of the resource (for ownership-based access).
OwnerID *uuid.UUID
// OrgID is the organization this resource belongs to.
OrgID *uuid.UUID
// Attributes contains additional resource attributes for ABAC.
Attributes map[string]any
}
Resource represents something being accessed.
func NewOrgResource ¶
func NewOrgResource(resourceType ResourceType, orgID uuid.UUID) Resource
NewOrgResource creates a Resource scoped to an organization.
func NewOwnedResource ¶
func NewOwnedResource(resourceType ResourceType, id, ownerID uuid.UUID) Resource
NewOwnedResource creates a Resource with an owner.
func NewResource ¶
func NewResource(resourceType ResourceType) Resource
NewResource creates a Resource with the given type.
func NewResourceWithID ¶
func NewResourceWithID(resourceType ResourceType, id uuid.UUID) Resource
NewResourceWithID creates a Resource with type and ID.
type ResourceExtractor ¶
ResourceExtractor is a function that extracts a resource from an HTTP request. Use this for routes that include resource IDs in the path.
func WithResourceID ¶
func WithResourceID(resourceType ResourceType, pathParamName string, getParam func(r *http.Request, key string) string) ResourceExtractor
WithResourceID creates a ResourceExtractor that parses a resource ID from a URL path parameter.
type ResourceType ¶
type ResourceType string
ResourceType identifies the kind of resource.
const ( ResourceTypeOrganization ResourceType = "organization" ResourceTypeMember ResourceType = "member" ResourceTypeUser ResourceType = "user" )
Common resource type constants.
type RoleHierarchy ¶
RoleHierarchy defines a hierarchy of roles where higher values indicate more access. Roles with higher hierarchy values can access resources requiring lower levels.
func (RoleHierarchy) CanAccess ¶
func (h RoleHierarchy) CanAccess(userRole, requiredRole string) bool
CanAccess checks if a user role can access resources requiring the target role. Higher hierarchy values can access lower ones.
func (RoleHierarchy) IsHigherOrEqual ¶
func (h RoleHierarchy) IsHigherOrEqual(role1, role2 string) bool
IsHigherOrEqual checks if role1 is higher than or equal to role2.
func (RoleHierarchy) Level ¶
func (h RoleHierarchy) Level(role string) int
Level returns the hierarchy level for a role, or 0 if not found.
type RolePermissions ¶
RolePermissions maps roles to their granted permissions.
func (RolePermissions) GetPermissions ¶
func (rp RolePermissions) GetPermissions(role string) []string
GetPermissions returns all permissions for a role.
func (RolePermissions) HasAllPermissions ¶
func (rp RolePermissions) HasAllPermissions(role string, permissions []string) bool
HasAllPermissions checks if a role has all of the specified permissions.
func (RolePermissions) HasAnyPermission ¶
func (rp RolePermissions) HasAnyPermission(role string, permissions []string) bool
HasAnyPermission checks if a role has any of the specified permissions.
func (RolePermissions) HasPermission ¶
func (rp RolePermissions) HasPermission(role, permission string) bool
HasPermission checks if a role has a specific permission.
type SyncMode ¶ added in v0.2.0
type SyncMode string
SyncMode determines how sync failures are handled.
const ( // SyncModeStrict fails the operation if authorization sync fails. // Use when authorization must be consistent with identity. SyncModeStrict SyncMode = "strict" // SyncModeEventual logs sync failures but allows the operation to succeed. // Use when eventual consistency is acceptable and a retry mechanism exists. SyncModeEventual SyncMode = "eventual" )
Directories
¶
| Path | Synopsis |
|---|---|
|
Package noop provides a no-operation authorization syncer for deployments that don't require authorization backend synchronization.
|
Package noop provides a no-operation authorization syncer for deployments that don't require authorization backend synchronization. |
|
Package providertest provides conformance tests for authz.Provider implementations.
|
Package providertest provides conformance tests for authz.Provider implementations. |
|
Package simple provides a simple role-based authorization provider.
|
Package simple provides a simple role-based authorization provider. |
|
Package spicedb provides SpiceDB-based authorization for CoreForge.
|
Package spicedb provides SpiceDB-based authorization for CoreForge. |