FerrisKey CLI
ferris-ctl is the official command-line interface for FerrisKey. It talks to the FerrisKey REST API, so from a terminal you can manage realms, OAuth2 clients, and users, import a realm from a description file, Keycloak, Zitadel, or Supabase, and script administrative tasks.
What you can do
Manage contexts
Store connection profiles (URL, client, realm) and switch between environments.
Sign in
Authenticate with the OAuth 2.0 Device Authorization Grant. No client secret required.
Administer resources
Create and inspect realms, clients, and users.
Import realms
Migrate a realm from a file, a live Keycloak, a live Zitadel, or a Supabase project.
Install
cargo install ferris-ctlgit clone https://github.com/ferriskey/ferriskey-cli.git
cd ferriskey-cli
cargo build --release
# binary at target/release/ferris-ctldocker run --rm ghcr.io/ferriskey/ferris-ctl --helpBuilding from source needs Rust 1.88 or later. The workspace sets no rust-version, but the code uses let chains, which became stable in 1.88.
Pre-built binaries
Every GitHub release carries three archives. Extract ferris-ctl and put it on your PATH.
| Platform | Archive |
|---|---|
| Linux x86_64 | ferris-ctl-v0.3.0-x86_64-unknown-linux-gnu.tar.gz |
| macOS, Apple Silicon | ferris-ctl-v0.3.0-aarch64-apple-darwin.tar.gz |
| Windows x86_64 | ferris-ctl-v0.3.0-x86_64-pc-windows-msvc.zip |
The names follow ferris-ctl-<tag>-<target>; the ones above are the 0.3.0 release. A SHA256SUMS.txt file in the same release lists the checksum of each archive, so you can check a download before you run it. There is no pre-built binary for Intel Macs or for Linux on ARM: use Cargo or the container image there.
Container image
The image ghcr.io/ferriskey/ferris-ctl is built for linux/amd64 and linux/arm64, and its entrypoint is ferris-ctl. A release publishes the tags X.Y.Z, X.Y, and X. The tag latest is rebuilt from every push to main, so it can be ahead of the last release: pin X.Y.Z when you need a released build.
The image runs as an unprivileged user that has no home directory. Pass the connection through FERRISKEY_URL, FERRISKEY_CLIENT_ID, FERRISKEY_CLIENT_SECRET, and FERRISKEY_REALM instead of relying on a context file (see Authentication).
Release candidates (tags with -rc) are published as GitHub pre-releases and as images, but not to crates.io.
Verify the install:
ferris-ctl --help
How it works
CLI args → ferris-ctl → resolve context + credentials → FerrisKey REST API
↑
config.toml / credentials.toml
Every command that calls the API resolves three things in order:
- Where to connect: the server URL from the active context, or from
--urlwhen--client-idis given too. - Who you are: a saved login session, or the client credentials stored in the context.
- Which realm to act on: the realm you sign in to is the context’s
realm, and a command acts on that same realm unless you pass--realm.
Global flags
These flags work on every command, before or after the subcommand name.
| Flag | Short | Default | Env var | Description |
|---|---|---|---|---|
--context | active context | Use this stored context instead of the active one | ||
--output | -o | table | Output format: table, json, or yaml | |
--url | FERRISKEY_URL | FerrisKey server URL | ||
--client-id | FERRISKEY_CLIENT_ID | OAuth2 client used to sign in | ||
--client-secret | FERRISKEY_CLIENT_SECRET | Secret of that client | ||
--realm | FERRISKEY_REALM | Realm the command acts on |
The connection flags are not per-field overrides. --url and --client-id take effect only together: when both are set, the CLI builds its connection from the flags and ignores the config file and --context. Authentication lays out the exact rules, including how login differs.
-o applies to every command except login, logout, and client secret, which always print plain text.