Documentation
¶
Index ¶
Constants ¶
const ( // DefaultConfigPath is the default config path value (empty string). // When passed to ResolveRBACConfigPath, it will try default paths: configs/rbac.json, configs/rbac.yaml, configs/rbac.yml. DefaultConfigPath = "" )
Variables ¶
var ( // ErrAccessDenied is returned when a user doesn't have required role/permission. ErrAccessDenied = errors.New("forbidden: access denied") // ErrRoleNotFound is returned when role cannot be extracted from request. ErrRoleNotFound = errors.New("unauthorized: role not found") )
var ( // ErrEndpointMissingPermissions is returned when an endpoint doesn't specify requiredPermissions and is not public. ErrEndpointMissingPermissions = errors.New("endpoint must specify requiredPermissions (or be public)") )
Functions ¶
func Middleware ¶
Middleware creates an HTTP middleware function that enforces RBAC authorization. It extracts the user's role and checks if the role is allowed for the requested route.
func ResolveRBACConfigPath ¶
ResolveRBACConfigPath resolves the RBAC config file path. If configFile is empty, tries default paths in order: configs/rbac.json, configs/rbac.yaml, configs/rbac.yml.
Types ¶
type AuditLog ¶
type AuditLog struct {
CorrelationID string `json:"correlation_id,omitempty"`
Method string `json:"method,omitempty"`
Route string `json:"route,omitempty"`
Status string `json:"status,omitempty"`
Role string `json:"role,omitempty"`
}
AuditLog represents a structured log entry for RBAC authorization decisions. It follows the same pattern as HTTP RequestLog for consistency.
func (*AuditLog) PrettyPrint ¶
PrettyPrint formats the RBAC audit log for terminal output, matching HTTP log format.
type Config ¶
type Config struct {
// Roles defines all roles with their permissions and inheritance
// This is the unified way to define roles (replaces RouteWithPermissions, RoleHierarchy)
Roles []RoleDefinition `json:"roles,omitempty" yaml:"roles,omitempty"`
// Endpoints maps API endpoints to authorization requirements
// This is the unified way to define endpoint access (replaces RouteWithPermissions, OverRides)
Endpoints []EndpointMapping `json:"endpoints,omitempty" yaml:"endpoints,omitempty"`
// RoleHeader specifies the HTTP header key for header-based role extraction
// Example: "X-User-Role"
// If set, role is extracted from this header
RoleHeader string `json:"roleHeader,omitempty" yaml:"roleHeader,omitempty"`
// JWTClaimPath specifies the JWT claim path for JWT-based role extraction
// Examples: "role", "roles[0]", "permissions.role"
// If set, role is extracted from JWT claims in request context
JWTClaimPath string `json:"jwtClaimPath,omitempty" yaml:"jwtClaimPath,omitempty"`
// ErrorHandler is called when authorization fails
// If nil, default error response is sent
ErrorHandler func(w http.ResponseWriter, r *http.Request, role, route string, err error)
// Logger is the logger instance for audit logging
// Set automatically by EnableRBAC - users don't need to configure this
// Audit logging is automatically performed when RBAC is enabled
Logger datasource.Logger `json:"-" yaml:"-"`
// Metrics is the metrics instance for RBAC metrics
// Set automatically by EnableRBAC
Metrics infra.Metrics `json:"-" yaml:"-"`
// Tracer is the tracer instance for RBAC tracing
// Set automatically by EnableRBAC
Tracer trace.Tracer `json:"-" yaml:"-"`
// contains filtered or unexported fields
}
Config represents the unified RBAC configuration structure.
func LoadPermissions ¶
func LoadPermissions(path string, logger datasource.Logger, metrics infra.Metrics, tracer trace.Tracer) (*Config, error)
LoadPermissions loads RBAC configuration from a JSON or YAML file. The file format is automatically detected based on the file extension. Supported formats: .json, .yaml, .yml. Dependencies (logger, metrics, tracer) are optional and can be set after loading.
func (*Config) GetEndpointPermission ¶
GetEndpointPermission returns the required permissions for an endpoint. Returns empty slice if endpoint is public or not found. Returns all required permissions (user needs ANY of them - OR logic). Config is read-only after initialization, so no mutex is needed.
func (*Config) GetRolePermissions ¶
GetRolePermissions returns the permissions for a role. Config is read-only after initialization, so no mutex is needed.
type EndpointMapping ¶
type EndpointMapping struct {
// Path is the route path pattern using URL parameter syntax.
// Examples:
// - "/api/users" (exact match)
// - "/api/users/{id}" (matches any single segment)
// - "/api/users/{id:[0-9]+}" (matches numeric IDs only)
// - "/api/{resource}" (single-level wildcard: matches /api/users, /api/posts)
// - "/api/{path:.*}" (multi-level wildcard: matches /api/users/123, /api/posts/comments)
// - "/api/{category}/posts" (middle variable: matches /api/tech/posts, /api/news/posts)
// Only URL parameter patterns are supported. Wildcards (/*) and regex (^...$) are not supported.
Path string `json:"path,omitempty" yaml:"path,omitempty"`
// Methods is a list of HTTP methods (GET, POST, PUT, DELETE, PATCH, etc.)
// Use ["*"] to match all methods
// Example: ["GET", "POST"]
Methods []string `json:"methods" yaml:"methods"`
// RequiredPermissions is a list of permissions required to access this endpoint (format: "resource:action")
// User needs to have ANY of these permissions (OR logic)
// Example: ["users:read"] or ["users:read", "users:admin"]
// This is checked against the role's permissions
// REQUIRED: All endpoints must specify requiredPermissions (except public endpoints)
RequiredPermissions []string `json:"requiredPermissions,omitempty" yaml:"requiredPermissions,omitempty"`
// Public indicates this endpoint is publicly accessible (bypasses authorization)
// Example: true for /health, /metrics endpoints
Public bool `json:"public,omitempty" yaml:"public,omitempty"`
}
EndpointMapping defines authorization requirements for an API endpoint. Pure config-based: only route&method->permission mapping is supported. No direct route to role mapping - all authorization is permission-based.
type RoleDefinition ¶
type RoleDefinition struct {
// Name is the role name (required)
Name string `json:"name" yaml:"name"`
// Permissions is a list of permissions for this role (format: "resource:action")
// Example: ["users:read", "users:write"]
Permissions []string `json:"permissions,omitempty" yaml:"permissions,omitempty"`
// InheritsFrom lists roles this role inherits permissions from
// Example: ["viewer"] - editor inherits all viewer permissions
InheritsFrom []string `json:"inheritsFrom,omitempty" yaml:"inheritsFrom,omitempty"`
}
RoleDefinition defines a role with its permissions and inheritance. Pure config-based: only role->permission mapping is supported.