mezctl CLI Reference
mezctl is the administrative CLI for a Mezite cluster. It connects
to the auth service (default localhost:3025, override with --auth-server) and operates on every long-lived cluster resource: users, MFA
factors, roles, locks, join tokens, agents and agentless nodes, audit
logs, recordings, access requests, SSO connectors, trusted clusters,
workload identities, agent identities, the CA, and cluster config.
Every command authenticates via a session token. Get one with
mezctl login, then pass it with --token or export
it as MEZITE_AUTH_TOKEN.
login
Authenticate against the auth service and print a session token. The common pattern is to capture the token into an environment variable so subsequent commands inherit it.
# Local username/password
export MEZITE_AUTH_TOKEN=$(mezctl login \
--auth-server=mezite.example.com:3025 \
--username=admin \
--password="$MEZITE_ADMIN_PASSWORD")
# Use the captured token for subsequent commands
mezctl users list users
Create, list, delete, and reset MFA for cluster users.
# Create a user with roles
mezctl users create alice --roles=developer,viewer
# List users
mezctl users list
# Delete a user
mezctl users delete --username=alice
# Reset an enrolled second factor
mezctl users reset-totp alice
mezctl users reset-webauthn alice
# Inspect a user's enrolled MFA factors
mezctl users list-mfa alice
# Print enrollment instructions for a new MFA factor
# (currently only --type=webauthn is supported)
mezctl users add-mfa alice --type=webauthn roles
Manage the RBAC roles that govern SSH access. See the RBAC guide for the role schema.
# Create or update a role from a YAML or JSON spec
mezctl roles create --from-file=role-developer.yaml
# List roles
mezctl roles ls
# Render a role
mezctl roles get developer
# Delete a role
mezctl roles delete developer tokens
Manage one-time join tokens used by mezd agents and bots to enroll
into the cluster.
# Create a node join token (TTL 1h)
mezctl tokens create --roles=node --ttl=1h
# List active tokens
mezctl tokens list
# Delete a token by name or id
mezctl tokens delete <name-or-id> nodes
List, register, update, and remove SSH nodes. Mezite supports two kinds
of nodes: agent-based nodes (running
mezd, which dials out a reverse tunnel) and
agentless OpenSSH nodes (no mezd; the
proxy reaches the node's existing sshd directly).
# List all nodes
mezctl nodes ls
# Show the full record for one node
mezctl nodes get web-01
# Update labels on a node
mezctl nodes update web-01 --labels env=staging,role=web
# Remove a node from the cluster
mezctl nodes rm web-01 # Pin a host key from a file on disk
mezctl nodes add \
--openssh \
--name=db-legacy-01 \
--host=db-legacy-01.internal \
--port=22 \
--labels=env=production,role=db \
--host-key-file=/etc/ssh/ssh_host_ed25519_key.pub \
--verify-host-key
# Or paste the key inline (authorized_keys format)
mezctl nodes add \
--openssh \
--name=db-legacy-01 \
--host=db-legacy-01.internal \
--port=22 \
--host-key="ssh-ed25519 AAAA..." \
--verify-host-key
# Rotate (or pin) the host-key fingerprint on an agentless node
mezctl nodes rotate-host-key db-legacy-01 \
--host-key-file=/etc/ssh/ssh_host_ed25519_key.pub
Only agentless nodes are registered through mezctl nodes add; an agent-based node joins itself by calling
GenerateHostCerts + RegisterAgent on first start,
using a token from mezctl tokens create.
apps
Register and manage the internal applications exposed through the proxy. Each application maps a public hostname to a private internal address served by one or more bound agents. See the Application Access guide for the end-to-end flow.
# Register an internal HTTP app, bound to two serving agents
mezctl apps register \
--name=grafana \
--uri=http://10.0.3.12:3000 \
--public-addr=grafana.apps.example.com \
--labels=env=prod,team=platform \
--agent-hostname=node-1 \
--agent-hostname=node-2
# Register a TCP app (databases, caches, custom daemons)
mezctl apps register \
--name=redis-internal \
--protocol=tcp \
--uri=tcp://10.0.3.20:6379 \
--public-addr=redis-internal.apps.example.com \
--agent-hostname=node-1
# Inspect
mezctl apps ls
mezctl apps get grafana
# Update an app's config (replaces all non-agent fields)
mezctl apps update grafana \
--uri=http://10.0.3.12:3000 \
--public-addr=grafana.apps.example.com \
--labels=env=prod,team=platform
# Manage the serving set without re-registering
mezctl apps add-agent grafana node-3
mezctl apps rm-agent grafana node-2
# Take an app offline temporarily (config + bindings preserved), or remove it
mezctl apps disable grafana
mezctl apps enable grafana
mezctl apps rm grafana -
--uriis the internal address the agent dials; it never appears in DNS. -
--public-addrmust be a subdomain of the configuredproxy.apps_domain. -
--protocolishttp(default) ortcp.--agent-hostnameis repeatable for HA. -
--labelsdrive RBAC viaapp_labelson roles;--custom-headers,--strip-path-prefix, and--inject-identitytune HTTP forwarding.
auth export
Export public trust material for offline verification. Today it exports the application-identity JWT public key set (JWKS), which a backend uses to verify the signed identity assertion the proxy attaches to forwarded application requests — useful for backends with no outbound internet to fetch the proxy's published JWKS endpoint.
# Write the JWKS to a file (default --type is app-jwt)
mezctl auth export --type=app-jwt --out=app-jwt-jwks.json
# Or print to stdout
mezctl auth export --type=app-jwt locks
Locks are the cluster-wide kill switch for an identity. A lock takes
effect immediately on the auth service and propagates to active sessions
on the next interceptor pass — they are how you stop a compromised user,
role, agent, or agent identity from doing further damage without waiting
for cert expiry. Supported target types are
user, role, agent, and
agent_identity.
# Lock a user (any active sessions and any new cert issuance are denied)
mezctl locks create --user=alice --message="Security review"
# Lock a role across all its holders
mezctl locks create --role=on-call-prod --message="Pager freeze"
# Lock a specific agent identity (e.g. a compromised bot)
mezctl locks create --type=agent_identity --name=ci-bot --message="Rotating credentials"
# List active locks
mezctl locks list
# Remove a lock
mezctl locks delete --target-type=user --target-name=alice access-requests
Review just-in-time access requests for elevated roles. Verbs are
approve, deny, cancel (used by the
requester before approval), and revoke (used after approval to
terminate an active grant).
# List pending and historical requests
mezctl access-requests ls
# Reviewer side
mezctl access-requests approve <request-id>
mezctl access-requests deny <request-id>
# Revoke an already-approved grant (admin or original reviewer)
mezctl access-requests revoke <request-id>
# Requester side: walk back an unanswered request
mezctl access-requests cancel <request-id>
Access requests today are role-only: a requester asks
for one or more additional roles via requested_roles. There
is no resource-mode access-request flow yet — that is tracked as a
product gap and not exposed through this CLI.
sessions
Inspect and terminate active SSH sessions. Termination is enforced by the proxy and the agent; the session ends immediately on the operator side.
mezctl sessions ls
mezctl sessions terminate <session-id> recordings
List and download session recording metadata and the recording bytes
themselves. The download verb pulls the recording from the configured
storage backend (local or s3) and writes it to
disk so it can be played back with msh play.
# List recent recordings (paginated, newest first)
mezctl recordings ls
# Filter by user
mezctl recordings ls --user=alice
# Download to disk
mezctl recordings download <session-id> --out=/tmp/<session-id>.cast audit
Query the audit log and archive events to long-term storage. See the Audit Logging guide for the event schema.
mezctl audit ls
mezctl audit ls --type=session.start
mezctl audit ls --type=access.denied --since=1h
mezctl audit ls --user=alice --since=24h
# Archive events to the cluster's configured S3 bucket
mezctl audit archive ca
Manage the cluster's certificate authorities. Mezite runs three CAs — User, Host, and SPIFFE — and exposes a multi-phase rotation state machine so a CA key can be swapped without invalidating in-flight certificates. The state machine is described in the architecture page.
# Show the current phase and key fingerprints for every CA
mezctl ca status
# Export a CA's public material (e.g. for trust bundles or audits)
mezctl ca export --type=user
mezctl ca export --type=host
mezctl ca export --type=spiffe # Begin rotation on the User CA: a new key is generated alongside the
# existing key. Both keys are trusted; existing certs continue to validate.
mezctl ca rotate --type=user
# Advance to the next phase once you've verified clients are pinning the
# new trust bundle. Phases: init -> update-clients -> update-servers ->
# standby -> complete.
mezctl ca advance --type=user
# Roll back to the previous phase if a phase advance broke a population of
# clients you can't redeploy quickly.
mezctl ca rollback --type=user connectors
Manage SSO authentication connectors (OIDC, SAML, GitHub OAuth, LDAP / Active Directory). See the SSO guide for per-IdP setup instructions.
# Create an OIDC connector (Okta example)
mezctl connectors create \
--name=okta \
--type=oidc \
--issuer-url=https://dev-12345.okta.com/oauth2/default \
--client-id="$OKTA_CLIENT_ID" \
--client-secret="$OKTA_CLIENT_SECRET" \
--redirect-url=https://mezite.example.com/v1/webapi/oidc/callback \
--claims-to-roles="groups:engineering:access,ssh-production;groups:platform-team:admin"
# Create a SAML connector
mezctl connectors create \
--name=corp-saml \
--type=saml \
--entity-id=mezite \
--idp-metadata-url=https://idp.example.com/metadata \
--acs-url=https://mezite.example.com/v1/webapi/saml/callback \
--attributes-to-roles="groups:engineering:access"
# List configured connectors
mezctl connectors list
# Delete a connector
mezctl connectors delete --name=okta trusted-clusters
Establish proxy-to-proxy trust between two Mezite clusters so a user in the root cluster can SSH into nodes registered with a leaf cluster. The flow is:
-
On the root cluster, mint a single-use trust token with
mezctl trusted-clusters create-token. -
On the leaf cluster, redeem the token with
mezctl trusted-clusters join. -
On the root cluster, the new leaf shows up in
mezctl trusted-clusters listand can beenabled,disabled, ordeleted.
# On the root cluster: mint a token and hand it to the leaf operator
mezctl trusted-clusters create-token --allow-cluster=leaf-eu --ttl=30m
# On the leaf cluster: redeem the token
mezctl trusted-clusters join \
--root-proxy=root.example.com:443 \
--cluster-name=leaf-eu \
--join-token=<paste-the-token>
# Back on the root cluster: inspect and manage
mezctl trusted-clusters list
mezctl trusted-clusters get leaf-eu
mezctl trusted-clusters disable leaf-eu
mezctl trusted-clusters enable leaf-eu
mezctl trusted-clusters delete leaf-eu
# Token housekeeping
mezctl trusted-clusters list-tokens
mezctl trusted-clusters delete-token <token> agent-identities
Manage the long-lived identity material an agent uses after the initial join. These records hold the agent's stable identifier, the host certificate fingerprint, and the cluster-side metadata about the host. Normally rotated automatically — these commands are for recovery (e.g. an agent whose disk was wiped).
mezctl agent-identities add --name=web-01
mezctl agent-identities ls
mezctl agent-identities status web-01
mezctl agent-identities rm web-01 workload-identities
Manage SPIFFE workload identities. Each identity binds a workload role
(encoded in the SVID URI SAN) to a node or set of nodes. Workloads on
those nodes then call the
mezd identity Unix socket to fetch short-lived X.509-SVIDs or
JWT-SVIDs signed by the SPIFFE CA.
mezctl workload-identities create --from-file=workload.yaml
mezctl workload-identities ls
mezctl workload-identities get <name>
mezctl workload-identities rm <name> devices
Manage trusted devices that the cluster uses for device-trust
enforcement on roles with device_trust_mode set.
mezctl devices add # interactive enrollment of the current machine
mezctl devices ls
mezctl devices rm <id>
mezctl devices revoke <id> integrations
Configure outbound third-party integrations such as the
aws-oidc federation used by managed deployments to mint short-lived
AWS credentials from a Mezite identity. Today only the
aws-oidc configure flow is implemented; in script mode it prints
the AWS CLI commands and trust policy to apply by hand, and in live mode (when
--aws-profile and/or
--aws-region is supplied) it calls AWS IAM directly.
# Script mode: print the aws-cli commands and IAM trust policy
mezctl integrations configure aws-oidc \
--account=123456789012 \
--spiffe-id="spiffe://mezite.example.com/*" \
--role-name=MeziteWorkloadRole
# Live mode: actually create / converge the OIDC provider in AWS
mezctl integrations configure aws-oidc \
--aws-profile=mezite-prod \
--aws-region=us-east-1 \
--account=123456789012 \
--spiffe-id="spiffe://mezite.example.com/*" \
--role-name=MeziteWorkloadRole config
Read and update the per-cluster runtime config record (distinct from the YAML/env-var bootstrap config). Useful when changing a setting that's intended to be cluster-wide and observable from any node, e.g. the access-request reviewer policy.
mezctl config get <key>
mezctl config set <key> <value> Global flags
-
--auth-server <addr>— Auth service gRPC endpoint (defaultlocalhost:3025). -
--token <session-token>— Session token. Also honoured via theMEZITE_AUTH_TOKENenvironment variable. -
--insecure— Skip server certificate verification. Dev-only.