Skip to content

Topology Schema

The topology is defined in a single YAML file. The schema is validated by Pydantic; extra keys are forbidden everywhere.


Top-level structure

global:    # GlobalConfig
defaults:  # DefaultsConfig
groups:    # list[Group]
users:     # list[User]
routing:   # RoutingConfig
regions:   # list[Region]

global

Field Type Required Description
namespace str yes Unique identifier for this network — used as seed for all UUID/shortId derivation
aphelion_domain str yes Base domain for exit node hostnames
bridge_domain str yes Base domain for hub node hostnames
cdn CdnConfig no CDN domains for xhttp transport

global.cdn

Field Type Required Description
exit_domain str yes CDN domain fronting exit nodes
hub_domain str yes CDN domain fronting hub nodes

defaults

Default configuration applied to all exit or hub nodes. Node-level fields override these.

defaults.exit

Field Type Required Description
ipv6 bool yes Enable IPv6 on exit nodes by default
keys KeysConfig yes Encryption key configuration

defaults.hub

Field Type Required Default Description
ipv6 bool yes Enable IPv6 on hub nodes by default
proxy_inbound bool no false Enable mixed proxy inbound
keys KeysConfig yes Encryption key configuration
exit_connections ExitConnectionsConfig yes How hubs connect to exits
reality RealityConfig yes Default Reality config for hub nodes
mtproto MtprotoConfig no MTProto proxy configuration
observatory ObservatoryConfig no see below Health-check / load-balancer probe settings

KeysConfig

Field Type Required Default Description
enabled bool no true Whether encryption is active
mode str yes Key mode string (e.g. rprx_vision)
session_time str yes Session duration (e.g. 12h)
auth mlkem768 \| x25519 no mlkem768 Encryption algorithm
padding str no Optional padding value

ExitConnectionsConfig

Field Type Required Default Description
method str yes Handshake method (e.g. mlkem768x25519plus)
fingerprint str no edge Client TLS fingerprint

ObservatoryConfig

Field Type Default Description
sampling int (1–24) 8 Number of probe samples
interval str 15s Probe interval (format: \d+(ms\|s\|m\|h))
timeout str 5s Probe timeout
concurrency bool true Run probes concurrently

MtprotoConfig

Field Type Required Default Description
domain str yes Domain for the MTProto inbound
port int (1–65535) no 1234 MTProto listen port

groups

List of user groups. Groups provide a shared shortId for Reality inbound filtering.

Field Type Required Description
id str yes Unique group identifier
short_id str no Override auto-derived shortId

If short_id is omitted it is derived as SHA256("{id}.{namespace}")[:16].

Example:

groups:
  - id: staff
  - id: vip
    short_id: deadbeef01234567

users

Field Type Required Description
username str yes Unique username — used as derivation seed
group str yes Must reference an existing groups[].id
access list[AccessType] yes Access types: xhttp, server, cdn, proxy
uuid UUID no Override auto-derived UUID
portals list[Portal] no Portal (site-to-site tunnel) definitions
guests list[str] no Guest identity labels

Access types

Value Description
xhttp Direct Reality xhttp access
server Server-to-server access
cdn CDN-fronted xhttp access
proxy Mixed proxy inbound access

Portal

Field Type Required Description
label str yes Portal label (used in UUID derivation)
routes PortalRoutes yes Traffic selectors for this portal

PortalRoutes

Field Type Description
domains list[str] Domain matchers
ips list[str] IP/CIDR matchers

At least one matcher is required.

Example:

users:
  - username: alice
    group: staff
    access: [xhttp, cdn]
    portals:
      - label: office
        routes:
          domains: [internal.example.com]
          ips: [10.0.0.0/8]
    guests: [alice-phone, alice-tablet]

routing

Field Type Required Default Description
hub_default str yes Default region tag for unmatched hub traffic; must reference an existing regions[].id
exit_warp_global list[str] no [] Domain list routed to the warp interface on all exit nodes
exit_routes_global list[ExitRoute] no [] Global exit routing rules applied to all exit nodes
hub_routes list[HubRoute] no [] Hub routing rules (ordered; first match wins)

ExitRoute

