YUME Internet freedom by FixCraft
On this page

Configuration reference

yume and yumed each read one JSON document in schema 1. yume-setup writes both, and --validate checks one without starting anything. This page lists every key. The parser, src/config/v1/config.cpp, is the authority, and tests/test_config_reference.py fails when a key it accepts is missing here.

Every object is closed: an unknown or misspelled key fails with its JSON pointer, as do a wrong type, a value out of range and an unsupported value. The document is at most 1 MiB and 16 levels deep. Network and security policy come only from this file. No command-line option overrides them.

File references

Keys that name a file take an object with one key, file, such as {"file": "credentials/admission.key"}. A relative path resolves against the configuration file’s directory. The path is at most 4096 bytes and may not be empty, contain control characters or surrounding space, start with ~, be a URI or contain ... Text that looks like key material, a PEM block or 64 hexadecimal characters, is refused as an inline secret. When the program loads a secret, the file must be a regular file owned by its user with no group or other permission bits.

Top level

Key Roles Required Meaning
schema both yes 1
role both yes client or server
endpoint both yes Where the client connects, or where the server listens
suite both yes The one YTP/1 composition, spelled out
credentials both yes File references to keys and trust stores
cover both yes The browser profile, and a server’s cover site
services both yes The named services a session may open
adapters both yes What connects each service to the host, up to 16
limits both yes Resource bounds of each session
control both no The owner-only control socket
cluster server no Membership of an operator’s cluster
circuits client no Routing through a cluster’s circuits

endpoint

A client names its server:

Key Required Meaning
host yes The server’s DNS name or IP literal, at most 253 bytes. TLS and admission authenticate this name
port yes 1 to 65535
connect_address no An IP literal dialled instead of resolving host. Managed TUN default routing needs it, or a numeric host, to exclude the transport
socks5_proxy no A SOCKS5 proxy to reach the server through: address (an IP literal), port, and optional credentials, a protected file of a username line and a password line of 1 to 255 bytes each. The proxy resolves host unless connect_address is set

A server lists where it listens: listen_addresses, 1 to 16 distinct IP literals, and port. Its optional event_loops, 1 to 64, is how many threads serve sessions. Absent, it is the number of CPUs the process may run on, at most 16. One loop accepts every connection and hands each to the loop serving the fewest sessions, where its TLS, cover, admission, authentication and session stay for their whole life, so one session uses at most one core and several sessions share the cores. A configuration with a cluster section or a packet adapter refuses a value above 1 and runs one loop when the key is absent: a circuit relays cells between sessions, and a packet adapter serves one device to one session.

An IP literal is IPv4 as four decimal parts of 0 to 255 without leading zeros, or IPv6 text in either case with at most one :: and an optional dotted IPv4 tail. A leading zero is refused because the system resolver reads 010 as octal 8, so 010.0.0.1 would reach 8.0.0.1.

suite

YTP/1 has one composition, so every value is fixed: id is ytp1-tls13-h2, secure_channel is tls13-native, front_door is h2-web, carrier is h2-duplex and session is ytp1-hybrid. Another value fails rather than selecting a different provider.

credentials

A client names six files:

Key Holds
composite_key The client’s composite Ed25519 and ML-DSA-87 private key
access_psk The client’s 32-byte access PSK, which must differ from the admission key
admission_key The server’s 32-byte admission key
server_trust The TLS trust the client verifies the server’s certificate with
server_identity The server’s composite public identity
server_mlkem The server’s ML-KEM-1024 public key

A server names seven:

Key Holds
composite_key The server’s composite private key
authorized_keys The client identities allowed traffic, each with its access PSK, granted services and optional max_sessions and weight
admin_keys Reserved second-factor identities in a separate store from authorized_keys. The second-factor AUTH exchange is planned; this store grants no traffic
tls_certificate, tls_key The TLS certificate chain and its private key
admission_key The 32-byte admission key
mlkem_key The server’s ML-KEM-1024 private key

Operations describes the identity stores.

cover

profile names the captured browser profile, which must be the one this build qualifies, chrome151-node24-v1. A client has nothing else here. A server adds exactly one of:

  • root, a file reference to the directory of the static cover site. It must hold an index and a not-found page, and yumed loads it at start.
  • reverse_proxy, with url http://127.0.0.1:PORT or http://[::1]:PORT. The parser accepts it, and yumed refuses to start with it, because the reverse-proxy cover is not implemented yet.

services

1 to 64 services, unique by name and kind:

Key Meaning
name 1 to 128 bytes of dot-separated segments of lowercase ASCII letters and digits, with - and _ allowed inside a segment. Names whose first segment is yume belong to the daemon and are refused
kind stream or packet
max_concurrent_streams 1 to 65535 open streams of this service per session

