Class: RackJwtAegis::Configuration

Inherits:
Object
  • Object
show all
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.

Examples:

Basic configuration

config = Configuration.new(jwt_secret: 'your-secret')

Full configuration

config = Configuration.new(
  jwt_secret: ENV['JWT_SECRET'],
  jwt_algorithm: 'HS256',
  validate_subdomain: true,
  validate_pathname_slug: true,
  rbac_enabled: true,
  skip_paths: ['/health', '/api/public/*'],
  debug_mode: Rails.env.development?
)

Author:

  • Ken Camajalan Demanawa

Since:

  • 0.1.0

Core JWT Settings collapse

Feature Toggles collapse

Multi-tenant Settings collapse

Path Management collapse

Cache Configuration collapse

Custom Validators collapse

Response Customization collapse

Development Settings collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Configuration

Initialize a new Configuration instance

Parameters:

  • options (Hash) (defaults to: {})

    configuration options

Options Hash (options):

  • :jwt_secret (String) — default: required

    JWT secret key for signature verification

  • :jwt_algorithm (String) — default: 'HS256'

    JWT algorithm to use

  • :validate_subdomain (Boolean) — default: false

    enable subdomain validation

  • :validate_pathname_slug (Boolean) — default: false

    enable pathname slug validation

  • :rbac_enabled (Boolean) — default: false

    enable RBAC authorization

  • :tenant_id_header_name (String) — default: 'X-Tenant-Id'

    tenant ID header name

  • :pathname_slug_pattern (Regexp)

    default pattern for pathname slugs

  • :payload_mapping (Hash)

    mapping of JWT claim names

  • :skip_paths (Array<String, Regexp>) — default: []

    legacy paths to skip authentication

  • :skip_routes (Array<String, Regexp, Hash>) — default: []

    routes to skip authentication

  • :rbac_cache_store (Symbol)

    cache adapter type

  • :rbac_cache_store_options (Hash)

    cache configuration options

  • :permissions_cache_store (Symbol)

    cache adapter type

  • :permissions_cache_store_options (Hash)

    cache configuration options

  • :cached_permissions_ttl (Integer) — default: 1800

    user permissions cache TTL in seconds

  • :debug_mode (Boolean) — default: false

    enable debug logging

Raises:

Since:

  • 0.1.0



194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/rack_jwt_aegis/configuration.rb', line 194

def initialize(options = {})
  # Set defaults
  set_defaults

  # Merge user options
  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

#cached_permissions_ttlInteger

Time-to-live for user permissions cache in seconds

Returns:

  • (Integer)

    TTL in seconds (default: 1800 - 30 minutes)

Since:

  • 0.1.0



136
137
138
# File 'lib/rack_jwt_aegis/configuration.rb', line 136

def cached_permissions_ttl
  @cached_permissions_ttl
end

#circuit_breaker_cooldown_secondsInteger

Seconds to fail fast before allowing another request attempt

Returns:

  • (Integer)

    cooldown seconds

Since:

  • 0.1.0



76
77
78
# File 'lib/rack_jwt_aegis/configuration.rb', line 76

def circuit_breaker_cooldown_seconds
  @circuit_breaker_cooldown_seconds
end

#circuit_breaker_enabledBoolean

Whether unexpected errors should trip a fail-fast circuit breaker

Returns:

  • (Boolean)

    true if circuit breaker is enabled

Since:

  • 0.1.0



68
69
70
# File 'lib/rack_jwt_aegis/configuration.rb', line 68

def circuit_breaker_enabled
  @circuit_breaker_enabled
end

#circuit_breaker_failure_thresholdInteger

Number of unexpected failures before the circuit opens

Returns:

  • (Integer)

    failure threshold

Since:

  • 0.1.0



72
73
74
# File 'lib/rack_jwt_aegis/configuration.rb', line 72

def circuit_breaker_failure_threshold
  @circuit_breaker_failure_threshold
end

#custom_payload_validatorProc

Custom payload validation proc

Examples:

->(payload, request) { payload['role'] == 'admin' }

Returns:

  • (Proc)

    a callable that receives (payload, request) and returns boolean