Field Type Required Description
destination direct \| blocked \| warp yes Routing destination
domains list[str] cond. Domain matchers (at least one of domains/ips required)
ips list[str] cond. IP/CIDR matchers

HubRoute

Field Type Required Description
destination str yes Region ID, node ID, direct, blocked, or warp
domains list[str] cond. Domain matchers
ips list[str] cond. IP/CIDR matchers
users list[str] cond. Match only these usernames
proxy_users list[str] cond. Match only these proxy usernames

At least one matcher (domains, ips, users, or proxy_users) is required.


regions

Field Type Required Description
id str yes Unique region identifier
type exit \| hub yes Region type
vless_route int exit only Numeric route tag; must be unique across all regions
cdn_xhttp_path str no CDN xhttp path override for this region
lb_strategy str no Load balancer strategy (e.g. leastLoad)
lb_fallback str no Fallback node ID (must be in this region)
lb_least_load LeastLoadSettings no leastLoad tuning
routing RegionRouting no Per-region routing overrides (exit only)
warp WarpConfig no Warp tunnel configuration
nodes list[Node] yes At least one node required

LeastLoadSettings

Field Type Default Description
baselines list[str] ["30ms","100ms","250ms"] Latency buckets
expected int (≥1) 1 Expected alive count
max_rtt str 750ms Maximum accepted RTT
tolerance float (0–1) 0.5 Tolerance ratio

RegionRouting (exit regions only)

Field Type Description
warp_extra list[str] Additional warp domain overrides for this region
routes list[ExitRoute] Per-region exit routes (destination must be a special destination)

WarpConfig

Field Type Required Description
vless_route int yes Warp vless route tag; must be unique across all regions

Node

Field Type Required Description
id str yes Unique node identifier (globally unique across all regions)
hostname str yes Node FQDN
ipv6 bool no Override default IPv6 setting
lb_role backup no Mark as load-balancer backup node
reality RealityConfig exit nodes Reality TLS config (required for all exit nodes)
keys NodeKeysOverride no Override default key settings
exit_connections NodeExitConnectionsOverride no Override exit connection settings (hub nodes)
proxy_inbound bool no Override proxy inbound setting (hub nodes)
mtproto NodeMtprotoOverride no Override MTProto settings (hub nodes)

RealityConfig

Field Type Required Default Description
dest str yes Fallback destination (e.g. www.cloudflare.com:443)
server_names list[str] no SNI list; auto-derived from dest if omitted
xhttp_host str no xhttp Host header override
xhttp_path str yes xhttp request path (e.g. /stream)
fallback_limits RealityFallbackLimits no see below Fallback traffic limits

RealityFallbackLimits

Field Type Default Description
after_bytes int 16384 Bytes before fallback triggers
bytes_per_sec int 50000 Sustained rate limit
burst_bytes_per_sec int 100000 Burst rate limit

NodeKeysOverride

All fields optional; null means "use the default":

Field Type Description
enabled bool Override enabled
mode str Override mode
session_time str Override session_time
auth mlkem768 \| x25519 Override auth algorithm
padding str Override padding

NodeMtprotoOverride

Field Type Description
enabled bool Enable/disable MTProto on this node
domain str Override MTProto domain
port int (1–65535) Override MTProto port

Complete minimal example

global:
  namespace: mynet
  aphelion_domain: exit.example.com
  bridge_domain: hub.example.com

defaults:
  exit:
    ipv6: false
    keys:
      auth: mlkem768
      mode: native
      session_time: 600s
  hub:
    ipv6: false
    keys:
      auth: x25519
      mode: native
      session_time: 600s
    exit_connections:
      method: mlkem768x25519plus
    reality:
      dest: www.google.com:443
      xhttp_path: /stream

groups:
  - id: staff

users:
  - username: alice
    group: staff
    access: [xhttp, cdn]

routing:
  hub_default: hub-eu

regions:
  - id: exit-nl
    type: exit
    vless_route: 1
    nodes:
      - id: nlA00
        hostname: nl-a00.exit.example.com
        reality:
          dest: www.cloudflare.com:443
          xhttp_path: /stream

  - id: hub-eu
    type: hub
    nodes:
      - id: euH00
        hostname: eu-h00.hub.example.com