Skip to content

Latest commit

 

History

History
393 lines (294 loc) · 21.5 KB

File metadata and controls

393 lines (294 loc) · 21.5 KB
title Configuration Reference
description Complete reference for all Portal environment variables, CLI flags, and configuration files.

Configuration Reference

Complete reference for all Portal environment variables, CLI flags, and configuration files.

Relay Server Environment Variables

The relay server (relay-server) reads configuration from environment variables. Each variable corresponds to a CLI flag of the same shape (e.g. PORTAL_URL--portal-url). CLI flags take precedence over environment variables when both are set.

Core

Variable Default Type Description
PORTAL_URL https://localhost string Public HTTPS origin of this relay server and embedded dashboard
PORTAL_FRONTEND_DIR "" string Custom SPA directory containing index.html; empty uses the frontend embedded in the Portal binary
IDENTITY_PATH ./.portal-certs string Directory path for relay identity, policy state, and TLS materials
API_PORT 4017 int Admin/API server listen port
SNI_PORT 443 int TCP SNI router listen port; non-standard values are intended for local testing, while the bundled public deployment requires 443
WIREGUARD_PORT 51820 int Public and listen UDP port for relay discovery overlay

Transport

Variable Default Type Description
MIN_PORT 0 int Inclusive minimum port for UDP and raw TCP transports (0 = disabled)
MAX_PORT 0 int Inclusive maximum port for UDP and raw TCP transports (0 = disabled)
UDP_ENABLED false bool Enable UDP relay transport; requires a valid MIN_PORT/MAX_PORT range
TCP_ENABLED false bool Enable raw TCP port transport; requires a valid MIN_PORT/MAX_PORT range

Features

Variable Default Type Description
DISCOVERY false bool Serve relay discovery endpoints and poll discovery peers
BOOTSTRAPS "" string Additional bootstrap relay API URLs used for discovery expansion (comma-separated)
LANDING_PAGE_ENABLED false bool Initial dashboard landing-page visibility; admin changes are persisted in the relay policy state

Payments

Variable Default Type Description
X402_ENABLED false bool Enable relay-owned Sui x402 facilitator endpoints under /api/x402 for future control-plane payments
X402_TESTNET false bool Use Sui testnet for relay-owned x402 facilitator payments; false uses Sui mainnet
X402_PAY_TO "" string Sui payment recipient address for relay-owned control-plane x402 resources

Proxy

Variable Default Type Description
TRUST_PROXY_HEADERS false bool Trust X-Forwarded-* and X-Real-IP headers from trusted proxies
TRUSTED_PROXY_CIDRS "" string Trusted proxy CIDR allowlist for forwarded headers (comma-separated); defaults to private/loopback ranges when TRUST_PROXY_HEADERS is enabled

TLS

Variable Default Type Description
ACME_DNS_PROVIDER "" string DNS provider for managed DNS-01/A-record sync, the relay ECH record, opt-in tunnel ECH records, and ENS gasless DNSSEC/TXT automation (embedded | cloudflare | gcloud | hetzner | njalla | route53 | vultr); unset defaults to embedded; manual fullchain.pem/privatekey.pem in IDENTITY_PATH is used when present
ENS_GASLESS_ENABLED false bool Enable ENS gasless DNS import automation for the managed DNS zone and lease hostnames; not supported with ACME_DNS_PROVIDER=embedded yet

Embedded DNS

This section is the canonical reference for embedded DNS configuration. The deployment and self-hosting guides link here rather than restating the details.

Serves the relay base domain from an authoritative DNS server embedded in the relay process, so no DNS provider API credentials are required. It is the default provider when ACME_DNS_PROVIDER is unset. Delegate the base domain once at the parent zone (NS portal.example.com -> ns.portal.example.com with glue A pointing at the relay public IP) and open 53/tcp + 53/udp. Containers running without root need CAP_NET_BIND_SERVICE to bind the default port. A answers for the apex and every covered name are synthesized from the relay public IPv4; ACME DNS-01 TXT and tunnel ECH HTTPS records are served directly. ENS gasless automation (zone DNSSEC) is not supported yet.

Variable Default Type Description
EMBEDDED_DNS_PORT 53 int Listen port for the embedded authoritative DNS server (UDP and TCP)

Diagnostics

Variable Default Type Description
PPROF_ENABLED false bool Enable the relay pprof diagnostics HTTP server
PPROF_ADDR 127.0.0.1:6060 string pprof listen address when enabled; keep it on loopback unless the port is protected

Admin

Variable Default Type Description
ADMIN_TOKEN string Bearer token source for relay admin and policy APIs; set a long random value for production relays

Cloudflare

