Skip to content
SkiMasque

Guide

Applies to: ✓ Mode 1 · ✓ Mode 2 · ✓ Mode 3

A companion to --help, not a replacement — every command prints its own full help, and this page groups the surface so you can find things. Three binaries ship in skimasque-cli:

BinaryRole
skimasqueworkstation front door — policy, sign-in, fleet management
skimasque-serverthe gateway data plane
skimasque-clientopens tunnels through a gateway

Most flags also read a SKIMASQUE_* environment variable (noted where it matters); secrets are marked so --help hides their values.


skimasque

Policy, locally (no network)

CommandDoes
skimasque init [--policy-dir DIR]scaffold .masque/policies/ (default .masque/policies)
skimasque policy check <POLICY> <DEST>ALLOW/DENY for one request; exit 0 = allow, 1 = deny (composes in scripts)
skimasque policy explain <POLICY> <DEST>same, but always exit 0 and print the full reasoning
skimasque policy testrun every policy's [[tests]] assertions
skimasque policy validate [--strict]parse every file and lint [match] blocks; --strict exits non-zero on a lint, for a CI gate
skimasque policy diff <OLD> <NEW>what changed between two policy dirs or files
skimasque policy learn <OBSERVATIONS> [--name N]turn observed {application,destination} tuples into a reviewable draft
skimasque why <DEST>pick the policy whose [match] accepts the identity, evaluate, and print the decision
skimasque statussummarise the local policy set — what loads, whether its tests pass

check / explain / why / learn take identity flags — --repository owner/name, --branch <b> (or --ref refs/heads/<b>), --workflow, --environment, --actor, --organization — plus --app <name> and --transport tcp|udp (default tcp). Policy source is --policy-dir (default .masque/policies) or repeatable --policy-file.

$ skimasque why db.internal:5432 --app psql --repository acme/web --branch main

Sign in to a control plane

CommandDoes
skimasque login [--control-plane URL]GitHub device flow; stores a 30-day session. Defaults to https://control.skimasque.com, then the last one used. A bare host gains https://. $SKIMASQUE_CONTROL_PLANE also works.
skimasque logoutrevoke the session and delete the credential file
skimasque whoamishow the signed-in developer and control plane

The credential file lives at $SKIMASQUE_CONFIG_HOME, else $XDG_CONFIG_HOME/skimasque/, else ~/.config/skimasque/ (Unix) / %APPDATA%\skimasque\ (Windows), mode 0600.

Manage an organisation (needs skimasque login)

CommandDoes
skimasque org create <NAME>create an org; you become its owner
skimasque org listthe orgs you belong to
skimasque org memberslist members and roles
skimasque org add-member <github-login>add a member (they must have signed in once)
skimasque org set-role <github-login> <owner|member>promote/demote (owner-only)
skimasque org remove-member <github-login>remove a member (owner-only)
skimasque gateway register [--org ID] [--hostname H] [--acme] [--label k=v]…mint a registration token and print (or, with --run, execute) the ready skimasque-server --control-plane … command
skimasque audit [--gateway ID] [--decision allow|deny] [--since RFC3339] [--limit N]recent decisions across the fleet; the client pages the API so --limit has no ceiling
skimasque why <DEST> --control-plane [--org ID] [--revision N | --draft] [--gateway G]evaluate server-side against the published policy (or a revision / the draft), through the same engine the gateway uses

--org is inferred when you belong to exactly one.

Give a coding agent access (needs skimasque login)

CommandDoes
skimasque agent-session start [--org ID] [--ttl 30m] [--runtime NAME] [--run-id ID] [--parent SESSION] (--token-file PATH [--force] | --print-token)start a session and hand over its credential. --token-file writes a new owner-only file and prints the session id; --print-token prints only the credential. One of the two is required.
skimasque agent-session list [--org ID] [--all]the org's recent agent sessions (active only, unless --all)
skimasque agent-session end <SESSION_ID> [--org ID]end it now, and every session delegated from it

The lifetime defaults to 30 minutes and is capped at 4 hours. See agents.md for the model and for sandboxing.