adapters

Each adapter has a kind and the service it serves, which must be declared with the kind the adapter needs. At most one direct_tcp or module adapter handles a stream service.

Kind Role Keys
socks5 client listen_address (127.0.0.1 or ::1), listen_port, and optional udp_service, the packet service UDP ASSOCIATE opens. Without it UDP ASSOCIATE is refused
forward client Either listen_address (127.0.0.1 or ::1) with listen_port, or listen_path, an absolute normalized socket path of at most 107 bytes. Optional destination with host and port. SOCKS5 and forward listeners may not share an address and port
packet both interface_name (at most 15 bytes), mtu (576 to 65535, at most limits.max_packet_bytes) and network: addresses, routes, local_networks, peer_networks and dns with servers and domains, described in managed TUN
module server socket, the absolute normalized path of the module’s listening socket, at most 107 bytes. It must belong to the daemon’s user with no group or other access, in a directory only root or that user can write. Modules describes the protocol and the systemd units
direct_tcp, direct_udp server destinations, below. direct_tcp serves a stream service and direct_udp a packet service

destinations says where a direct adapter may connect:

Key Required Meaning
public yes true permits globally reachable unicast addresses
networks yes Up to 64 canonical prefixes, such as 10.0.0.0/8. At least one of public and networks must permit something
lists no Up to 16 egress lists, each {"action": "deny" or "allow", "format": "json" or "vpdb", "file": path}, which only narrow what public and networks permit
country_database no A MaxMind country database file, needed by a list that names countries

Public space excludes private, shared, loopback, link-local, documentation, benchmarking, 6to4, Teredo and NAT64 prefixes, and unspecified, multicast and reserved addresses are always refused. IPv4-mapped IPv6 is evaluated as IPv4. Every address a destination name resolves to is checked before a socket opens. In an egress list the most specific entry decides and a deny wins a tie. A JSON list holds ips, addresses or networks with zero host bits, and countries, two-letter codes, and a country entry loses to any address entry. A vpdb file is the binary VPN provider database, format 1. A JSON list may hold 16 MiB, the other files 128 MiB, and all lists together 2,097,152 ranges. List files are read when yumed starts or validates.

limits

Key Range Meaning
max_frame_bytes 1676 to 1048576 The largest frame, at most max_queued_bytes. The minimum fits a rekey INIT
max_streams 1 to 65535 Open streams per session
max_queued_bytes 65536 to 67108864 The session’s byte budget. Receive windows grow up to it, so a far path is faster with more. A session holds up to the budget of outbound data and twice the budget, at least 8 MiB, of received records
max_pending_opens 1 to 1024 OPENs waiting for an answer, at most max_streams
max_rekey_jobs 2 to 64 Rekey operations in flight, two for a crossed rotation
max_control_messages 8 to 4096 Connection control records, such as PONG and rekey messages, queued for sending. Credit and CLOSE records are bounded per receive window and per stream instead
max_packet_bytes 576 to 65535 The largest packet, at most max_frame_bytes
max_packet_batch 1 to 256 The most packets one C ABI packet read or write call moves
max_epoch_bytes 1 MiB to 64 MiB, a power of two, 1 MiB when absent The most payload one directional key epoch protects. A session uses the smaller of the two sides’ values
credit_returns_per_window 2, 4 or 8, 2 when absent Normal batching frequency for a receive window at its maximum. More lets a far sender use more of the window, and sends more small records upstream. Consumed connection credit also returns early when the peer has less than one maximum frame left; see YTP/1 flow credit
idle_epoch_rotation true or false, false when absent Whether this side rotates a key epoch that has carried records once it is 250 ms old, without waiting for its next send. The first send after a pause then needs no extra round trip, but each burst ends with a rekey exchange of about 1.7 KB each way, which the browser captures do not show
max_egress_mbps 1 to 1000000, server only The rate stream payload shares between busy identities by their weight

control

socket is an absolute normalized path of at most 107 bytes that no forward uses. The running program serves its status there to processes of its own user, and --status reads it. The socket’s directory must belong to that user and be closed to writes by group and others. Control protocol 1 is the contract.

cluster

A server in an operator’s cluster names the files of its membership: operator_key, list, signature, routes, routes_signature, peers and state. The daemon writes state itself, so its directory must be writable. An optional exit with service names the direct_tcp adapter a circuit exit leaves through.

circuits

A client that routes through a cluster’s circuits:

