Class: RailsAiBridge::Mcp::Authenticator
- Inherits:
-
Object
- Object
- RailsAiBridge::Mcp::Authenticator
- Defined in:
- lib/rails_ai_bridge/mcp/authenticator.rb
Overview
Service object that authenticates HTTP MCP requests.
Consolidates strategy resolution, static-token lookup, and configuration predicates into a single entry point — previously split across +McpHttpAuth+ (utility helpers) and +Mcp::HttpAuth+ (strategy orchestrator), both removed in v2.0.0.
== Strategy priority (highest → lowest)
- Configuration#mcp_jwt_decoder → RailsAiBridge::Mcp::Auth::Strategies::Jwt
- Configuration#mcp_token_resolver → RailsAiBridge::Mcp::Auth::Strategies::BearerToken (resolver mode)
- +config.http_mcp_token+ / +ENV["RAILS_AI_BRIDGE_MCP_TOKEN"]+ → RailsAiBridge::Mcp::Auth::Strategies::BearerToken (static mode)
- None configured → open access (RailsAiBridge::Mcp::AuthResult.ok)
== Security design notes
Static-token comparison uses +Digest::SHA256+ pre-hashing + +ActiveSupport::SecurityUtils.secure_compare+ (constant-time over fixed-length digests). This prevents token-length leakage but does NOT protect against brute-force guessing. Use +config.mcp.rate_limit_max_requests+ for built-in per-IP rate limiting, or +rack-attack+ for distributed/stricter quotas.
The JWT strategy is decoder-only — this gem carries no JWT dependency. The host supplies a lambda; any +StandardError+ it raises is caught and surfaced as +:decode_error+, never propagated.
Constant Summary collapse
- TOKEN_ENV_KEY =
'RAILS_AI_BRIDGE_MCP_TOKEN'
Class Method Summary collapse
-
.any_configured? ⇒ Boolean
Returns +true+ when any auth mechanism is configured — static token, resolver, or JWT decoder.
-
.call(request) ⇒ AuthResult
Authenticate an incoming Rack request against the configured strategy.
-
.unauthorized_rack_response ⇒ Array<(Integer, Hash{String => String}, Array<String>)>
Builds a Rack 401 response for unauthenticated HTTP MCP requests.
Class Method Details
.any_configured? ⇒ Boolean
Returns +true+ when any auth mechanism is configured — static token, resolver, or JWT decoder. Used by production-safety validators to confirm the MCP endpoint is protected.
Checks configuration presence, not runtime correctness. A resolver that always returns +nil+ still counts as "configured."
65 66 67 |
# File 'lib/rails_ai_bridge/mcp/authenticator.rb', line 65 def any_configured? resolve_strategy.present? end |
.call(request) ⇒ AuthResult
Authenticate an incoming Rack request against the configured strategy.
50 51 52 53 54 55 |
# File 'lib/rails_ai_bridge/mcp/authenticator.rb', line 50 def call(request) strategy = resolve_strategy return AuthResult.ok(nil) if strategy.nil? strategy.authenticate(request) end |
.unauthorized_rack_response ⇒ Array<(Integer, Hash{String => String}, Array<String>)>
Builds a Rack 401 response for unauthenticated HTTP MCP requests.
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/rails_ai_bridge/mcp/authenticator.rb', line 72 def [ 401, { 'Content-Type' => 'application/json', 'WWW-Authenticate' => 'Bearer realm="rails-ai-bridge-mcp"' }, ['{"error":"Unauthorized"}'] ] end |