Class: RackJwtAegis::Configuration
- Inherits:
-
Object
- Object
- RackJwtAegis::Configuration
- Defined in:
- lib/rack_jwt_aegis/configuration.rb
Overview
Configuration class for RackJwtAegis middleware
Manages all configuration options for JWT authentication, multi-tenant validation, RBAC authorization, and caching behavior.
Core JWT Settings collapse
-
#jwt_algorithm ⇒ String
The JWT algorithm to use for token verification.
-
#jwt_secret ⇒ String
The secret key used for JWT signature verification.
Feature Toggles collapse
-
#rbac_enabled ⇒ Boolean
Whether RBAC (Role-Based Access Control) is enabled.
-
#validate_pathname_slug ⇒ Boolean
Whether to validate pathname slug-based multi-tenancy.
-
#validate_subdomain ⇒ Boolean
Whether to validate subdomain-based multi-tenancy.
-
#validate_tenant_id ⇒ Boolean
Whether to validate tenant id from request header against the tenant id from JWT payload.
Multi-tenant Settings collapse
-
#pathname_slug_pattern ⇒ Regexp
The regular expression pattern to extract pathname slugs.
-
#payload_mapping ⇒ Hash
Mapping of standard payload keys to custom JWT claim names.
-
#tenant_id_header_name ⇒ String
The HTTP header name containing the tenant ID.
Path Management collapse
-
#skip_paths ⇒ Array<String, Regexp>
Array of paths that should skip JWT authentication.
Cache Configuration collapse
-
#cache_options ⇒ Hash
Options passed to the cache store adapter.
-
#cache_store ⇒ Symbol
The primary cache store adapter type.
-
#cache_write_enabled ⇒ Boolean
Whether the middleware can write to cache stores.
-
#permission_cache_options ⇒ Hash
Options for the permission cache store.
-
#permission_cache_store ⇒ Symbol
The permission cache store adapter type.
-
#rbac_cache_options ⇒ Hash
Options for the RBAC cache store.
-
#rbac_cache_store ⇒ Symbol
The RBAC cache store adapter type (separate from main cache).
-
#user_permissions_ttl ⇒ Integer
Time-to-live for user permissions cache in seconds.
Custom Validators collapse
-
#custom_payload_validator ⇒ Proc
Custom payload validation proc.
Response Customization collapse
-
#forbidden_response ⇒ Hash
Custom response for forbidden requests (403).
-
#unauthorized_response ⇒ Hash
Custom response for unauthorized requests (401).
Development Settings collapse
-
#debug_mode ⇒ Boolean
Whether debug mode is enabled for additional logging.
Instance Method Summary collapse
-
#cache_write_enabled? ⇒ Boolean
Check if cache write access is enabled.
-
#config_boolean?(value) ⇒ Boolean
private
Convert various falsy/truthy values to proper boolean for configuration.
-
#debug_mode? ⇒ Boolean
Check if debug mode is enabled.
-
#initialize(options = {}) ⇒ Configuration
constructor
Initialize a new Configuration instance.
-
#payload_key(standard_key) ⇒ Symbol
Get the mapped payload key for a standard key.
-
#rbac_enabled? ⇒ Boolean
Check if RBAC is enabled.
- #set_defaults ⇒ Object private
-
#skip_path?(path) ⇒ Boolean
Check if the given path should skip JWT authentication.
- #validate! ⇒ Object private
- #validate_cache_settings! ⇒ Object private
- #validate_jwt_settings! ⇒ Object private
- #validate_multi_tenant_settings! ⇒ Object private
-
#validate_pathname_slug? ⇒ Boolean
Check if pathname slug validation is enabled.
- #validate_payload_mapping! ⇒ Object private
-
#validate_subdomain? ⇒ Boolean
Check if subdomain validation is enabled.
-
#validate_tenant_id? ⇒ Boolean
Check if tenant id validation is enabled.
Constructor Details
#initialize(options = {}) ⇒ Configuration
Initialize a new Configuration instance
178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 178 def initialize( = {}) # Set defaults set_defaults # Merge user options .each do |key, value| raise ConfigurationError, "Unknown configuration option: #{key}" unless respond_to?("#{key}=") public_send("#{key}=", value) end # Validate configuration validate! end |
Instance Attribute Details
#cache_options ⇒ Hash
Options passed to the cache store adapter
98 99 100 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 98 def end |
#cache_store ⇒ Symbol
The primary cache store adapter type
94 95 96 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 94 def cache_store @cache_store end |
#cache_write_enabled ⇒ Boolean
Whether the middleware can write to cache stores
102 103 104 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 102 def cache_write_enabled @cache_write_enabled end |
#custom_payload_validator ⇒ Proc
Custom payload validation proc
132 133 134 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 132 def custom_payload_validator @custom_payload_validator end |
#debug_mode ⇒ Boolean
Whether debug mode is enabled for additional logging
156 157 158 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 156 def debug_mode @debug_mode end |
#forbidden_response ⇒ Hash
Custom response for forbidden requests (403)
148 149 150 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 148 def forbidden_response @forbidden_response end |
#jwt_algorithm ⇒ String
Supported algorithms: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512
The JWT algorithm to use for token verification
38 39 40 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 38 def jwt_algorithm @jwt_algorithm end |
#jwt_secret ⇒ String
This is required and must not be empty
The secret key used for JWT signature verification
33 34 35 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 33 def jwt_secret @jwt_secret end |
#pathname_slug_pattern ⇒ Regexp
The regular expression pattern to extract pathname slugs
70 71 72 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 70 def pathname_slug_pattern @pathname_slug_pattern end |
#payload_mapping ⇒ Hash
Mapping of standard payload keys to custom JWT claim names
76 77 78 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 76 def payload_mapping @payload_mapping end |
#permission_cache_options ⇒ Hash
Options for the permission cache store
118 119 120 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 118 def end |
#permission_cache_store ⇒ Symbol
The permission cache store adapter type
114 115 116 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 114 def end |
#rbac_cache_options ⇒ Hash
Options for the RBAC cache store
110 111 112 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 110 def end |
#rbac_cache_store ⇒ Symbol
The RBAC cache store adapter type (separate from main cache)
106 107 108 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 106 def rbac_cache_store @rbac_cache_store end |
#rbac_enabled ⇒ Boolean
Whether RBAC (Role-Based Access Control) is enabled
58 59 60 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 58 def rbac_enabled @rbac_enabled end |
#skip_paths ⇒ Array<String, Regexp>
Array of paths that should skip JWT authentication
86 87 88 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 86 def skip_paths @skip_paths end |
#tenant_id_header_name ⇒ String
The HTTP header name containing the tenant ID
66 67 68 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 66 def tenant_id_header_name @tenant_id_header_name end |
#unauthorized_response ⇒ Hash
Custom response for unauthorized requests (401)
142 143 144 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 142 def end |
#user_permissions_ttl ⇒ Integer
Time-to-live for user permissions cache in seconds
122 123 124 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 122 def end |
#validate_pathname_slug ⇒ Boolean
Whether to validate pathname slug-based multi-tenancy
50 51 52 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 50 def validate_pathname_slug @validate_pathname_slug end |
#validate_subdomain ⇒ Boolean
Whether to validate subdomain-based multi-tenancy
46 47 48 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 46 def validate_subdomain @validate_subdomain end |
#validate_tenant_id ⇒ Boolean
Whether to validate tenant id from request header against the tenant id from JWT payload
54 55 56 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 54 def validate_tenant_id @validate_tenant_id end |
Instance Method Details
#cache_write_enabled? ⇒ Boolean
Check if cache write access is enabled
225 226 227 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 225 def cache_write_enabled? config_boolean?(cache_write_enabled) end |
#config_boolean?(value) ⇒ Boolean (private)
Convert various falsy/truthy values to proper boolean for configuration
260 261 262 263 264 265 266 267 268 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 260 def config_boolean?(value) if (value.is_a?(Numeric) && value.zero?) || (value.is_a?(String) && ['false', '0', '', 'no'].include?(value.downcase.strip)) return false end # Everything else is truthy !!value end |
#debug_mode? ⇒ Boolean
Check if debug mode is enabled
219 220 221 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 219 def debug_mode? config_boolean?(debug_mode) end |
#payload_key(standard_key) ⇒ Symbol
Get the mapped payload key for a standard key
253 254 255 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 253 def payload_key(standard_key) payload_mapping&.fetch(standard_key, standard_key) || standard_key end |
#rbac_enabled? ⇒ Boolean
Check if RBAC is enabled
195 196 197 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 195 def rbac_enabled? config_boolean?(rbac_enabled) end |
#set_defaults ⇒ Object (private)
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 270 def set_defaults @jwt_algorithm = 'HS256' @validate_subdomain = false @validate_pathname_slug = false @validate_tenant_id = false @rbac_enabled = false @tenant_id_header_name = 'X-Tenant-Id' @pathname_slug_pattern = %r{^/api/v1/([^/]+)/} @skip_paths = [] @cache_write_enabled = false = 1800 # 30 minutes default @debug_mode = false @payload_mapping = { user_id: :user_id, tenant_id: :tenant_id, subdomain: :subdomain, pathname_slugs: :pathname_slugs, role_ids: :role_ids, } = { error: 'Authentication required' } @forbidden_response = { error: 'Access denied' } end |
#skip_path?(path) ⇒ Boolean
Check if the given path should skip JWT authentication
232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 232 def skip_path?(path) return false if skip_paths.nil? || skip_paths.empty? skip_paths.any? do |skip_path| case skip_path when String path == skip_path when Regexp skip_path.match?(path) else false end end end |
#validate! ⇒ Object (private)
293 294 295 296 297 298 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 293 def validate! validate_jwt_settings! validate_payload_mapping! validate_cache_settings! validate_multi_tenant_settings! end |
#validate_cache_settings! ⇒ Object (private)
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 327 def validate_cache_settings! return unless rbac_enabled? # Validate cache store configuration if cache_store && !cache_write_enabled? # Zero trust mode - separate caches required if rbac_cache_store.nil? raise ConfigurationError, 'rbac_cache_store is required when cache_write_enabled is false' end if .nil? = :memory # Default fallback end elsif cache_store.nil? && rbac_cache_store.nil? # Both cache stores are missing - at least one is required for RBAC raise ConfigurationError, 'cache_store or rbac_cache_store is required when RBAC is enabled' end # Set default fallback for permission_cache_store when rbac_cache_store is provided return unless !rbac_cache_store.nil? && .nil? = :memory # Default fallback end |
#validate_jwt_settings! ⇒ Object (private)
300 301 302 303 304 305 306 307 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 300 def validate_jwt_settings! raise ConfigurationError, 'jwt_secret is required' if jwt_secret.to_s.strip.empty? valid_algorithms = ['HS256', 'HS384', 'HS512', 'RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512'] return if valid_algorithms.include?(jwt_algorithm) raise ConfigurationError, "Unsupported JWT algorithm: #{jwt_algorithm}" end |
#validate_multi_tenant_settings! ⇒ Object (private)
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 351 def validate_multi_tenant_settings! if validate_subdomain? && !payload_mapping.key?(:subdomain) raise ConfigurationError, 'payload_mapping must include :subdomain when validate_subdomain is true' end if validate_tenant_id? error_msg = [] error_msg << 'payload_mapping must include :tenant_id' unless payload_mapping.key?(:tenant_id) error_msg << 'tenant_id_header_name is required' if tenant_id_header_name.to_s.strip.empty? raise ConfigurationError, "#{error_msg.join(' and ')} when validate_tenant_id is true" if error_msg.any? end return unless validate_pathname_slug? error_msg = [] error_msg << 'payload_mapping must include :pathname_slugs' unless payload_mapping.key?(:pathname_slugs) error_msg << 'pathname_slug_pattern is required' if pathname_slug_pattern.to_s.empty? raise ConfigurationError, "#{error_msg.join(' and ')} when validate_pathname_slug is true" if error_msg.any? end |
#validate_pathname_slug? ⇒ Boolean
Check if pathname slug validation is enabled
207 208 209 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 207 def validate_pathname_slug? config_boolean?(validate_pathname_slug) end |
#validate_payload_mapping! ⇒ Object (private)
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 309 def validate_payload_mapping! # Allow nil payload_mapping (will use defaults) return if payload_mapping.nil? raise ConfigurationError, 'payload_mapping must be a Hash' unless payload_mapping.is_a?(Hash) # Validate all values are symbols invalid_values = payload_mapping.reject { |_key, value| value.is_a?(Symbol) } return if invalid_values.empty? raise ConfigurationError, "payload_mapping values must be symbols, invalid: #{invalid_values.inspect}" # NOTE: We don't validate required keys because users may provide # partial mappings that are intended to override defaults. The payload_key method # handles missing keys by returning the standard key as fallback. # This includes RBAC keys - if :role_ids is not mapped, it falls back to 'role_ids'. end |
#validate_subdomain? ⇒ Boolean
Check if subdomain validation is enabled
201 202 203 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 201 def validate_subdomain? config_boolean?(validate_subdomain) end |
#validate_tenant_id? ⇒ Boolean
Check if tenant id validation is enabled
213 214 215 |
# File 'lib/rack_jwt_aegis/configuration.rb', line 213 def validate_tenant_id? config_boolean?(validate_tenant_id) end |