Run a gateway or open a tunnel

  • skimasque gateway <args…> execs skimasque-server with the args — see below.
  • skimasque connect <DEST> [client args…] execs skimasque-client … connect --target <DEST>, bridging the tunnel to stdin/stdout (an SSH ProxyCommand, a pipeline). Uses the client default gateway or an explicit --proxy; without an explicit credential, the client can mint one from your signed-in session. Automatic customer-gateway discovery is not implemented.

Run a command with access

skimasque exec [--policy NAME] [--app NAME] [--gateway HOST[:PORT]]
               [--forward [LOCAL_PORT:]HOST:PORT]... [--org ORG] [--quiet]
               [--auth-token T | --github-oidc --oidc-audience AUD]
               [--ca PEM | --insecure] -- COMMAND [ARGS...]

Opens a gateway session, starts an HTTP CONNECT proxy and a SOCKS5 relay on loopback, and runs COMMAND with HTTPS_PROXY/HTTP_PROXY (HTTP CONNECT), ALL_PROXY (socks5h://) and NO_PROXY=localhost,127.0.0.1,::1 set. Access ends when the command exits.

The HTTP_PROXY front end tunnels CONNECT (HTTPS and other TLS) and carries plain http:// requests too: it opens a tunnel to the URL's host and port, sends the request to the origin with Connection: close, and relays the reply. One connection carries one request, so no keep-alive; a request that is not a CONNECT or an absolute-form http:// URL is refused (405). Other TCP is reached through ALL_PROXY (socks5h://) or a --forward.

The loopback listeners are not authenticated: while the command runs, any process on the machine can use the proxy and forward ports with your identity, the same exposure as ssh -L. Don't run exec on a shared host you don't trust.

FlagMeaning
--policy NAMEOnly run if NAME is the policy selected for your identity; the gateway enforces it via X-Masque-Policy.
--app NAMEDeclared application; defaults to the command's file name.
--gateway HOST[:PORT] / $SKIMASQUE_GATEWAYDefaults to gateway.skimasque.com on SkiMasque Cloud; required with a self-hosted control plane.
--control-plane URL / $SKIMASQUE_CONTROL_PLANEDefaults to the control plane you signed in to, else SkiMasque Cloud.
--forward [LOCAL_PORT:]HOST:PORTA loopback listener tunnelled to one destination, for tools that ignore proxy settings (psql). Its address is in $SKIMASQUE_FORWARD_<HOST>_<PORT>. Pick LOCAL_PORT when your shell needs the port on the command line.
--quietNo access summary on stderr.
--agentRun as a coding agent: start an agent session for the command and end it when the command exits. Needs skimasque login. The credential stays in this process. See agents.md.
--ttl D, --runtime NAME, --run-id ID, --parent SESSIONWith --agent: lifetime (default 30m, max 4h), audit labels, and the parent session to delegate from.
--sandbox srtConfine the command with Anthropic's sandbox runtime so SkiMasque is its only way out. Checks first that a direct connection is blocked, and refuses to start if not.
--allow-domain DOMAINWith --sandbox: a domain the sandbox lets through to SkiMasque (repeatable, required). The gateway's policy still decides each connection.
--sandbox-settings PATHWith --sandbox: your own srt settings, merged with the generated network settings.
--unsandboxedWith --agent: run it with no sandbox. An agent must pass --sandbox srt or this.

With a skimasque login session exec checks your access with the control plane first and refuses to start when --policy does not apply or every --forward would be denied. Exit status is the command's; 125 when exec fails before starting it, 126/127 when it cannot be run. Ctrl-C, SIGTERM or SIGHUP before the command starts stops exec with 128 + signal (130 for Ctrl-C); once it runs, Ctrl-C goes to the command and SIGTERM/SIGHUP are passed on to it.

On Windows a bare command name is resolved like cmd.exe does it: each PATH directory in order, trying each PATHEXT extension, so skimasque exec -- npm ci runs npm.cmd.

skimasque exec --policy production -- terraform apply
skimasque exec --forward 15432:db.prod:5432 -- psql -h 127.0.0.1 -p 15432

skimasque-server

--listen <ADDR> (default 0.0.0.0:4433; use 0.0.0.0:443 in production). Repeat -v for more logging — the ACME lifecycle and the policy audit trail show at the default level.

TLS — pick one

FlagsEffect
(none)a throwaway self-signed cert (--self-signed-name, --write-cert to save it); dev only
--acme + --hostname <name>in-process Let's Encrypt over TLS-ALPN-01, auto-renewing. --acme is a flag; the cert name is --hostname (default gateway.skimasque.com). Also: --acme-email, --acme-extra-domain, --acme-staging, --acme-cache <dir> (must persist — default skimasque-acme is relative). Needs inbound TCP 443 from the internet, not just a published port.
--cert <pem> --key <pem> + --tls-reloada certificate you supply; --tls-reload re-reads it in place on change (or SIGHUP), interval --tls-reload-interval (5s)

Identity

FlagEffect
--oidc (alias --github-oidc)verify CI OIDC tokens and enable the exchange endpoint; a tunnel without a verifiable credential is refused. Replaces --auth-token.
--oidc-provider <github|gitlab|buildkite|generic>which CI system's tokens (default github)
--oidc-audience <AUD>required with --oidc, repeatable — the aud each pipeline requests its token for
--oidc-issuer <URL>override the provider's hosted issuer (GHES, self-managed GitLab, generic)
--oidc-claim FIELD=CLAIMfor generic: map an identity field to a token claim
--auth-token <TOKEN> (SKIMASQUE_TOKEN)pre-OIDC static bearer; prefer --oidc
--credential-secret <HEX> (SKIMASQUE_CREDENTIAL_SECRET)HS256 key for platform credentials; set the same value fleet-wide. Unset = random per start.
--credential-ttl <DUR>credential lifetime (default 1h); the client refreshes ahead of it

Policy

--policy-dir <DIR> or repeatable --policy-file <PATH> — without a source the gateway applies only the address floor. --policy-reload swaps the set on a file change (or SIGHUP) with no dropped tunnel; --policy-reload-interval (5s). --policy-observe logs what policy would decide but allows every tunnel (feeds skimasque policy learn). --audit-log <PATH> appends a JSON-lines record of every decision (conflicts with --policy-observe).

Control plane (instead of local policy)

FlagEffect
--control-plane <URL>pull policy from skimasque's control plane (https://control.skimasque.com); requires --control-plane-state
--control-plane-state <DIR>persistent — the registered identity and the cached policy
--control-plane-token <TOKEN> (SKIMASQUE_CONTROL_TOKEN)one-time registration token; not needed once registered
--control-plane-name <NAME>fleet display name (default: the listen address)
--control-plane-label KEY=VALUEa label for D3 policy targeting; repeatable, re-sent every start
--control-plane-interval <DUR>long-poll / heartbeat interval (default 30s)
--control-plane-policy-lease <DUR>soft lease — degrade after this offline (default 15m)
--control-plane-cache-ttl <DUR>hard TTL — escalate the alarm after this, still enforcing (default 30m, ≥ lease)
--control-plane-no-credential-fallbackfail token exchange (502) during an outage instead of signing locally
--control-plane-signing-key-interval <DUR>re-fetch the org Ed25519 key (default 1h)

Address floor, limits, ops

  • --allow-cidr <CIDR> (repeatable) — open one private/loopback range; --allow-private opens all of them; --allow-port <PORT> (repeatable) restricts to named ports.
  • Resource caps, each 0 to disable: --max-connections (1024), --max-connection-rate / --max-connection-burst (50 / 200), --max-source-connection-rate / -burst (20 / 60), --max-exchange-rate / -burst (10 / 30), --max-concurrent-requests (1024), --max-tunnels-per-connection (256), --tunnel-idle-timeout (120s).
  • --no-connect-tcp — UDP only. TCP tunnels (what a SOCKS front end needs for curl / git / databases) are served by default; this refuses them.
  • --metrics-listen <ADDR> — /healthz, /readyz, Prometheus /metrics on a plain-HTTP listener; keep it on a private interface.
  • --shutdown-grace <DUR> — how long in-flight tunnels get after SIGTERM before the endpoint closes (default 10s).
  • --authority <HOST[:PORT]> / --template <T> — the URI Template served (defaults from --hostname).

skimasque-client

skimasque-client [connection flags] <proxy | socks5 | connect | probe>

skimasque-client capabilities --json reports versioned frontend capabilities without contacting a gateway or reading credentials.

Connection flags

FlagEffect
--proxy <HOST[:PORT]>the gateway (default gateway.skimasque.com, port 443)
--authority <HOST[:PORT]>TLS server name / :authority (default: the --proxy host)
--ca <PATH>trust these PEM certs instead of the system roots
--insecureaccept any certificate — gives up MITM defence; use --ca instead
--auth-token <TOKEN> (SKIMASQUE_TOKEN)static bearer, for a --auth-token gateway
--auth-token-file <PATH> (SKIMASQUE_TOKEN_FILE)read the static bearer from a file, keeping it out of argv and the environment; for an agent session's credential. Exclusive with the other credential sources.
--github-oidcfetch the runner's OIDC token and exchange it (needs --oidc-audience)
--oidc-token <JWT> (SKIMASQUE_OIDC_TOKEN)supply a token you fetched another way
--oidc-audience <AUD>must match one of the gateway's --oidc-audience values
--org <ORG>with none of the above: mint a credential from a skimasque login session instead, for this org (auto-resolved if the session belongs to only one)
--app <NAME>the application to declare (X-Masque-Application); policy matches on it

On Linux, proxy --tun-interface NAME also forwards packets from an existing user-owned TUN with MTU 1280 using embedded tun-rs and a smoltcp-based stack. The Action owns route/DNS setup; the client attaches without configuring it. Native readiness includes tun_interface, and Linux capabilities include proxy-tun-v1. TCP and UDP flow directly through the shared MASQUE session; there is no external adapter or intermediate SOCKS hop for native traffic. ICMP, IP fragmentation and arbitrary IP protocols are unsupported. UDP payloads must fit both the interface MTU and the MASQUE datagram limit.

Subcommands

CommandDoes
proxy [--http-listen ADDR] [--socks-listen ADDR] [--ready-file PATH]authenticated HTTP/HTTPS CONNECT and SOCKS5 TCP/UDP listeners; defaults 127.0.0.1:8080 and 127.0.0.1:1080. Loopback only; port 0 selects a free port.
socks5 [--listen ADDR]run a SOCKS5 relay (default 127.0.0.1:1080); CONNECT (TCP, refused by a --no-connect-tcp gateway) and UDP ASSOCIATE. Point ALL_PROXY=socks5h://… at it.
connect --target <HOST:PORT>one raw TCP tunnel bridged to stdin/stdout (SSH ProxyCommand, interop)
probe --target <HOST:PORT> [--dns NAME | --text T | --hex H] [--count N] [--timeout MS]send a payload and print the replies
$ skimasque-client --proxy gw.example.com --github-oidc \
    --oidc-audience https://gw.example.com --app psql \
    proxy --ready-file /tmp/skimasque-ready.json

For proxy-aware tools, set both uppercase and lowercase HTTP_PROXY and HTTPS_PROXY to http://127.0.0.1:8080, ALL_PROXY to socks5h://127.0.0.1:1080, and NO_PROXY to localhost,127.0.0.1,::1. HTTPS uses CONNECT through the HTTP listener; the SOCKS hostname is resolved at the gateway. These variables do not intercept tools using raw sockets.

The optional readiness file is created atomically after authentication and both binds. It contains schema 1, pid, actual http/socks addresses and the connected gateway. Existing files are never overwritten. Unix SIGTERM/Ctrl-C and normal exit remove readiness; forced kills can leave a stale file, so callers must also verify process identity and health. OIDC credentials refresh in place: new tunnels use the replacement and existing tunnels continue. Gateway closure terminates the frontend.

The connect Action supervises this mode. Its transparent mode additionally routes configured private TCP/UDP and DNS through a TUN adapter on supported dedicated Ubuntu runners, without global proxy variables. It requires explicit CIDRs and private DNS settings, both families when needed, and matching client/Action releases.