Module: Legion::Rbac
- Extended by:
- Logging::Helper
- Defined in:
- lib/legion/rbac.rb,
lib/legion/rbac/role.rb,
lib/legion/rbac/store.rb,
lib/legion/rbac/routes.rb,
lib/legion/rbac/version.rb,
lib/legion/rbac/settings.rb,
lib/legion/rbac/principal.rb,
lib/legion/rbac/middleware.rb,
lib/legion/rbac/permission.rb,
lib/legion/rbac/team_scope.rb,
lib/legion/rbac/config_loader.rb,
lib/legion/rbac/policy_engine.rb,
lib/legion/rbac/capability_audit.rb,
lib/legion/rbac/group_role_mapper.rb,
lib/legion/rbac/capability_registry.rb,
lib/legion/rbac/entra_claims_mapper.rb,
lib/legion/rbac/kerberos_claims_mapper.rb
Defined Under Namespace
Modules: CapabilityAudit, CapabilityRegistry, ConfigLoader, EntraClaimsMapper, GroupRoleMapper, KerberosClaimsMapper, PolicyEngine, Routes, Settings, Store, TeamScope
Classes: AccessDenied, DenyRule, Middleware, Permission, Principal, Role
Constant Summary
collapse
- EMPTY_ROLE_INDEX =
{}.freeze
- VERSION =
'0.3.4'
Class Method Summary
collapse
Class Method Details
.audit_extension(extension_name:, source_path:, declared_capabilities: []) ⇒ Object
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
# File 'lib/legion/rbac.rb', line 135
def audit_extension(extension_name:, source_path:, declared_capabilities: [])
log.info("RBAC audit_extension extension=#{extension_name} source_path=#{source_path}")
result = CapabilityAudit.audit(
extension_name: extension_name,
source_path: source_path,
declared_capabilities: declared_capabilities
)
CapabilityRegistry.register(
extension_name,
capabilities: result.detected_capabilities,
audit_result: result
)
log.info(
"RBAC audit_extension result extension=#{extension_name} allowed=#{result.allowed} " \
"detected=#{result.detected_capabilities.size} undeclared=#{result.undeclared.size}"
)
result
end
|
.authorize!(principal:, action:, resource:) ⇒ Object
97
98
99
100
101
102
103
104
105
106
107
108
109
|
# File 'lib/legion/rbac.rb', line 97
def authorize!(principal:, action:, resource:, **)
return { allowed: true, reason: 'rbac disabled' } unless enabled?
result = PolicyEngine.evaluate(principal: principal, action: action, resource: resource, **)
log.info("RBAC authorize principal=#{principal.id} action=#{action} resource=#{resource} allowed=#{result[:allowed]}")
unless result[:allowed]
log.warn("RBAC authorize denied principal=#{principal.id} reason=#{result[:reason]}")
raise AccessDenied, result if enforcing?
end
result
end
|
.authorize_capability!(principal:, capability:, extension_name: nil) ⇒ Object
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
# File 'lib/legion/rbac.rb', line 154
def authorize_capability!(principal:, capability:, extension_name: nil)
result = PolicyEngine.evaluate_capability(
principal: principal,
capability: capability,
extension_name: extension_name
)
log.info(
"RBAC authorize_capability principal=#{principal.id} capability=#{capability} " \
"extension=#{extension_name} allowed=#{result[:allowed]}"
)
log.warn("RBAC authorize_capability denied principal=#{principal.id} reason=#{result[:reason]}") unless result[:allowed]
raise AccessDenied, result unless result[:allowed]
result
end
|
.authorize_execution!(principal:, runner_class:, function:, target_team: nil) ⇒ Object
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# File 'lib/legion/rbac.rb', line 111
def authorize_execution!(principal:, runner_class:, function:, target_team: nil, **)
return { allowed: true, reason: 'rbac disabled' } unless enabled?
runner_path = build_runner_path(runner_class, function)
log.info(
"RBAC authorize_execution principal=#{principal.id} runner=#{runner_path} " \
"target_team=#{target_team || principal.team || 'none'}"
)
result = PolicyEngine.evaluate_execution(
principal: principal,
action: :execute,
resource: runner_path,
target_team: target_team,
**
)
unless result[:allowed]
log.warn("RBAC authorize_execution denied principal=#{principal.id} reason=#{result[:reason]}")
raise AccessDenied, result if enforcing?
end
result
end
|
.enabled? ⇒ Boolean
76
77
78
79
80
|
# File 'lib/legion/rbac.rb', line 76
def enabled?
return true unless defined?(Legion::Settings)
Legion::Settings[:rbac]&.fetch(:enabled, true) != false
end
|
.enforcing? ⇒ Boolean
82
83
84
85
86
|
# File 'lib/legion/rbac.rb', line 82
def enforcing?
return true unless defined?(Legion::Settings)
Legion::Settings[:rbac]&.fetch(:enforce, true) != false
end
|
.events_enabled? ⇒ Boolean
88
89
90
91
92
93
94
95
|
# File 'lib/legion/rbac.rb', line 88
def events_enabled?
return false unless defined?(Legion::Events)
return false unless defined?(Legion::Settings)
Legion::Settings[:rbac]&.fetch(:emit_events, true) != false
rescue StandardError
false
end
|
.register_routes ⇒ Object
47
48
49
50
51
52
53
54
|
# File 'lib/legion/rbac.rb', line 47
def register_routes
return unless defined?(Legion::API) && Legion::API.respond_to?(:register_library_routes)
Legion::API.register_library_routes('rbac', Legion::Rbac::Routes)
log.debug 'Legion::Rbac routes registered with API'
rescue StandardError => e
handle_exception(e, level: :warn, operation: 'rbac.register_routes')
end
|
.role_index ⇒ Object
43
44
45
|
# File 'lib/legion/rbac.rb', line 43
def role_index
role_index_lock.synchronize { @role_index || EMPTY_ROLE_INDEX }
end
|
.setup ⇒ Object
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
# File 'lib/legion/rbac.rb', line 56
def setup
log.info 'Legion::Rbac setup started'
Legion::Settings.merge_settings(:rbac, Legion::Rbac::Settings.default)
unless enabled?
update_role_index(EMPTY_ROLE_INDEX, connected: false)
log.info 'Legion::Rbac disabled via settings'
return
end
loaded_roles = ConfigLoader.load_roles.freeze
update_role_index(loaded_roles, connected: true)
register_routes
log.info "Legion::Rbac connected roles=#{loaded_roles.size}"
end
|
.shutdown ⇒ Object
71
72
73
74
|
# File 'lib/legion/rbac.rb', line 71
def shutdown
update_role_index(EMPTY_ROLE_INDEX, connected: false)
log.info 'Legion::Rbac shutdown complete'
end
|