Module: Otto::EnvKeys
- Defined in:
- lib/otto/env_keys.rb
Overview
Rack environment keys used by Otto framework
All Otto-specific keys are namespaced under 'otto.*' to avoid conflicts with other Rack middleware or applications.
Defined Under Namespace
Constant Summary collapse
- ROUTE_DEFINITION =
Route definition parsed from routes file Type: Otto::RouteDefinition Set by: Otto::Core::Router#parse_routes Used by: AuthenticationMiddleware, RouteHandlers, LogicClassHandler
'otto.route_definition'- ROUTE_OPTIONS =
Route-specific options parsed from route string Type: Hash (e.g., { response: 'json', csrf: 'exempt', auth: 'authenticated' }) Set by: Otto::RouteDefinition#initialize Used by: CSRFMiddleware, RouteHandlers
'otto.route_options'- STRATEGY_RESULT =
Authentication strategy result containing session/user state Type: Otto::Security::Authentication::StrategyResult Set by: RouteAuthWrapper (wraps all route handlers) Used by: RouteHandlers, LogicClasses, Controllers Guarantee: ALWAYS present - either authenticated or anonymous
- Routes WITH auth requirement: Authenticated StrategyResult or 401/302
- Routes WITHOUT auth requirement: Anonymous StrategyResult
'otto.strategy_result'- SECURITY_CONFIG =
Security configuration object Type: Otto::Security::Config Set by: Otto#initialize, SecurityConfig Used by: All security middleware (CSRF, Headers, Validation)
'otto.security_config'- NONCE =
Per-request CSP nonce, minted lazily on first access and memoized here. Type: String (base64) Set by: Otto::Security::CSP.nonce / Otto::Request#csp_nonce (first touch) Used by: views (stamping script/style nonces) and Otto::Security::CSP::EmitMiddleware (emit-if-consumed) Note: this is the DEFAULT key. Apps with an existing convention can point the accessor at their own key via Otto::Security::Config#csp_nonce_key (e.g. 'onetime.nonce'), so the header and views still share one value.
'otto.nonce'- VIA_TRUSTED_PROXY =
Whether the request arrived via a trusted proxy. TRI-STATE. Type: Boolean when present; the key may be ABSENT. Set by: IPPrivacyMiddleware, evaluated on the original peer BEFORE REMOTE_ADDR is masked — but ONLY when proxy trust is configured (Security::Config#proxy_trust_configured?: CIDR matchers, a depth, or the explicit trust-nobody assertion
trusted_proxies: :none). True when the peer matches a configured trusted_proxies CIDR (filter mode), or unconditionally when count-based depth mode is active (trusted_proxy_depth >= 1) — the modes are mutually exclusive, and configuring a depth is the operator's assertion that the connecting peer is their proxy tier (#226). False means trust IS configured and this peer failed it — an authoritative deny; it is also false for EVERY peer (loopback included) when the operator assertedtrusted_proxies: :none(#259). When no proxy trust is configured the key is NOT written, so consumers can distinguish "denied" from "unconfigured" and apply legacy heuristics only in the latter case. Used by: Otto::Request#secure? to authorize X-Forwarded-Proto / X-Scheme without depending on the (masked) REMOTE_ADDR, and by downstream middleware (e.g. forwarded-host handling) as the peer-trust signal now that REMOTE_ADDR no longer identifies the connecting peer. Consumers should treat a PRESENT key as authoritative in both directions and reserve fallback heuristics for the absent case. 'otto.via_trusted_proxy'- PEER_LOOPBACK =
Whether the connecting peer was the loopback interface. Type: Boolean Set by: IPPrivacyMiddleware (every request, evaluated on the ORIGINAL socket peer BEFORE REMOTE_ADDR is masked/rewritten). A boolean, never an address, so it carries no identifying data. Used by: Otto::CaddyTLS::LocalhostGuard to authenticate a direct local call now that IPPrivacyMiddleware runs outermost. Deliberately the raw peer, not the resolved client IP: forwarded headers must play no part in a localhost trust decision.
'otto.peer_loopback'- PEER_RELAYED =
Whether the request arrived relayed by a proxy (any relay marker header present). Type: Boolean Set by: IPPrivacyMiddleware (every request), evaluated on the ORIGINAL headers BEFORE the untrusted-peer scrub may DELETE those carriers (Otto::Utils::RELAY_MARKER_HEADERS cover the forwarded-for family, RFC 7239 Forwarded, and the X-Forwarded-Host/Proto/Scheme/SSL/Port authority carriers — everything the scrub removes). A boolean, so it carries no identifying data. Used by: Otto::CaddyTLS::LocalhostGuard#relayed? — without this record a request relayed over loopback by a proxy emitting only RFC 7239
Forwardedor onlyX-Forwarded-Hostwould look like a direct local call after the scrub, and a deny would become an allow. 'otto.peer_relayed'- LOCALE =
Resolved locale for current request Type: String (e.g., 'en', 'es', 'fr') Set by: LocaleMiddleware Used by: RouteHandlers, LogicClasses, Views
'otto.locale'- LOCALE_CONFIG =
Locale configuration object Type: Otto::LocaleConfig Set by: LocaleMiddleware Used by: Locale resolution logic
'otto.locale_config'- AVAILABLE_LOCALES =
Available locales for the application Type: Array
Set by: LocaleConfig Used by: Locale middleware, language switchers 'otto.available_locales'- DEFAULT_LOCALE =
Default/fallback locale Type: String Set by: LocaleConfig Used by: Locale middleware when resolution fails
'otto.default_locale'- ERROR_ID =
Unique error ID for tracking/logging Type: String (hex format, e.g., '4ac47cb3a6d177ef') Set by: ErrorHandler, RouteHandlers Used by: Error responses, logging, support
'otto.error_id'- CLIENT_IP =
Canonical client IP, resolved once early by IPPrivacyMiddleware ("resolve once, read everywhere"). Downstream code (client_ipaddress, Request#ip) reads this instead of re-deriving from REMOTE_ADDR / XFF. Type: String Set by: IPPrivacyMiddleware (every request, all modes) Value: masked IP when privacy enabled; resolved real IP when privacy disabled or the address is exempt (private/localhost) Note: presence also acts as the idempotency guard for the middleware
'otto.client_ip'- IP_MATCH =
Verdict-only CIDR membership check over the resolved, UNMASKED client IP Type: Proc — call with an Enumerable of CIDR strings or IPAddr objects, returns true/false Set by: IPPrivacyMiddleware (every path that resolves an IP, all privacy profiles) Used by: Downstream IP policy code (allowlists, denylists, network zones) that needs full /32-/128 precision without changing the observability posture — CLIENT_IP is masked under the default profile, so it cannot express a single host Note: the unmasked IP never lands in env; only this closure does, and a Proc serializes to nothing useful, so env dumps and loggers cannot leak the address accidentally. Returns false when the request had no resolvable client IP (fail-closed for allowlist callers); raises IPAddr::InvalidAddressError for invalid CIDR entries (configuration error). See Otto::Utils.ip_in_cidrs?. Note: setting CLIENT_IP yourself is out of contract — it trips the middleware's idempotency guard, so the unmasked address is never captured and this capability degrades to a logged fail-closed check that denies every range.
'otto.ip_match'- ORIGINAL_IP =
Original client IP address (only when privacy disabled) Type: String Set by: IPPrivacyMiddleware (when privacy disabled) Used by: Debugging, legitimate use cases requiring real IP NOTE: Not available when privacy is enabled (intentional)
'otto.original_ip'- ORIGINAL_USER_AGENT =
Original User-Agent string (only when privacy disabled) Type: String Set by: IPPrivacyMiddleware (when privacy disabled) Used by: Bot detection, browser feature detection NOTE: Not available when privacy is enabled (intentional)
'otto.original_user_agent'- ORIGINAL_REFERER =
Original Referer URL (only when privacy disabled) Type: String Set by: IPPrivacyMiddleware (when privacy disabled) Used by: Analytics, debugging NOTE: Not available when privacy is enabled (intentional)
'otto.original_referer'- MCP_HTTP_ENDPOINT =
MCP HTTP endpoint path Type: String (default: '/_mcp') Set by: Otto::MCP::Server#enable! Used by: MCP middleware, SchemaValidationMiddleware
'otto.mcp_http_endpoint'