DocsReferenceCLI

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 version

ngstone 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 saved
--serverstring
Edge control-plane address to verify against. Defaults to the config file's saved server, or ngstone.site:4443 if neither is set.
--insecurebooldefault: false
Dial the control plane in plaintext. Dev/test only — no certificate validation happens at all.
--server-namestring
TLS ServerName/SNI to verify against. Ignored with --insecure.
--pinstring
Optional SPKI pin, e.g. --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 demo

The 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, -sstring
Request a specific subdomain instead of a server-assigned one, e.g. --subdomain demo for demo.ngstone.site.
--serverstring
Edge control-plane address override. Defaults to the config file or ngstone.site:4443.
--tokenstring
Auth token override. Defaults to NGSTONE_TOKEN or the token saved by ngstone auth.
--insecurebooldefault: false
Dial the control plane in plaintext (dev/test only, no certificates involved).
--server-namestring
TLS ServerName/SNI to verify against. Ignored with --insecure.
--pinstring
Optional SPKI pin, checked in addition to normal chain validation. Off by default.
--no-tuibooldefault: false
Disable the terminal inspector UI and log plain text to stderr instead. The inspector is also skipped automatically whenever stdout isn't a terminal (piping, CI, running under &), 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:4443
server set to ngstone.site:4443
 
$ ngstone config get
token: nst_a1b2…9f3d
server: ngstone.site:4443
 
$ ngstone config get token
nst_a1b2…9f3d
 
$ ngstone config path
/home/you/.config/ngstone/config.json

config 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 logout
logged out

ngstone version#

Prints the build's version string, injected at compile time via -ldflags.

$ ngstone version
ngstone 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 generation is a plain shell one-liner, not a CLI verb. The edge only ever stores the token's SHA-256 hash — the plaintext lives on whichever machines run the agent.
TOKEN=$(openssl rand -base64 32 | tr '+/' '-_' | tr -d '=')
HASH=$(printf '%s' "$TOKEN" | shasum -a 256 | cut -d' ' -f1) # sha256sum on Linux

Keep $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 unset

The 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:

1. Flaghighest precedence
--token / --server on the command invoking it.
2. Environmenttoken only
NGSTONE_TOKEN. There is no environment override for the server address.
3. Config file
Whatever ngstone auth or ngstone config set last saved.
4. Defaultserver onlydefault: ngstone.site:4443
Used only if nothing above set a server address.

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 ID
-controlstringdefault: ngstone.site:4443
Edge control-plane address.
-tokenstring
Auth token. Falls back to NGSTONE_TOKEN if unset.
-targetstringdefault: http://127.0.0.1:3000
Local target URL to forward requests to.
-subdomainstring
Requested subdomain. Empty means server-assigned.
-instance-idstring
Undocumented, testing-only: force a specific instance ID instead of generating one.
-insecurebooldefault: false
Dial the control plane in plaintext (dev/test only).
-server-namestring
TLS ServerName/SNI to verify against.
-pinstring
Optional SPKI pin.
-versionbooldefault: false
Print version and exit.

Prefer ngstone auth plus ngstone port for day-to-day use — the legacy form exists for compatibility, not as the recommended path.