Runtime Targeting
Everything in RayLimit starts with selecting one runtime target. If runtime selection is weak, everything after it becomes weak.
Supported Runtime Selectors
The public CLI supports these runtime selectors:
--pid <pid>--container <id-or-name>--name <name>- optional
--source host_process|docker_container
For limit, exactly one runtime must be selected. For inspect, you can also use --all to inspect every matching target.
What Runtime-Local Means
Runtime locality is part of the product contract:
- one runtime plus one subject equals one limiter identity
- another runtime gets a different identity even if the tag or IP string is the same
- observation, reconcile, and cleanup all stay inside that runtime boundary
That matters directly for the IP model. --ip all is always scoped to one selected runtime only. In shared mode it is one runtime-local shared baseline. In per_ip mode it expands only the client IPs currently proven for that runtime. It is not a host-global default and it does not automatically cover other runtimes on the same host.
Selection Rules That Matter In Practice
inspectcan run without selectors and show every discovered targetlimitrequires exactly one runtime--pidand--containercannot be combined--source=docker_containercannot be used with--pid--source=host_processcannot be used with--container
If you match multiple runtimes with inspect and do not pass --all, RayLimit stops and asks you to refine the selection instead of choosing one silently.
Common Selection Patterns
Select one host process:
sudo raylimit inspect --pid 1234
sudo raylimit limit --pid 1234 --ip all --device eth0 --direction upload --rate 4096Select one Docker runtime:
sudo raylimit inspect --source docker_container --container xray-edge
sudo raylimit limit --source docker_container --container xray-edge --outbound proxy-out --device eth0 --direction upload --rate 2048Select by discovered name:
sudo raylimit inspect --name edge-eu
sudo raylimit limit --name edge-eu --inbound api-in --device eth0 --direction upload --rate 2048Inspect every runtime from one discovery source:
sudo raylimit inspect --source host_process --allBinary Detection And Resolution
Before a runtime can be selected, discovery has to recognize it as an Xray-family process or container, then resolve which binary to query.
Prefix-Match Detection
Detection normalizes a binary basename (lowercase, trailing .exe removed) and prefix-matches it against an allowlist:
xrayxray-coresanaeisanaei-core
Because the match is a prefix match, OS/arch release names and fork builds are recognized without extra configuration: xray-linux-amd64, xray-darwin-arm64, sanaei-linux-amd64, and even the 15-character /proc/<pid>/comm truncation (xray-linux-amd6). The Sanaei fork is detected through the sanaei* prefixes; vanilla Xray is detected through xray*.
Docker Detection Signals
For container runtimes, detection combines four signal classes and keeps the highest confidence while retaining every matched reason:
| Signal | Source | Confidence |
|---|---|---|
| Image repository base | container image name | High |
| Container command | entrypoint/command | High |
| Container labels | app, com.docker.compose.service, org.opencontainers.image.title | Medium |
| Published API port | port bindings, default 10085 | Low |
app is matched as a prefix; com.docker.compose.service and org.opencontainers.image.title are matched as substrings.
When running containers are scanned but none match any signal, discovery records a no_matches limitation (it is a limitation, not a fatal error — other discovery sources still return their results).
Binary-Name Resolution Precedence
When RayLimit queries the Xray API, it resolves the binary in this order:
For host runtimes:
--xray-binary(orRAYLIMIT_XRAY_BINARY)- the detected absolute executable path (
HostProcess.ExecutablePath) - the detected binary basename (
Identity.Binary) - the literal
"xray"fallback
For container runtimes:
--xray-binary(orRAYLIMIT_XRAY_BINARY)- the detected in-container binary basename
- the literal
"xray"fallback
Use --xray-binary when the fork binary lives at a non-standard path:
sudo raylimit discover --xray-binary /opt/sanaei/sanaei-linux-amd64Container CLI Override
Discovery and container queries default to docker. Use --container-cli (or RAYLIMIT_CONTAINER_CLI) to select podman or nerdctl:
sudo raylimit discover --container-cli podmanWhy Selection Discipline Matters
If runtime selection is ambiguous:
- the limiter subject changes
- the runtime evidence source changes
- the managed owner identity changes
- the cleanup target changes
For that reason, RayLimit validates runtime selection early instead of continuing with a weak target identity.