Class: Aikido::Zen::RuntimeSettings

Inherits:
Struct
  • Object
show all
Defined in:
lib/aikido/zen/runtime_settings.rb

Overview

Stores the firewall configuration sourced from the Aikido dashboard. This object is updated by the Agent regularly.

Because the RuntimeSettings object can be modified in runtime, it implements the Observable API, allowing you to subscribe to updates. These are triggered whenever #update_from_runtime_settings_json makes a change (i.e. if the settings don’t change, no update is triggered).

You can subscribe to changes with #add_observer(object, func_name), which will call the function passing the settings as an argument

Defined Under Namespace

Classes: DomainSettings, Domains, Endpoints, IPList, IPSet, ProtectionSettings, RateLimitSettings

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRuntimeSettings

Returns a new instance of RuntimeSettings.



15
16
17
18
19
20
21
22
23
# File 'lib/aikido/zen/runtime_settings.rb', line 15

def initialize(*)
  super
  self.endpoints ||= RuntimeSettings::Endpoints.new
  self.bypassed_ips ||= RuntimeSettings::IPSet.new
  self.blocked_ip_lists ||= []
  self.allowed_ip_lists ||= []
  self.monitored_ip_lists ||= []
  self.domains ||= RuntimeSettings::Domains.new
end

Instance Attribute Details

#allowed_ip_listsArray<Aikido::Zen::RuntimeSettings::IPList>



14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def allowed_ip_lists
  @allowed_ip_lists
end

#block_new_outboundBoolean

Returns:

  • (Boolean)


14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def block_new_outbound
  @block_new_outbound
end

#blocked_ip_listsArray<Aikido::Zen::RuntimeSettings::IPList>



14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def blocked_ip_lists
  @blocked_ip_lists
end

#blocked_user_agent_regexpRegexp

Returns:

  • (Regexp)


14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def blocked_user_agent_regexp
  @blocked_user_agent_regexp
end

#blocked_user_idsArray

Returns:

  • (Array)


14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def blocked_user_ids
  @blocked_user_ids
end

#blocking_modeBoolean

Returns:

  • (Boolean)


14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def blocking_mode
  @blocking_mode
end

#bypassed_ipsAikido::Zen::RuntimeSettings::IPSet



14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def bypassed_ips
  @bypassed_ips
end

#domainsArray<Aikido::Zen::RuntimeSettings::DomainSettings>



14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def domains
  @domains
end

#endpointsAikido::Zen::RuntimeSettings::Endpoints



14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def endpoints
  @endpoints
end

#excluded_user_ids_from_rate_limitingArray<String>?

Returns the user IDs that should be skipped from rate limiting entirely.

Returns:

  • (Array<String>, nil)

    the user IDs that should be skipped from rate limiting entirely.



14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def excluded_user_ids_from_rate_limiting
  @excluded_user_ids_from_rate_limiting
end

#heartbeat_intervalInteger

Returns duration in seconds between heartbeat requests to the Aikido server.

Returns:

  • (Integer)

    duration in seconds between heartbeat requests to the Aikido server.



14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def heartbeat_interval
  @heartbeat_interval
end

#monitored_ip_listsArray<Aikido::Zen::RuntimeSettings::IPList>



14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def monitored_ip_lists
  @monitored_ip_lists
end

#monitored_user_agent_regexpRegexp

Returns:

  • (Regexp)


14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def monitored_user_agent_regexp
  @monitored_user_agent_regexp
end

#received_any_statsBoolean

Returns whether the Aikido server has received any data from this application.

Returns:

  • (Boolean)

    whether the Aikido server has received any data from this application.



14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def received_any_stats
  @received_any_stats
end

#updated_atTime

Returns when these settings were updated in the Aikido dashboard.

Returns:

  • (Time)

    when these settings were updated in the Aikido dashboard.



14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def updated_at
  @updated_at
end

#user_agent_detailsRegexp

Returns:

  • (Regexp)


14
15
16
# File 'lib/aikido/zen/runtime_settings.rb', line 14

def user_agent_details
  @user_agent_details
end

Instance Method Details

#allowed_ip?(ip) ⇒ Boolean

Returns:

  • (Boolean)


201
202
203
# File 'lib/aikido/zen/runtime_settings.rb', line 201

def allowed_ip?(ip)
  allowed_ip_lists.empty? || allowed_ip_lists.any? { |ip_list| ip_list.include?(ip) }
end

#block_outbound?(connection) ⇒ Boolean

Returns:

  • (Boolean)


219
220
221
222
223
224
225
# File 'lib/aikido/zen/runtime_settings.rb', line 219

def block_outbound?(connection)
  domain = domains[connection.host]

  return true if !domain.equal?(RuntimeSettings::DomainSettings.none) && domain.block?

  block_new_outbound && domain.block?
end

#blocked_ip?(ip) ⇒ Boolean

Returns:

  • (Boolean)


205
206
207
# File 'lib/aikido/zen/runtime_settings.rb', line 205

def blocked_ip?(ip)
  blocked_ip_lists.any? { |ip_list| ip_list.include?(ip) }
end

#blocked_user_agent?(user_agent) ⇒ Boolean

Returns whether the user agent should be blocked.

Parameters:

  • user_agent (String)

    the user agent

Returns:

  • (Boolean)

    whether the user agent should be blocked



179
180
181
182
183
# File 'lib/aikido/zen/runtime_settings.rb', line 179