Variable Default Type Description
CLOUDFLARE_TOKEN string Cloudflare DNS API token; required when ACME_DNS_PROVIDER=cloudflare

Google Cloud

Variable Aliases Default Type Description
GCP_PROJECT_ID GOOGLE_CLOUD_PROJECT, GCLOUD_PROJECT, GCE_PROJECT string Google Cloud project ID for Cloud DNS automation; auto-detected from ADC or GCE metadata when omitted
GCP_MANAGED_ZONE GCP_ZONE, GCE_ZONE_ID string Explicit Google Cloud DNS managed zone name or numeric ID override
GOOGLE_APPLICATION_CREDENTIALS string Path to GCP service account key file (standard ADC; used by the GCP client library)

Hetzner

Variable Aliases Default Type Description
HETZNER_API_TOKEN HCLOUD_TOKEN string Hetzner Cloud API token for DNS automation; required when ACME_DNS_PROVIDER=hetzner

AWS

Variable Aliases Default Type Description
AWS_ACCESS_KEY_ID string AWS access key ID for Route53 static credentials; uses the default AWS credential chain when omitted
AWS_SECRET_ACCESS_KEY string AWS secret access key for Route53 static credentials
AWS_SESSION_TOKEN string AWS session token for Route53 temporary credentials
AWS_REGION AWS_DEFAULT_REGION us-east-1 string AWS region for Route53 and Route53-backed DNS-01
AWS_HOSTED_ZONE_ID string Explicit Route53 hosted zone ID override
AWS_DNSSEC_KMS_KEY_ARN string AWS KMS key ARN used to create a Route53 DNSSEC key-signing key when needed

Vultr

Variable Default Type Description
VULTR_API_KEY string Vultr API key for DNS automation; required when ACME_DNS_PROVIDER=vultr

Njalla

Variable Default Type Description
NJALLA_TOKEN string Njalla API token for DNS automation; required when ACME_DNS_PROVIDER=njalla

Portal Tunnel CLI Flags

The portal expose subcommand accepts the following flags. Flags that read from environment variables are noted in the Env Var column.

Connection

Flag Env Var Type Default Description
--relays string (registry) Additional Portal relay server API URLs (comma-separated; scheme omitted defaults to https)
--discovery bool true Include public registry relays and discover additional relay bootstraps
--multi-hop MULTI_HOP string Ordered multi-hop relay API URLs, comma-separated
--multi-hop-depth MULTI_HOP_DEPTH int 0 Automatically create this-depth multi-hop routes for every eligible entry relay; 0 or 1 disables multi-hop
--max-active-relays MAX_ACTIVE_RELAYS int 3 Maximum auto-selected single-hop relays to keep connected; multi-hop uses every eligible relay as an entry; explicit relays are always included
--ban-mitm BAN_MITM bool false Ban relay when the MITM self-probe detects TLS termination

Identity

Flag Env Var Type Default Description
--identity-path IDENTITY_PATH string identity.json Identity JSON file path
--identity-json IDENTITY_JSON string Identity JSON payload; overrides --identity-path contents and is persisted there when both are set

Lease

Flag Env Var Type Default Description
--name string (auto) Public hostname prefix (single DNS label); auto-generated when omitted
--description string Service description metadata
--tags string Service tags metadata (comma-separated)
--owner string Service owner metadata
--thumbnail string Service thumbnail URL metadata
--hide bool false Hide service from relay listing screens
--x402-pay-to string Payment recipient address for this tunnel
--x402-testnet bool false Use Sui testnet when --x402-network is omitted
--x402-network string Optional Sui or Casper CAIP-2 network
--x402-asset string wCSPR CEP-18 contract hash required by Casper
--x402-endpoint string Optional Sui RPC or Casper facilitator endpoint; repeatable
--x402-facilitator-token CSPR_CLOUD_API_KEY string Casper facilitator authorization token

Routing

Flag Env Var Type Default Description
--http-route string HTTP route mapping in PATH=UPSTREAM [METHOD[,METHOD...]:PAYMENT_AMOUNT] form; repeat to aggregate multiple local HTTP services behind one public URL; route amounts require --x402-pay-to

Transport

Flag Env Var Type Default Description
--udp UDP_ENABLED bool false Enable public UDP relay in addition to the default stream path
--udp-addr UDP_ADDR string Local UDP target address for relayed datagrams (host:port or port only); defaults to the target when --udp is enabled
--tcp TCP_ENABLED bool false Request a dedicated TCP port on the relay for raw TCP services (no TLS; e.g., Minecraft, game servers)

The portal list subcommand accepts the following flags:

Flag Type Default Description
--relays string (registry) Additional Portal relay server API URLs (comma-separated)
--default-relays bool true Include public registry relays

