macOS Headless Client
firezone-cli runs the macOS Client from a terminal, without the menu bar app
in the foreground. It is intended for Macs that are managed remotely or run
unattended, such as build machines.
It is not a separate program. It is the macOS Client's own binary, started under a different name, which is what lets it use the same system extension, VPN profile, and stored token as the graphical Client.
If you're looking for the graphical macOS Client, see the macOS Client.
Prerequisites
- macOS 13 or higher
- The macOS Client installed in
/Applications - A Firezone account, plus admin access to create a service account if you intend to authenticate with a service account token
Location
The binary lives inside the app bundle:
/Applications/Firezone.app/Contents/MacOS/firezone-cli
Add it to your PATH to invoke it as firezone-cli:
export PATH="/Applications/Firezone.app/Contents/MacOS:$PATH"
System extension
The Client cannot start without its system extension, which is the same
extension the graphical Client uses. Launch Firezone.app once to install it.
Installing one requires a person to approve it, so the CLI cannot do it for
you.
To avoid prompting the user for approval, allowlist the extension ahead of time with MDM. See Allowlisting the macOS System Extension.
firezone-cli extension status reports whether the extension is installed and
matches the installed app, exiting non-zero if it does not:
> firezone-cli extension status
installed
Usage
Signing in
The Client never asks for a token at a prompt. It runs inside the sandboxed macOS Client, and a sandboxed process isn't allowed to turn terminal echo off, so a token typed at a prompt would sit in the terminal's scrollback. It reads one from its standard input instead.
Start the Client with no token and it tells you what to do:
No token found. To sign in:
1. Open this in a browser and sign in:
https://app.firezone.dev/<ACCOUNT_SLUG>?as=headless-client
2. Copy the token.
3. Run:
pbpaste | /Applications/Firezone.app/Contents/MacOS/firezone-cli
A token can also be set in FIREZONE_TOKEN, or read from a file:
/Applications/Firezone.app/Contents/MacOS/firezone-cli < token
The token is saved to the Keychain, so later runs don't need one.
pbpaste writes the clipboard straight into the Client, so the token is never
displayed and never reaches your shell history. The Keychain keeps it afterwards,
so later runs need no token at all.
A service account token is supplied the same way, and is the right choice for a Mac that runs unattended.
Supplying a token without a person present
Read the token from a file:
firezone-cli < /path/to/token
Or set FIREZONE_TOKEN from somewhere your shell won't record:
export FIREZONE_TOKEN="$(cat /path/to/token)"
firezone-cli
Don't put a token directly on the command line, for example by prefixing
firezone-cli with FIREZONE_TOKEN=. Your shell records the whole command in
its history file, where the token stays readable long after the session ends.
Service account tokens are long-lived, so treat one as you would a password.
Better still, keep a shell out of it. Give the token to launchd in the job's
EnvironmentVariables, or have your MDM deliver it, and keep the file readable
only by the account that runs the Client.
Running
connect is the default subcommand, so firezone-cli on its own brings the
tunnel up and stays in the foreground until stopped. SIGINT and SIGTERM shut
the tunnel down; SIGHUP restarts it. Logs are written to standard error.
Signing out
firezone-cli sign-out
This removes the stored token from the Keychain.
Help output
> firezone-cli --help
OVERVIEW: Firezone headless Client
USAGE: firezone-cli <subcommand>
OPTIONS:
--version Show the version.
-h, --help Show help information.
SUBCOMMANDS:
connect (default) Bring the tunnel up and stay running. This is the
default.
sign-out Sign out and remove the stored token.
extension Inspect and install the system extension.
See 'firezone-cli help <subcommand>' for detailed help.
> firezone-cli connect --help
OVERVIEW: Bring the tunnel up and stay running. This is the default.
USAGE: firezone-cli connect [--activate-internet-resource] [--account-slug <account-slug>]
OPTIONS:
--activate-internet-resource
Activate Internet Resource.
--account-slug <account-slug>
Account slug.
--version Show the version.
-h, --help Show help information.
> firezone-cli extension --help
OVERVIEW: Inspect the system extension.
USAGE: firezone-cli extension <subcommand>
SUBCOMMANDS:
status Report whether the system extension is installed and
current.
Environment variable reference
| Variable Name | Default Value | Description |
|---|---|---|
FIREZONE_TOKEN | Token used to authenticate the Client. A token piped into the Client takes precedence. If neither is given, the Client uses the token stored in the Keychain, and explains how to supply one if there isn't one. | |
FIREZONE_ACCOUNT_SLUG | Account slug to sign in to. Equivalent to --account-slug. | |
FIREZONE_ACTIVATE_INTERNET_RESOURCE | Set to 1 to activate the Internet Resource. Equivalent to --activate-internet-resource. | |
FIREZONE_LOG_FILTER | info | Log level for the Client. Set to debug for verbose logging. |
FIREZONE_API_URL | wss://api.firezone.dev | Control plane URL. Only change this if you have been asked to. |
FIREZONE_AUTH_BASE_URL | https://app.firezone.dev | Portal URL used to build the browser sign-in link. Only change this if you have been asked to. |
Upgrading
The CLI is part of the macOS Client, so upgrade the app as usual. The system
extension is upgraded with it the next time Firezone.app runs.
Diagnostic logs
The CLI writes logs to standard error. Redirect them to a file to keep them:
firezone-cli > firezone.log 2>&1
Logs from the system extension are written to the same location the graphical Client uses. See the Troubleshooting guide for more.
Need help? See all support options.