CLI
The ngstone command is built on the stdlib flag package — no cobra, no subcommand framework. There are five verbs: auth, port, config, logout, and version.
Overview#
ngstone <command> [arguments] Commands: auth <token> verify and save an auth token port <port|url> expose a local port or URL through the tunnel config view or set local configuration logout remove the saved auth token version print the ngstone versionngstone auth#
Verifies a token against the edge's control plane, then saves the token and server address to the config file. Nothing is written to disk until the edge has confirmed the token is valid.
$ ngstone auth <token>verified against ngstone.site:4443 and savedngstone.site:4443 if neither is set.ServerName/SNI to verify against. Ignored with --insecure.--pin sha256/BASE64, checked in addition to normal chain validation. Off by default.A bad token or an unreachable server exits non-zero with a specific, actionable message rather than a generic failure.
ngstone port#
Starts a tunnel to a local port or URL. This is the command that actually opens a connection to the edge and forwards traffic. When stdout is a terminal, it also opens a full-screen inspector dashboard showing every request and response live, with headers, decoded bodies, timing, and replay — see Using the request inspector.
$ ngstone port 3000$ ngstone port http://127.0.0.1:3000$ ngstone port 3000 --subdomain demoThe positional argument is either a bare port number (forwarded to http://127.0.0.1:<port>) or a full target URL. Flags may appear before or after it.
--subdomain demo for demo.ngstone.site.ngstone.site:4443.NGSTONE_TOKEN or the token saved by ngstone auth.ServerName/SNI to verify against. Ignored with --insecure.&), so this flag mainly matters when stdoutis a terminal and you still want plain logs.ngstone config#
Read or change the local config file without hand-editing JSON.
$ ngstone config set server ngstone.site:4443server set to ngstone.site:4443 $ ngstone config gettoken: nst_a1b2…9f3dserver: ngstone.site:4443 $ ngstone config get tokennst_a1b2…9f3d $ ngstone config path/home/you/.config/ngstone/config.jsonconfig get always redacts the token — the middle of the value is replaced with …, only the first and last four characters are shown.
ngstone logout#
Clears the saved token from the config file. The server address is left untouched.
$ ngstone logoutlogged outngstone version#
Prints the build's version string, injected at compile time via -ldflags.
$ ngstone versionngstone v0.1.0 (commit 3f1a9c2, built 2026-06-01T12:00:00Z)No arguments and -h#
Running ngstone with no arguments does not start a tunnel — it prints usage to stderr and exits 1. -h, --help, and -help print the same usage to stdout and exit 0.
Generating a token#
There is no ngstone token command
TOKEN=$(openssl rand -base64 32 | tr '+/' '-_' | tr -d '=')HASH=$(printf '%s' "$TOKEN" | shasum -a 256 | cut -d' ' -f1) # sha256sum on LinuxKeep $TOKEN for ngstone auth on every machine that will run the agent, and pass $HASH to the edge as -token-sha256 (or $NGSTONE_TOKEN_SHA256). There is exactly one token per edge — rotating it invalidates every agent at once, since it changes what the edge accepts, not something per-agent.
The config file#
ngstone auth, ngstone port, ngstone config, and ngstone logout all read and write the same JSON file:
$XDG_CONFIG_HOME/ngstone/config.json# falls back to ~/.config/ngstone/config.json if XDG_CONFIG_HOME is unsetThe file holds token and server. It's written with mode 0600 inside a 0700 directory, and saved via a temp-file-plus-rename so a crash mid-write can't corrupt it.
Resolution order for both the token and the server address:
--token / --server on the command invoking it.NGSTONE_TOKEN. There is no environment override for the server address.ngstone auth or ngstone config set last saved.Legacy flag form#
A flat-flags invocation is still supported alongside the verbs above, mainly for scripts and the e2e test suite written against it. It starts a tunnel directly — there's no config file involved.
$ ngstone -control ADDR -token TOK -target URL -subdomain NAME \ -insecure -server-name NAME -pin SPKI -instance-id IDNGSTONE_TOKEN if unset.Prefer ngstone auth plus ngstone port for day-to-day use — the legacy form exists for compatibility, not as the recommended path.