Configuration Files

config.toml

portal agent run reads the platform default config.toml and starts one managed process for all declared tunnels. Relative paths are resolved from the config file directory. The config file must exist before the agent is started.

Default paths:

OS Config Default identity
Linux user $XDG_CONFIG_HOME/portal-tunnel/agent/config.toml or ~/.config/portal-tunnel/agent/config.toml $XDG_DATA_HOME/portal-tunnel/agent/identity.json or ~/.local/share/portal-tunnel/agent/identity.json
Linux root /etc/portal-tunnel/agent/config.toml /var/lib/portal-tunnel/agent/identity.json
macOS user ~/Library/Application Support/Portal Tunnel/Agent/config.toml ~/Library/Application Support/Portal Tunnel/Agent/identity.json
macOS root /Library/Application Support/Portal Tunnel/Agent/config.toml /Library/Application Support/Portal Tunnel/Agent/identity.json
Windows %ProgramData%\Portal Tunnel\Agent\config.toml %ProgramData%\Portal Tunnel\Agent\identity.json
[agent]
control_addr = "127.0.0.1:4018"
service_name = "portal-agent"

[[tunnels]]
id = "web"
name = "myapp"
target = "127.0.0.1:3000"
relays = ["https://portal.example.com"]
discovery = false
description = "Managed web tunnel"
tags = ["web"]

[[tunnels]]
id = "api"
name = "myapp"
x402_pay_to = "0x..."
x402_testnet = true

[[tunnels.http_routes]]
prefix = "/api"
upstream = "http://127.0.0.1:3001"
methods = ["GET"]
amount = "0.01"

[[tunnels.http_routes]]
prefix = "/"
upstream = "http://127.0.0.1:5173"

Agent fields:

Field Default Description
state_dir Platform default state directory Stores the local control endpoint token and runtime state
control_addr 127.0.0.1:4018 Loopback-only local control API address
service_name portal-agent OS service name
allowed_wallets empty Wallet addresses allowed to read local agent status through wallet auth; empty allows any wallet on the loopback auth endpoint

The local agent dashboard and mutating control API calls use the bearer token in the agent state directory. Wallet-authenticated agent requests are read-only and can only read /agent/status.

Tunnel fields mirror portal expose flags:

Field Type Description
id string Stable tunnel ID used by the agent dashboard
target string Local TCP target, equivalent to the portal expose <target> argument
http_routes table array HTTP route mappings; cannot be combined with target or udp
relays string array Explicit relay API URLs
discovery bool Include registry and relay discovery expansion
multi_hop string array Ordered multi-hop relay path
multi_hop_depth int Automatically create this-depth multi-hop routes for every eligible entry relay
ech bool Enable ECH hostname privacy for TLS stream tunnels; defaults to false
identity_path string Tunnel identity JSON file path. When omitted, one tunnel uses the platform default identity.json; multiple tunnels use <state-dir>/<tunnel-id>/identity.json
identity_json string Identity JSON payload; overrides identity_path contents and is persisted there when both are set
udp, udp_addr, tcp bool/string UDP and raw TCP relay options
description, tags, owner, thumbnail, hide mixed Lease metadata shown by relays
x402_pay_to string Payment recipient for paid HTTP routes
x402_testnet bool Use Sui testnet when x402_network is omitted; omitted or false uses Sui mainnet
x402_network string Optional CAIP-2 network: sui:mainnet, sui:testnet, casper:casper, or casper:casper-test
x402_asset string wCSPR CEP-18 contract hash; required for Casper payments
x402_endpoints string array Optional Sui RPC endpoints or Casper facilitator URL; Casper uses the first endpoint
x402_facilitator_token string Casper facilitator authorization token; when omitted, the agent uses CSPR_CLOUD_API_KEY
http_routes[].amount string Optional human payment amount, such as 0.01, for one HTTP route prefix; requires x402_pay_to
http_routes[].methods string array Optional HTTP methods that require payment on that route; empty means every method

When any routed HTTP entry has amount, the tunnel also serves /x402/client.js and /x402/prepare on the public tunnel origin. Browser frontends served by another route in the same tunnel can import /x402/client.js and use x402Fetch() for Sui payments. Casper clients read the 402 requirements from the protected resource, sign them with a compatible external SDK, and retry with PAYMENT-SIGNATURE or X-PAYMENT; the embedded browser client remains Sui-only. Payment is enforced by the tunnel before the request reaches the upstream.

x402 payment networks

Network Asset Decimals Facilitator
sui:mainnet, sui:testnet USDC gasless stablecoin 6 Built-in Sui facilitator
casper:casper, casper:casper-test wCSPR CEP-18 token 9 https://x402-facilitator.cspr.cloud, overridable per payment

