Module: Otto::Privacy::Core

Included in:
Otto
Defined in:
lib/otto/privacy/core.rb

Overview

Core privacy configuration methods included in the Otto class. Provides the public API for configuring IP privacy features.

Instance Method Summary collapse

Instance Method Details

#configure_ip_privacy(octet_precision: nil, hash_rotation: nil, geo: nil, redis: nil, correlation_secret: nil) ⇒ Object

Configure IP privacy settings

Privacy is enabled by default. Use this method to customize privacy behavior without disabling it entirely.

Examples:

Mask 2 octets instead of 1

otto.configure_ip_privacy(octet_precision: 2)

Disable geo-location

otto.configure_ip_privacy(geo: false)

Custom hash rotation

otto.configure_ip_privacy(hash_rotation: 24.hours)

Enable stable IP correlation (same visitor across days)

otto.configure_ip_privacy(correlation_secret: ENV['IP_CORRELATION_SECRET'])

Multi-server with Redis

redis = Redis.new(url: ENV['REDIS_URL'])
otto.configure_ip_privacy(redis: redis)

Parameters:

  • octet_precision (Integer) (defaults to: nil)

    Number of octets to mask (1 or 2, default: 1)

  • hash_rotation (Integer) (defaults to: nil)

    Seconds between key rotation (default: 86400)

  • geo (Boolean) (defaults to: nil)

    Enable geo-location resolution (default: true)

  • redis (Redis) (defaults to: nil)

    Redis connection for multi-server atomic key generation

  • correlation_secret (String) (defaults to: nil)

    A secret string that turns on IP correlation: it lets you tell whether two requests, even months apart, came from the same visitor — without your app ever seeing the real IP. (Otto masks the IP before your app runs; with a secret set it also fingerprints the full IP into req.ip_correlation_hash, which can’t be reversed to an IP without the secret.) Omit it to leave any existing secret unchanged; pass an empty string to turn the feature back off.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/otto/privacy/core.rb', line 78

def configure_ip_privacy(octet_precision: nil, hash_rotation: nil, geo: nil, redis: nil,
                         correlation_secret: nil)
  ensure_not_frozen!
  config = @security_config.ip_privacy_config

  config.octet_precision = octet_precision if octet_precision
  config.hash_rotation_period = hash_rotation if hash_rotation
  config.geo_enabled = geo unless geo.nil?
  # Mirror geo's `unless nil?` guard: nil means "leave unchanged", while an
  # explicit "" is a real value that disables the correlation hash. (A
  # plain `if correlation_secret` would also assign "" since "" is truthy
  # in Ruby, but stating the nil intent explicitly keeps this consistent
  # with the other nilable kwargs.)
  config.correlation_secret = correlation_secret unless correlation_secret.nil?
  config.instance_variable_set(:@redis, redis) if redis

  # Validate configuration
  config.validate!
end

#disable_ip_privacy!Object

Disable IP privacy to access original IP addresses

IMPORTANT: By default, Otto masks public IP addresses for privacy. Private/localhost IPs (127.0.0.0/8, 10.0.0.0/8, etc.) are never masked. Only disable this if you need access to original public IPs.

When disabled: - env[‘REMOTE_ADDR’] contains the real IP address - env[‘otto.original_ip’] also contains the real IP - No PrivateFingerprint is created

Examples:

otto.disable_ip_privacy!


23
24
25
26
# File 'lib/otto/privacy/core.rb', line 23

def disable_ip_privacy!
  ensure_not_frozen!
  @security_config.ip_privacy_config.disable!
end

#enable_full_ip_privacy!void

This method returns an undefined value.

Enable full IP privacy (mask ALL IPs including private/localhost)

By default, Otto exempts private and localhost IPs from masking for better development experience. Call this method to mask ALL IPs regardless of type.

Examples:

Enable full privacy (mask all IPs)

otto = Otto.new(routes_file)
otto.enable_full_ip_privacy!
# Now 127.0.0.1 → 127.0.0.0, 192.168.1.100 → 192.168.1.0

Raises:

  • (FrozenError)

    if called after configuration is frozen



41
42
43
44
# File 'lib/otto/privacy/core.rb', line 41

def enable_full_ip_privacy!
  ensure_not_frozen!
  @security_config.ip_privacy_config.mask_private_ips = true
end