-
Notifications
You must be signed in to change notification settings - Fork 0
Configuration
Edge is configured via a single YAML file passed as the first argument. Keys use snake_case. Unknown keys are rejected at startup.
edge <path-to-config.yml>
If api_keys is configured, every request must include the key as a header:
x-api-key: <your-api-key>
A missing, empty, or unrecognised key returns 401 Unauthorized. When omitted or empty, all endpoints are publicly accessible.
api_keys:
- "key-alpha"
- "key-beta"| Property | Type | Default | Description |
|---|---|---|---|
host |
string | "127.0.0.1" |
Bind address. Use "0.0.0.0" to listen on all interfaces. |
port |
integer | 8080 |
TCP port. |
Redis instance Edge subscribes to for incoming proxy events.
| Property | Type | Default | Description |
|---|---|---|---|
endpoint |
string |
host:port of the Redis server. |
|
password |
string? | Redis AUTH password. |
|
ssl |
boolean | false |
Enable TLS. |
channel |
string | "proxy_feed" |
Pub/sub channel to subscribe to. |
Redis instance Edge stores bucketed event data in.
| Property | Type | Default | Description |
|---|---|---|---|
endpoint |
string |
host:port of the Redis server. |
|
password |
string? | Redis AUTH password. |
|
ssl |
boolean | false |
Enable TLS. |
database |
integer | 0 |
Redis logical database index. |
Path to a MaxMind-format IP database. Used to populate location and network fields in API responses, and to evaluate mmdb.* filter conditions. The file must exist at startup.
| Property | Type | Description |
|---|---|---|
path |
string | Absolute path to the .mmdb file. |
mmdb:
path: "/data/geoip.mmdb"Named, reusable predicates referenced by buckets. A filter matches when all of its conditions are satisfied simultaneously. Filters with no conditions always match.
Two condition types are supported:
provider: matches the event's provider field. Accepts a single string or a list; any match passes. Case-insensitive.
mmdb.<path>: matches a field in the MMDB record for the event's IP using dot-notation. Accepts a single value or a list; any match passes. Comparisons are case-insensitive; numeric fields (e.g. ASN) are matched by their string representation.
filters:
skynet:
provider: "skynet"
known_providers:
provider: [skynet, netprobe]
us:
mmdb.country.iso_code: "US"
europe:
mmdb.country.iso_code: [DE, FR, NL, SE, PL]
hosting:
mmdb.traits.user_type: "hosting"
residential:
mmdb.traits.user_type: "residential"
# Multiple conditions, all must match
us_hosting:
mmdb.country.iso_code: "US"
mmdb.traits.user_type: "hosting"Filter names must be unique and are referenced by name in bucket definitions.
Named retention windows. An incoming event is written to every bucket whose conditions it satisfies. At least one bucket must be defined.
| Property | Type | Required | Description |
|---|---|---|---|
ttl |
string | Yes | Retention period as a TimeSpan, e.g. "00:05:00" (5 min), "01:00:00" (1 h), "1.00:00:00" (1 day). |
all |
string[] | No | Event must match every listed filter. |
any |
string[] | No | Event must match at least one listed filter. |
not |
string[] | No | Event must not match any listed filter. |
All three clauses may be combined; all must pass. A bucket with no clauses accepts every event. All referenced filter names must be defined in filters.
buckets:
# No filters, accepts everything
global:
ttl: "00:05:00"
# US residential IPs, short window
us_residential:
ttl: "00:30:00"
all: [us, residential]
# Hosting infra in US or Europe, from any known provider
known_hosting_west:
ttl: "01:00:00"
all: [hosting]
any: [us, europe]
not: [skynet]
# skynet only, regardless of geo
skynet_global:
ttl: "00:15:00"
all: [skynet]Each message published to the configured source.channel must be a JSON object:
{
"ip": "1.3.3.7",
"provider": "skynet",
"timestamp": "1708356600"
}| Field | Type | Description |
|---|---|---|
ip |
string | IPv4 or IPv6 address. |
provider |
string | Data source identifier. Used for filter matching and recorded in per-bucket activity. |
timestamp |
string | Unix epoch seconds as a string. Events older than now - bucket.ttl are discarded. |
source:
endpoint: "127.0.0.1:6379"
sink:
endpoint: "127.0.0.1:6379"
database: 1
mmdb:
path: "/data/dbip.mmdb"
buckets:
all_traffic:
ttl: "01:00:00"server:
host: "0.0.0.0"
port: 8080
api_keys:
- "prod-key-abc123"
source:
endpoint: "redis-feed.internal:6379"
password: "feed-secret"
ssl: true
channel: "proxy_feed"
sink:
endpoint: "redis-store.internal:6379"
password: "store-secret"
ssl: true
database: 2
mmdb:
path: "/data/geoip.mmdb"
filters:
skynet:
provider: "skynet"
us:
mmdb.country.iso_code: "US"
europe:
mmdb.country.iso_code: [DE, FR, NL, SE, PL]
hosting:
mmdb.traits.user_type: "hosting"
residential:
mmdb.traits.user_type: "residential"
buckets:
# No filters, accepts everything
global:
ttl: "00:05:00"
# Short-lived window for US residential IPs
us_residential:
ttl: "00:30:00"
all: [us, residential]
# Hosting infra in US or Europe from trusted providers, excluding skynet
known_hosting_west:
ttl: "01:00:00"
all: [hosting]
any: [us, europe]
not: [skynet]
# skynet activity only, medium retention
skynet_global:
ttl: "00:15:00"
all: [skynet]