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.

Authenticate and export the session token bash
# 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.

User lifecycle bash
# 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.

Role lifecycle bash
# 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.

Join tokens bash
# 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).

Inventory bash
# 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
Register an agentless OpenSSH node bash
# 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.

Application lifecycle bash
# 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
  • --uri is the internal address the agent dials; it never appears in DNS.
  • --public-addr must be a subdomain of the configured proxy.apps_domain.
  • --protocol is http (default) or tcp. --agent-hostname is repeatable for HA.
  • --labels drive RBAC via app_labels on roles; --custom-headers, --strip-path-prefix, and --inject-identity tune 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.

Export the application-identity JWKS bash
# 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 management bash
# 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).

Access requests bash
# 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.

Active sessions bash
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.

Recording management bash
# 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.

Audit queries bash
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.

CA status and export bash
# 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
Rotation flow bash
# 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.

Connector management bash
# 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:

  1. On the root cluster, mint a single-use trust token with mezctl trusted-clusters create-token.
  2. On the leaf cluster, redeem the token with mezctl trusted-clusters join.
  3. On the root cluster, the new leaf shows up in mezctl trusted-clusters list and can be enabled, disabled, or deleted.
Trusted-cluster lifecycle bash
# 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).

Agent identity operations bash
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.

Workload identity operations bash
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.

Device management bash
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.

Integrations bash
# 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.

Cluster config bash
mezctl config get <key>
mezctl config set <key> <value>

Global flags

  • --auth-server <addr> — Auth service gRPC endpoint (default localhost:3025).
  • --token <session-token> — Session token. Also honoured via the MEZITE_AUTH_TOKEN environment variable.
  • --insecure — Skip server certificate verification. Dev-only.