Since:

  • 0.1.0



146
147
148
# File 'lib/rack_jwt_aegis/configuration.rb', line 146

def custom_payload_validator
  @custom_payload_validator
end

#debug_modeBoolean

Whether debug mode is enabled for additional logging

Returns:

  • (Boolean)

    true if debug mode is enabled

Since:

  • 0.1.0



170
171
172
# File 'lib/rack_jwt_aegis/configuration.rb', line 170

def debug_mode
  @debug_mode
end

#forbidden_responseHash

Custom response for forbidden requests (403)

Examples:

{ error: 'Access denied', code: 'AUTH_002' }

Returns:

  • (Hash)

    the forbidden response body

Since:

  • 0.1.0



162
163
164
# File 'lib/rack_jwt_aegis/configuration.rb', line 162

def forbidden_response
  @forbidden_response
end

#jwt_algorithmString

Note:

Supported algorithms: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512

The JWT algorithm to use for token verification

Returns:

  • (String)

    the JWT algorithm (default: ‘HS256’)

Since:

  • 0.1.0



36
37
38
# File 'lib/rack_jwt_aegis/configuration.rb', line 36

def jwt_algorithm
  @jwt_algorithm
end

#jwt_secretString

Note:

This is required and must not be empty

The secret key used for JWT signature verification

Returns:

  • (String)

    the JWT secret key

Since:

  • 0.1.0



31
32
33
# File 'lib/rack_jwt_aegis/configuration.rb', line 31

def jwt_secret
  @jwt_secret
end

#pathname_slug_patternRegexp

The regular expression pattern to extract pathname slugs