Key Required Meaning
hops yes 2 or 3 servers per circuit
min_hops no The shortest route used without asking, 1 to hops, hops when absent
plain_http no refuse, the default, ends plain HTTP before it leaves the client. allow lets it through
operator_key, routes, routes_signature, state yes File references to the operator’s key, the routes view and its signature, and the client’s state

With circuits, every SOCKS5 CONNECT and forward to a destination leaves through a circuit, UDP ASSOCIATE is refused and a packet adapter is not allowed. yume-setup add-client --circuits writes this section.

Tuning presets

yume-setup init --preset NAME writes one of five combinations for max_queued_bytes, max_epoch_bytes, credit_returns_per_window and idle_epoch_rotation into both configurations, and add-client gives a new client the server’s settings. yume-doctor names the preset a configuration matches, or reports custom. config/tuning_presets.json holds the same table for other tools.

Preset Budget Epoch Credit returns Idle rotation Speed Security Stealth
stealth, the default 4 MiB 1 MiB 2 off 1 4 4
stealth-16 4 MiB 16 MiB 2 off 2 2 4
balanced 16 MiB 4 MiB 2 off 3 3 3
fast 32 MiB 16 MiB 4 on 4 2 2
max 64 MiB 64 MiB 8 on 5 1 1

Speed has five positions; security and stealth have four. Each stands for a measured or stated effect. Speed orders the measured combinations, with fast and max ahead only on hosts with raised TCP ceilings. It is not a universal throughput score. Security follows how much data one key epoch protects: 1, 4, 16 or 64 MiB, and never more than 500 ms of sending. Stealth is 4 for the settings the browser captures describe. Lower levels use a larger HTTP/2 receive window or send more small credit records upstream, changes that have no capture or classifier evidence yet. fast and max also rotate idle keys, whose rekey exchange after each burst the captures show a browser session does not send. Without it a request after more than half a second of quiet waits one round trip for the new key. The stealth level describes only windows, credit records and idle rotation; changing the epoch also changes rekey frequency. It proves no classifier result.

The table owns coupling.rule (nearest-levels-v1): when a slider moves, keep its requested level and choose the combination minimizing the sum of absolute differences on the other two axes from the current combination. Break ties by higher stealth, then higher security, then lower speed, then table order. This operates on combinations, never interpolated limit values. Custom limits stay custom until the user explicitly chooses a combination. The table’s fields describe labels, units and divisors for the plain-terms panel; each combination’s measurement refers to a conditions record in measurements. Consumers embed this table unchanged.

A separate comparison at default 6 MiB host TCP ceilings measured stealth at 41.4, 41.8 and 41.9 percent of the direct path at 40, 100 and 200 ms RTT. stealth-16 reached 62.4, 59.2 and 58.6 percent; balanced reached 99.1, 97.0 and 95.6 percent. These are tail-rate medians of six 12-second single-download samples per condition on one host’s loss-free emulated paths, with both peers configured alike. A 64 MiB epoch with stealth’s other limits added no throughput, so it is not another preset. These measurements are not real-path speed or stealth claims.

To change an existing client, use yume-setup tune --config FILE --preset stealth-16, or set one expert value with --set max_epoch_bytes=2097152. The latter accepts any schema-valid value of the four tuning keys. Both validate the entire original and resulting configuration, then atomically replace the file while preserving other members. Restart the client to apply it. The command changes the client’s allowance. While connected, posture.epoch_bytes reports the negotiated epoch, and posture.limits reports the client’s configured limits. See yume-setup(1) for file handling and failure behavior.

One emulator run on one host measured these rates for a single download, in Mbit/s at 40, 100 and 200 ms round trips without loss, each preset with its own idle rotation setting:

Preset Default host TCP buffers 64 MiB host TCP buffers
stealth 176, 78, 39 180, 78, 40
balanced 423, 176, 94 653, 284, 155
fast 417, 179, 93 2384, 1095, 579
max 415, 177, 92 3038, 2499, 1333

An earlier run with idle rotation on in every preset measured rates within 10 % of these, and a small request took the same time. With Linux’s default 6 MiB ceilings, one TCP connection holds about 2 MiB per round trip whether it is tunnelled or not, and the untunnelled download moved 434 to 437, 186 to 189 and 98 Mbit/s. balanced already reaches about 95 % of that, so fast and max are faster only on a host with raised ceilings. The emulator handles packets in software, which caps its rates below a real network card, and none of these rates is a claim about a real path.

Some limits hold for every preset. Keys always rotate, a session uses the smaller epoch that either side allows, and a server can therefore hold its clients to a stricter setting than theirs. A larger budget needs memory, and far-path speed above a few MiB per round trip also needs the host’s TCP buffer ceilings raised, for the tunnel as for any other single TCP connection.