View Source Paraxial.io Agent Guide

introduction

Introduction

Welcome to the Paraxial.io agent documentation. This page will introduce you to key features of the agent, how to install it in your project, and how to use conn assigns for sending select user data to the backend.


index

Index

  1. Agent Features

  2. Detailed Installation Instructions

  3. Debugging Installation Errors

  4. Paraxial Functions

  5. Paraxial Plugs

  6. Assigns

  7. Additional Documentation


If you are already familiar with the Paraxial.io agent, and are looking for a concise set of steps to install the agent, without exposition, see the install page.

1-agent-features

1. Agent Features

allowing-and-blocking-requests

Allowing and Blocking Requests

When a request arrives in an application protected by Paraxial.io, the agent determines if the request should be allowed or blocked. A request may be blocked for many reasons, such as matching a user-defined rule, belonging to a cloud provider's IP range, or being placed on a site's ban list by a user. An example of a user defined rule is, "If one IP address sends > 10 login requests in 5 seconds, ban it".

The decision to allow or deny a request is based on the value of conn.remote_ip. If you are hosting your Phoenix application behind a proxy, this value is probably different from the real IP of the client. To fix this, use the remote_ip library.

cloud-ip-range-matching

Cloud IP Range Matching

The agent is able to determine if an incoming request's IP address matches the IP range of several major cloud providers. For more details, see cloud ip matching.

trusted-domains-and-bulk-actions

Trusted Domains and Bulk Actions

If the Paraxial.io customer application contains code for a bulk action, such as a user sending dozens of emails with a single POST request, the agent can maintain a data structure of "trusted" domains. Users from these trusted domains can be granted a higher threshold for the bulk action, compared with users from untrusted domains. This means mike@paraxial.io can send up to 100 emails at a time, while kyle@10minmail.com will be limited to 3.

data-forwarding-to-paraxial-io-backend

Data Forwarding to Paraxial.io Backend

The agent forwards data about incoming requests to the Paraxial.io backend. There are several paraxial_ prefixed assigns available, to add information about the customer application's users to this data. For example, if you want to quickly determine which requests are associated with logged-in users, use the :paraxial_current_user assigns.

2-detailed-installation-instructions

2. Detailed Installation Instructions

optional-install-remote_ip-in-your-application

(Optional) Install remote_ip in your application

If your application is showing a different conn.remote_ip than expected, it is probably behind a proxy. Install the remote_ip library to fix this.

use-plug-plug-requestid-in-your-application-s-endpoint-ex-file

Use plug Plug.RequestId in your application's endpoint.ex file:

The majority of Phoenix applications do this by default. Check your endpoint.ex file for the line:

  plug Plug.RequestId

This plug sets x-request-id, which is required for the Paraxial agent to work correctly. If it does not exist, add it to your project.

install-paraxial-in-your-application-s-mix-exs-file

Install :paraxial in your application's mix.exs file:

def deps do
  [
    {:paraxial, "~> 2.7.7"}
  ]
end

application-configuration

Application Configuration:

In your Paraxial.io account, we recommend creating two different sites for your application. One site for development/testing, and one site for production. For your local environment, edit your application's config/dev.exs:

config :paraxial,
  paraxial_api_key: System.get_env("PARAXIAL_API_KEY"),
  fetch_cloud_ips: true,
  bulk: %{email: %{trusted: 100, untrusted: 3}},
  trusted_domains: MapSet.new(["paraxial.io", "blackcatprojects.xyz"])

Configuration keys and values:

  1. paraxial_api_key - Found in your site's settings page. Required for secure communication between the agent and Paraxial.io backend service.

  2. paraxial_url - This is https://app.paraxial.io.

  3. fetch_cloud_ips - By default, Paraxial.io will sent HTTP requests to retrieve the public IP ranges of several cloud providers. If you wish to disable this, set fetch_cloud_ips to false. When disabled, matching incoming requests against cloud IP addresses will not work.

  4. bulk and trusted_domains - In the above example, user emails ending in @paraxial.io or @blackcatprojects.xyz will be able to send up to 100 emails. Emails from different domains can only send 3. These values are optional.

configure-plugs

Configure Plugs

Open endpoint.ex and add the required plugs:

  plug RemoteIp
  plug Paraxial.AllowedPlug
  plug Paraxial.RecordPlug
  plug HavanaWeb.Router
  plug Paraxial.RecordPlug

The duplicated Paraxial.RecordPlug before and after the router is intentional, it is done to record requests that fail to match in the router.

3-debugging-installation-errors

3. Debugging Installation Errors

Check that your application is configured correctly.

1-set-your-application-s-local-logging-level-to-debug-this-will-allow-you-to-see-debug-messages-from-the-paraxial-agent-example-config-dev-exs

1. Set your application's local logging level to debug. This will allow you to see debug messages from the Paraxial agent. Example config/dev.exs:

config :logger, level: :debug

2-check-the-paraxial-lines-in-config-dev-exs-are-similar-to

2. Check the Paraxial lines in config/dev.exs are similar to:

config :paraxial,
  paraxial_api_key: System.get_env("PARAXIAL_API_KEY"),
  fetch_cloud_ips: true,
  bulk: %{email: %{trusted: 100, untrusted: 3}},
  trusted_domains: MapSet.new(["paraxial.io", "blackcatprojects.xyz"])

The following values are optional:

  • fetch_cloud_ips
  • bulk
  • trusted_domains

3-start-your-application-locally-read-the-debug-lines-from-paraxial

3. Start your application locally, read the debug lines from Paraxial.

Bad start:

@ house % mix phx.server
[warning] Paraxial API key not found.

This warning means your application is not configured correctly. Check your config files.

Bad start:

[info] Paraxial URL and API key found.
[info] [Paraxial] :fetch_cloud_ips not set. No requests sent.
[info] [Paraxial] Agent starting supervisor.
[info] Running HouseWeb.Endpoint with cowboy 2.9.0 at 127.0.0.1:4002 (http)
[info] Access HouseWeb.Endpoint at http://localhost:4002
[error] Task #PID<0.603.0> started from Paraxial.Crow terminating
** (FunctionClauseError) no function clause matching in Access.get/3

Check that your paraxial_url starts with https and not http. Also check that your API key is entered correctly.

Good start:

[info] Paraxial URL and API key found.
[info] [Paraxial] :fetch_cloud_ips set to true, fetching...
[debug] [Paraxial] Prefixes downloaded for aws: 8075
[debug] [Paraxial] Prefixes downloaded for azure: 56752
[debug] [Paraxial] Prefixes downloaded for digital_ocean: 1644
[debug] [Paraxial] Prefixes downloaded for gcp: 540
[debug] [Paraxial] Prefixes downloaded for oracle: 492
[debug] [Paraxial] Prefixes length with duplicates: 67503
[debug] [Paraxial] Iptrie count - 39566
[debug] [Paraxial] Iptrie size in MB: 1.233269
[info] [Paraxial] Agent starting supervisor.
[info] Running HouseWeb.Endpoint with cowboy 2.9.0 at 127.0.0.1:4002 (http)
[info] Access HouseWeb.Endpoint at http://localhost:4002
[watch] build finished, watching for changes...
[debug] [Paraxial] HTTPBuffer sending POST request
[debug] :ok

4-paraxial-functions

4. Paraxial Functions

There is only one Paraxial function intended for use by users:

  1. Paraxial.bulk_allowed?/3

5-paraxial-plugs

5. Paraxial Plugs

The Paraxial.io Agent provides several Plugs to be used in your application code:

  1. Paraxial.AllowedPlug - Required, this Plug determines if an incoming requests matches your allow/block lists. If a request is halted by this Plug, internally Paraxial will still record it.

  2. Paraxial.RecordPlug - Required, records incoming HTTP requests into a local buffer, then sends them to the Paraxial.io backend.

  3. Paraxial.AssignCloudIP - Optional, if the remote_ip of an incoming request matching a cloud provider IP address, this plug will add metadata to the conn via an assigns. For example, if a conn's remote_ip matches aws, this plug will do assigns(conn, :paraxial_cloud_ip, :aws).

  4. Paraxial.BlockCloudIP - Optional, similar to AssignCloudIP. When a conn matches a cloud provider IP, the assign is updated and the conn is halted, with a 404 response sent to the client.

  5. Paraxial.CurrentUserPlug - Optional, only works if conn.assigns.current_user.email is set. Sets the :paraxial_current_user assigns by calling assign(conn, :paraxial_current_user, conn.assigns.current_user.email)

6-assigns

6. Assigns

This is a table of every Paraxial assigns value. To avoid conflict with assigns in your application code, each assigns key is prefixed with paraxial.

KeySet ByType
:paraxial_login_successUser ApplicationBoolean
:paraxial_login_user_nameUser ApplicationString
:paraxial_current_userUser ApplicationString
:paraxial_cloud_ipParaxial AgentString (aws, azure, etc.)

To monitor login attempts, use:

assign(conn, :paraxial_login_success, true/false)

To monitor the login name for the given login attempt use:

assign(conn, :paraxial_login_user_name, "userNameHere")

To map incoming requests to the currently logged in user, use:

assign(conn, :paraxial_current_user, "userNameHere")

The :paraxial_cloud_ip assign is set by Paraxial.AssignCloudIP. If you do not use this assign anywhere in your application code, and just want to block cloud IPs, use Paraxial.BlockCloudIP. Check your configuration to ensure fetch_cloud_ips: true is set.

7-additional-documentation

7. Additional Documentation

Agent Internals

Cloud IPs

Brief Install Guide