Returns:

  • (Regexp)

    the pathname slug pattern (default: /^/api/v1/(+)//)

Since:

  • 0.1.0



96
97
98
# File 'lib/rack_jwt_aegis/configuration.rb', line 96

def pathname_slug_pattern
  @pathname_slug_pattern
end

#payload_mappingHash

Mapping of standard payload keys to custom JWT claim names

Examples:

{ user_id: :sub, tenant_id: :company_id, subdomain: :domain }

Returns:

  • (Hash)

    the payload mapping configuration

Since:

  • 0.1.0



102
103
104
# File 'lib/rack_jwt_aegis/configuration.rb', line 102

def payload_mapping
  @payload_mapping
end

#permissions_cache_storeSymbol

The permission cache store adapter type

Returns:

  • (Symbol)

    the permission cache store type

Since:

  • 0.1.0



128
129
130
# File 'lib/rack_jwt_aegis/configuration.rb', line 128

def permissions_cache_store
  @permissions_cache_store
end

#permissions_cache_store_optionsHash

Options for the permission cache store

Returns:

  • (Hash)

    permission cache configuration options

Since:

  • 0.1.0



132
133
134
# File 'lib/rack_jwt_aegis/configuration.rb', line 132

def permissions_cache_store_options
  @permissions_cache_store_options
end

#rbac_cache_storeSymbol

The RBAC cache store adapter type (separate from main cache)

Returns:

  • (Symbol)

    the RBAC cache store type

Since:

  • 0.1.0



120
121
122
# File 'lib/rack_jwt_aegis/configuration.rb', line 120

def rbac_cache_store
  @rbac_cache_store
end

#rbac_cache_store_optionsHash

Options for the RBAC cache store

Returns:

  • (Hash)

    RBAC cache configuration options

Since:

  • 0.1.0



124
125
126
# File 'lib/rack_jwt_aegis/configuration.rb', line 124

def rbac_cache_store_options
  @rbac_cache_store_options
end

#rbac_enabledBoolean

Whether RBAC (Role-Based Access Control) is enabled

Returns:

  • (Boolean)

    true if RBAC is enabled

Since:

  • 0.1.0



64
65
66
# File 'lib/rack_jwt_aegis/configuration.rb', line 64

def rbac_enabled
  @rbac_enabled
end

#require_authentication_headersBoolean

Whether authenticated requests must include all identity/tenant headers

Returns:

  • (Boolean)

    true if strict authenticated request headers are required

Since:

  • 0.1.0



56
57
58
# File 'lib/rack_jwt_aegis/configuration.rb', line 56

def require_authentication_headers
  @require_authentication_headers
end

#require_expiration_claimsBoolean

Whether JWTs must include expiration-related claims

Returns:

  • (Boolean)

    true if exp and iat claims are required

Since:

  • 0.1.0



60
61
62
# File 'lib/rack_jwt_aegis/configuration.rb', line 60

def require_expiration_claims
  @require_expiration_claims
end

#skip_pathsArray<String, Regexp, Hash>

Array of routes that should skip JWT authentication

Examples:

['/health', '/api/public', /^\/assets/]
[{ path: '/api/v1/sessions', verbs: [:post] }]

Returns:

  • (Array<String, Regexp, Hash>)

    routes to skip authentication for

Since:

  • 0.1.0



113
114
115
# File 'lib/rack_jwt_aegis/configuration.rb', line 113

def skip_paths
  @skip_paths
end

#skip_routesArray<String, Regexp, Hash>

Array of routes that should skip JWT authentication

Examples:

['/health', '/api/public', /^\/assets/]
[{ path: '/api/v1/sessions', verbs: [:post] }]

Returns:

  • (Array<String, Regexp, Hash>)

    routes to skip authentication for

Since:

  • 0.1.0



113
114
115
# File 'lib/rack_jwt_aegis/configuration.rb', line 113

def skip_routes
  @skip_routes
end

#tenant_id_header_nameString

The HTTP header name containing the tenant ID

Returns:

  • (String)

    the tenant ID header name (default: ‘X-Tenant-Id’)

Since:

  • 0.1.0



84
85
86
# File 'lib/rack_jwt_aegis/configuration.rb', line 84

def tenant_id_header_name
  @tenant_id_header_name
end

#tenant_slug_header_nameString

The HTTP header name containing the tenant slug

Returns:

  • (String)

    the tenant slug header name

Since:

  • 0.1.0



88
89
90
# File 'lib/rack_jwt_aegis/configuration.rb', line 88

def tenant_slug_header_name
  @tenant_slug_header_name
end

#unauthorized_responseHash

Custom response for unauthorized requests (401)

Examples:

{ error: 'Authentication required', code: 'AUTH_001' }

Returns:

  • (Hash)

    the unauthorized response body

Since:

  • 0.1.0



156
157
158
# File 'lib/rack_jwt_aegis/configuration.rb', line 156

def unauthorized_response
  @unauthorized_response
end

#user_id_header_nameString

The HTTP header name containing the user ID

Returns:

  • (String)

    the user ID header name

Since:

  • 0.1.0



92
93
94
# File 'lib/rack_jwt_aegis/configuration.rb', line 92

def user_id_header_name
  @user_id_header_name
end

#validate_pathname_slugBoolean

Whether to validate pathname slug-based multi-tenancy

Returns:

  • (Boolean)

    true if pathname slug validation is enabled

Since:

  • 0.1.0



48
49
50
# File 'lib/rack_jwt_aegis/configuration.rb', line 48

def validate_pathname_slug
  @validate_pathname_slug
end

#validate_subdomainBoolean

Whether to validate subdomain-based multi-tenancy

Returns:

  • (Boolean)

    true if subdomain validation is enabled

Since:

  • 0.1.0



44
45
46
# File 'lib/rack_jwt_aegis/configuration.rb', line 44

def validate_subdomain
  @validate_subdomain
end

#validate_tenant_idBoolean

Whether to validate tenant id from request header against the tenant id from JWT payload

Returns:

  • (Boolean)

    true if tenant id validation is enabled

Since:

  • 0.1.0



52
53
54
# File 'lib/rack_jwt_aegis/configuration.rb', line 52

def validate_tenant_id
  @validate_tenant_id
end

Instance Method Details

#circuit_breaker_enabled?Boolean

Check if circuit breaker is enabled

Returns:

  • (Boolean)

    true if circuit breaker is enabled

Since:

  • 0.1.0



217
218
219
# File 'lib/rack_jwt_aegis/configuration.rb', line 217

def circuit_breaker_enabled?
  config_boolean?(circuit_breaker_enabled)
end

#debug_mode?Boolean

Check if debug mode is enabled

Returns:

  • (Boolean)

    true if debug mode is enabled

Since:

  • 0.1.0



253
254
255
# File 'lib/rack_jwt_aegis/configuration.rb', line 253

def debug_mode?
  config_boolean?(debug_mode)
end

#payload_key(standard_key) ⇒ Symbol

Get the mapped payload key for a standard key

Examples:

config.payload_key(:user_id) #=> :sub (if mapped)
config.payload_key(:user_id) #=> :user_id (if not mapped)

Parameters:

  • standard_key (Symbol)

    the standard key to map

Returns:

  • (Symbol)

    the mapped key from payload_mapping, or the original key if no mapping exists

Since:

  • 0.1.0



292
293
294
# File 'lib/rack_jwt_aegis/configuration.rb', line 292

def payload_key(standard_key)
  payload_mapping&.fetch(standard_key, standard_key) || standard_key
end

#rbac_enabled?Boolean

Check if RBAC is enabled

Returns:

  • (Boolean)

    true if RBAC is enabled

Since:

  • 0.1.0



211
212
213
# File 'lib/rack_jwt_aegis/configuration.rb', line 211

def rbac_enabled?
  config_boolean?(rbac_enabled)
end

#require_authentication_headers?Boolean

Check if strict authenticated request headers are required

Returns:

  • (Boolean)

    true if required auth headers are enabled

Since:

  • 0.1.0



241
242
243
# File 'lib/rack_jwt_aegis/configuration.rb', line 241

def require_authentication_headers?
  config_boolean?(require_authentication_headers)
end

#require_expiration_claims?Boolean

Check if exp and iat claims are required

Returns:

  • (Boolean)

    true if expiration claims are required

Since:

  • 0.1.0



247
248
249
# File 'lib/rack_jwt_aegis/configuration.rb', line 247

def require_expiration_claims?
  config_boolean?(require_expiration_claims)
end

#skip_path?(path) ⇒ Boolean

Check if the given path should skip JWT authentication

Parameters:

  • path (String)

    the request path to check

Returns:

  • (Boolean)

    true if the path should be skipped for any method

Since:

  • 0.1.0



270
271
272
# File 'lib/rack_jwt_aegis/configuration.rb', line 270

def skip_path?(path)
  skip_request?(path)
end

#skip_request?(path, request_method = nil) ⇒ Boolean

Check if the given request should skip JWT authentication

Parameters:

  • path (String)

    the request path to check

  • request_method (String, nil) (defaults to: nil)

    the HTTP method to check

Returns:

  • (Boolean)

    true if the route should be skipped

Since:

  • 0.1.0



278
279
280
281
282
283
284
# File 'lib/rack_jwt_aegis/configuration.rb', line 278

def skip_request?(path, request_method = nil)
  return false if normalized_skip_routes.empty?

  normalized_skip_routes.any? do |skip_route|
    route_matches?(skip_route, path, request_method)
  end
end

#validate_pathname_slug?Boolean

Check if pathname slug validation is enabled

Returns:

  • (Boolean)

    true if pathname slug validation is enabled

Since:

  • 0.1.0



229
230
231
# File 'lib/rack_jwt_aegis/configuration.rb', line 229

def validate_pathname_slug?
  config_boolean?(validate_pathname_slug)
end

#validate_subdomain?Boolean

Check if subdomain validation is enabled

Returns:

  • (Boolean)

    true if subdomain validation is enabled

Since:

  • 0.1.0



223
224
225
# File 'lib/rack_jwt_aegis/configuration.rb', line 223

def validate_subdomain?
  config_boolean?(validate_subdomain)
end

#validate_tenant_id?Boolean

Check if tenant id validation is enabled

Returns:

  • (Boolean)

    true if tenant id validation is enabled

Since:

  • 0.1.0



235
236
237
# File 'lib/rack_jwt_aegis/configuration.rb', line 235

def validate_tenant_id?
  config_boolean?(validate_tenant_id)
end