Casper has no Go chain SDK, so casper:* payments delegate /verify and /settle to a remote x402 facilitator over HTTP. The wCSPR CEP-18 contract hash differs per network deployment, so it must be set as the payment asset. The default CSPR.cloud facilitator requires an access token in CSPR_CLOUD_API_KEY; use x402_facilitator_token only when the agent service cannot receive that environment variable.

x402_network = "casper:casper-test"
x402_asset = "hash-..."
x402_pay_to = "account-hash-..."
x402_endpoints = ["https://x402-facilitator.cspr.cloud"]

For a task-oriented walkthrough, see Portal Agent.

identity.json

Stores the secp256k1 identity used to sign tunnel sessions and relay descriptors. portal expose treats --identity-path as a direct JSON file path. relay-server treats IDENTITY_PATH as a state directory and stores this file at IDENTITY_PATH/identity.json.

Field Type Description
name string Human-readable label for this identity
address string Derived EVM address used for SIWE and identity ownership
public_key string Compressed secp256k1 public key hex
private_key string secp256k1 private key hex; keep secret
mnemonic string BIP-39 mnemonic used to derive the secp256k1 identity key; keep secret
derivation_path string EVM derivation path for mnemonic; defaults to m/44'/60'/0'/0/0
wireguard_public_key string Relay-only WireGuard overlay public key when discovery is enabled
wireguard_private_key string Relay-only WireGuard overlay private key when discovery is enabled
encrypted_client_hello_seed string Relay-only HKDF salt for deriving the ECH HPKE private key; generated automatically when missing; keep secret

When mnemonic is present, Portal derives the private key at derivation_path and preserves the mnemonic form when rewriting identity.json. The same identity file or state directory can be reused across restarts to keep a stable address.

policy.json

Persists relay policy state. Managed automatically by the relay on write; do not edit manually while the server is running.

Relay policy settings are stored at IDENTITY_PATH/policy.json.


ACME DNS Provider Configuration

Set ACME_DNS_PROVIDER (or --acme-dns-provider) to one of the values below to enable DNS-backed automation. Portal uses the same provider for DNS-01 challenges, managed A records, the relay root HTTPS/ECH record, tenant A and HTTPS/ECH records for tunnels with ech = true, and optional ENS gasless DNS records. The default ech = false tunnel mode does not create tenant ECH DNS records.

When this variable is empty the relay server falls back to manually supplied fullchain.pem and privatekey.pem files in IDENTITY_PATH.

For ENS gasless behavior and wallet authentication details, see Wallet and ENS.

Cloudflare (cloudflare)

Variable Required Description
CLOUDFLARE_TOKEN Yes Cloudflare DNS API token with Zone:DNS:Edit permission

Google Cloud DNS (gcloud)

Variable Required Description
GCP_PROJECT_ID No Google Cloud project ID; auto-detected from ADC or GCE metadata when omitted
GCP_MANAGED_ZONE No Cloud DNS managed zone name or numeric ID; inferred from the portal domain when omitted
GOOGLE_APPLICATION_CREDENTIALS No Path to a service account key JSON file; uses Application Default Credentials when omitted

AWS Route53 (route53)

Variable Required Description
AWS_ACCESS_KEY_ID No Access key ID; uses the default AWS credential chain (instance profile, env, ~/.aws/credentials) when omitted
AWS_SECRET_ACCESS_KEY No Secret access key; required when AWS_ACCESS_KEY_ID is set
AWS_SESSION_TOKEN No Session token for temporary credentials
AWS_REGION No AWS region; defaults to us-east-1
AWS_HOSTED_ZONE_ID No Route53 hosted zone ID; inferred from the portal domain when omitted
AWS_DNSSEC_KMS_KEY_ARN No KMS key ARN for DNSSEC key-signing key creation

Hetzner DNS (hetzner)

Variable Required Description
HETZNER_API_TOKEN Yes Hetzner Cloud API token with DNS zone and RRSet write access

Note: Hetzner DNS does not support provider-side DNSSEC signing, so ACME_DNS_PROVIDER=hetzner supports ACME, A records, and HTTPS/ECH records, but not ENS gasless DNSSEC automation.

Njalla DNS (njalla)

Variable Required Description
NJALLA_TOKEN Yes Njalla API token with DNS record write access

Note: Njalla supports managed ACME, A records, TXT records, and HTTPS/ECH records. Portal does not automate Njalla DNSSEC signing, so ACME_DNS_PROVIDER=njalla does not support ENS gasless DNSSEC automation.

Vultr DNS (vultr)

Variable Required Description
VULTR_API_KEY Yes Vultr API key with DNS domain, record, and DNSSEC write access