def blocked_user_agent?(user_agent)
  return false if blocked_user_agent_regexp.nil?

  blocked_user_agent_regexp.match?(user_agent)
end

#bypassed_ip?(ip) ⇒ Boolean

Returns Whether the IP is included in the bypassed IPs set.

Parameters:

  • ip (String)

Returns:

  • (Boolean)

    Whether the IP is included in the bypassed IPs set.



166
167
168
# File 'lib/aikido/zen/runtime_settings.rb', line 166

def bypassed_ip?(ip)
  bypassed_ips.include?(ip)
end

#monitored_ip?(ip) ⇒ Boolean

Returns:

  • (Boolean)


209
210
211
# File 'lib/aikido/zen/runtime_settings.rb', line 209

def monitored_ip?(ip)
  monitored_ip_lists.any? { |ip_list| ip_list.include?(ip) }
end

#monitored_ip_list_keys(ip) ⇒ Object



213
214
215
216
217
# File 'lib/aikido/zen/runtime_settings.rb', line 213

def monitored_ip_list_keys(ip)
  return [] if ip.nil?

  monitored_ip_lists.filter_map { |ip_list| ip_list.key if ip_list.include?(ip) }
end

#monitored_user_agent?(user_agent) ⇒ Boolean

Returns whether the user agent should be monitored.

Parameters:

  • user_agent (String)

    the user agent

Returns:

  • (Boolean)

    whether the user agent should be monitored



187
188
189
190
191
# File 'lib/aikido/zen/runtime_settings.rb', line 187

def monitored_user_agent?(user_agent)
  return false if monitored_user_agent_regexp.nil?

  monitored_user_agent_regexp.match?(user_agent)
end

#update_from_runtime_config_json(data) ⇒ bool

Parse and interpret the JSON response from the core API with updated runtime settings, and apply the changes.

This will also notify any subscriber to updates.

Parameters:

  • data (Hash)

    the decoded JSON payload from the /api/runtime/config API endpoint.

Returns:

  • (bool)


84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/aikido/zen/runtime_settings.rb', line 84

def update_from_runtime_config_json(data)
  last_updated_at = updated_at

  self.updated_at = Time.at(data["configUpdatedAt"].to_i / 1000)
  self.heartbeat_interval = data["heartbeatIntervalInMS"].to_i / 1000
  self.endpoints = RuntimeSettings::Endpoints.from_json(data["endpoints"])
  self.blocked_user_ids = data["blockedUserIds"]
  self.bypassed_ips = RuntimeSettings::IPSet.from_json(data["allowedIPAddresses"])
  self.received_any_stats = data["receivedAnyStats"]
  self.blocking_mode = data["block"]

  self.block_new_outbound = data["blockNewOutgoingRequests"]
  self.domains = RuntimeSettings::Domains.from_json(data["domains"])

  self.excluded_user_ids_from_rate_limiting = data["excludedUserIdsFromRateLimiting"]

  updated_at != last_updated_at
end

#update_from_runtime_firewall_lists_json(data) ⇒ void

This method returns an undefined value.

Parse and interpret the JSON response from the core API with updated runtime firewall lists, and apply the changes.

Parameters:

  • data (Hash)

    the decoded JSON payload from the /api/runtime/firewall/lists API endpoint.



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/aikido/zen/runtime_settings.rb', line 109

def update_from_runtime_firewall_lists_json(data)
  self.blocked_user_agent_regexp = pattern(data["blockedUserAgents"])

  self.monitored_user_agent_regexp = pattern(data["monitoredUserAgents"])

  self.user_agent_details = []

  data["userAgentDetails"]&.each do |record|
    key = record["key"]
    pattern = pattern(record["pattern"])

    next if key.nil? || pattern.nil?

    user_agent_details << {
      key: key,
      pattern: pattern
    }
  end

  self.blocked_ip_lists = []

  data["blockedIPAddresses"]&.each do |ip_list|
    blocked_ip_lists << RuntimeSettings::IPList.from_json(ip_list)
  end

  self.allowed_ip_lists = []

  data["allowedIPAddresses"]&.each do |ip_list|
    allowed_ip_lists << RuntimeSettings::IPList.from_json(ip_list)
  end

  self.monitored_ip_lists = []

  data["monitoredIPAddresses"]&.each do |ip_list|
    monitored_ip_lists << RuntimeSettings::IPList.from_json(ip_list)
  end
end

#user_agent_keys(user_agent) ⇒ Array<String>

Returns the matching user agent keys.

Parameters:

  • user_agent (String)

    the user agent

Returns:

  • (Array<String>)

    the matching user agent keys



195
196
197
198
199
# File 'lib/aikido/zen/runtime_settings.rb', line 195

def user_agent_keys(user_agent)
  return [] if user_agent_details.nil?

  user_agent_details.filter_map { |record| record[:key] if record[:pattern].match?(user_agent) }
end

#user_excluded_from_rate_limiting?(user_id) ⇒ Boolean

Returns Whether the user is excluded from rate limiting.

Parameters:

  • user_id (String, nil)

Returns:

  • (Boolean)

    Whether the user is excluded from rate limiting.



172
173
174
175
# File 'lib/aikido/zen/runtime_settings.rb', line 172

def user_excluded_from_rate_limiting?(user_id)
  return false if user_id.nil?
  excluded_user_ids_from_rate_limiting&.include?(user_id.to_s) || false
end