{
    "product": "Cenvero Stratum",
    "generated_at": "2026-08-03T07:16:31+00:00",
    "format": "cenvero-docs-v1",
    "document_count": 1,
    "documents": [
        {
            "slug": "cli",
            "title": "CLI Reference",
            "category": null,
            "url": "https://www.stratum.cenvero.com/docs/cli",
            "headings": [
                {
                    "level": 1,
                    "text": "CLI Reference"
                },
                {
                    "level": 2,
                    "text": "Status & system"
                },
                {
                    "level": 3,
                    "text": "`status`"
                },
                {
                    "level": 3,
                    "text": "`version`"
                },
                {
                    "level": 3,
                    "text": "`metrics`"
                },
                {
                    "level": 3,
                    "text": "`hardware`"
                },
                {
                    "level": 3,
                    "text": "`pull`"
                },
                {
                    "level": 2,
                    "text": "System management"
                },
                {
                    "level": 3,
                    "text": "`config`"
                },
                {
                    "level": 3,
                    "text": "`service`"
                },
                {
                    "level": 3,
                    "text": "`api-token`"
                },
                {
                    "level": 3,
                    "text": "`tls`"
                },
                {
                    "level": 3,
                    "text": "`update`"
                },
                {
                    "level": 3,
                    "text": "`license`"
                },
                {
                    "level": 2,
                    "text": "Networking"
                },
                {
                    "level": 3,
                    "text": "`network`"
                },
                {
                    "level": 3,
                    "text": "`nic`"
                },
                {
                    "level": 3,
                    "text": "`ipam`"
                },
                {
                    "level": 3,
                    "text": "`dhcp`"
                },
                {
                    "level": 3,
                    "text": "`dns`"
                },
                {
                    "level": 3,
                    "text": "`vlan`"
                },
                {
                    "level": 3,
                    "text": "`vxlan`"
                },
                {
                    "level": 3,
                    "text": "`route`"
                },
                {
                    "level": 2,
                    "text": "Security"
                },
                {
                    "level": 3,
                    "text": "`firewall`"
                },
                {
                    "level": 3,
                    "text": "`rules`"
                },
                {
                    "level": 2,
                    "text": "Traffic shaping & visibility"
                },
                {
                    "level": 3,
                    "text": "`bandwidth`"
                },
                {
                    "level": 3,
                    "text": "`quota`"
                },
                {
                    "level": 3,
                    "text": "`flow`"
                },
                {
                    "level": 2,
                    "text": "Services & HA"
                },
                {
                    "level": 3,
                    "text": "`lb`"
                },
                {
                    "level": 3,
                    "text": "`bgp`"
                },
                {
                    "level": 3,
                    "text": "`gateway`"
                },
                {
                    "level": 3,
                    "text": "`ha`"
                },
                {
                    "level": 3,
                    "text": "`bond`"
                },
                {
                    "level": 3,
                    "text": "`cluster`"
                },
                {
                    "level": 2,
                    "text": "Tenants & billing"
                },
                {
                    "level": 3,
                    "text": "`tenant`"
                },
                {
                    "level": 3,
                    "text": "`apikeys`"
                },
                {
                    "level": 3,
                    "text": "`billing`"
                },
                {
                    "level": 2,
                    "text": "Operations"
                },
                {
                    "level": 3,
                    "text": "`backup`"
                },
                {
                    "level": 3,
                    "text": "`alert`"
                },
                {
                    "level": 3,
                    "text": "`heal`"
                },
                {
                    "level": 3,
                    "text": "`container`"
                },
                {
                    "level": 3,
                    "text": "`plugin`"
                },
                {
                    "level": 3,
                    "text": "`node`"
                },
                {
                    "level": 2,
                    "text": "Exit codes"
                },
                {
                    "level": 2,
                    "text": "See also"
                }
            ],
            "word_count": 3607,
            "markdown": "# CLI Reference\n\n`cenvero-str-ctl` is the operator interface to a node. It talks to the running\nagent over a local socket, so it only works **on the node itself** and needs\n`root` for any command that changes state. The socket is always available — it is\nthe node's management lifeline and can never be disabled.\n\n```bash\ncenvero-str-ctl <group> <command> [args] [flags]\n```\n\n- Add `--format json` (or `yaml`) to any command for machine-readable output\n  (the default is a human table/JSON view).\n- Add `-h` to any group or command for its full help, subcommands, and flags.\n- The same managers are reachable over the node's [REST API](/docs/api); this CLI\n  is the local equivalent.\n\nThe command groups, by area:\n\n| Area | Groups |\n|---|---|\n| Status & system | `status` `version` `metrics` `hardware` `pull` |\n| System management | `config` `service` `tls` `update` `license` |\n| Networking | `network` `nic` `ipam` `dhcp` `dns` `vlan` `vxlan` `geneve` `vrf` `route` |\n| Security | `firewall` `rules` |\n| Traffic shaping & visibility | `bandwidth` `quota` `flow` |\n| Services & HA | `lb` `l7lb` `bgp` `gateway` `nat64` `ha` `bond` `cluster` |\n| Tenants & billing | `tenant` `apikeys` `billing` |\n| Operations | `backup` `alert` `heal` `container` `plugin` `node` |\n\n---\n\n## Status & system\n\n### `status`\n\n```bash\ncenvero-str-ctl status        # health summary: version, license, data plane, bridges, cluster\n```\n\n### `version`\n\n```bash\ncenvero-str-ctl version       # agent version\n```\n\n### `metrics`\n\n```bash\ncenvero-str-ctl metrics       # current metrics snapshot\n```\n\n### `hardware`\n\nPrint this machine's **hardware ID** — the value an activation or SSL request is\nbound to. Use it to verify a pending request in your account before approving it.\n\n```bash\ncenvero-str-ctl hardware\n```\n\n### `pull`\n\nForce an immediate pull of the node's CA-signed TLS certificate **and** a license\nre-sync (fetch a pending activation, auto-renew, re-evaluate) now, instead of\nwaiting for the next background poll. Run it right after approving a node's\nSSL/license in your account.\n\n```bash\nsudo cenvero-str-ctl pull\n```\n\n---\n\n## System management\n\n### `config`\n\n| Command | Purpose |\n|---|---|\n| `config set [<key> <value>]` | Change a whitelisted operational setting (run with no args to list keys) |\n| `config show` | Print the decoded on-disk configuration (secrets redacted) |\n| `config dump` | Dump the on-disk configuration |\n| `config encode` | Write the node's signed configuration from flags (used by the installer) |\n\n`config set` writes to an **operator local-overrides** file that the agent layers\non top of its configuration at the next restart — and that a panel re-sync will\n**not** clobber (local always wins). Use the positional `config set <key> <value>`\nform, or the `--api-bind` / `--api-rate-limit` / `--api-rate-burst` shortcuts.\nApply with `systemctl restart cenvero-stratum`; verify with `config show`.\n\n```bash\nsudo cenvero-str-ctl config set api_rate_limit 2000\nsudo cenvero-str-ctl config set --api-bind 10.0.0.5 --api-rate-limit 2000 --api-rate-burst 200\nsudo cenvero-str-ctl config set            # list every settable key\n```\n\n**Settable keys:** `log_level`, `api_bind_address`, `api_rate_limit`,\n`api_rate_burst`, `api_allowed_ips`, `api_allowed_origins`,\n`api_read_timeout_secs`, `api_write_timeout_secs`, `api_idle_timeout_secs`,\n`port_rest`, `port_grpc`, `port_websocket`, `port_cluster`, `port_ha_heartbeat`,\n`metrics_bind_addr`, `dns_listen_addr`, `dns_allowed_clients`, `dns_upstreams`,\n`heal_interval_seconds`, `heal_disabled_checks`, and the six service switches\n(`rest_disabled`, `grpc_disabled`, `websocket_disabled`, `metrics_disabled`,\n`dns_disabled`, `dhcp_disabled`). Identity, the license server, the API token, and\nany signing/cluster-secret/TLS material are **refused** — they are panel- or\nidentity-owned, not local operational settings. See\n[Configuration](/docs/configuration) for the full field reference.\n\n`config show` / `dump` are read-only and decode the actual on-disk file (table,\n`--format json`, or `--format yaml`); pass `--include-secrets` to reveal redacted\nvalues, or `--file <path>` to inspect a specific file. `config encode` is what the\ninstaller uses to write the node's configuration and prints the resulting\n`api_token`.\n\n### `service`\n\nSee and toggle the agent's network services. `service status` shows each service's\n**ENABLED** switch, its **ADDRESS:PORT**, and a live **STATE**. Toggle a service on\nor off; the change applies on the next agent restart.\n\n| Command | Purpose |\n|---|---|\n| `service status` | Show each service (aliases: `list`, `top`, `ls`, `ps`) |\n| `service <name> on` | Enable a service (also `service on <name>`) |\n| `service <name> off` | Disable a service (also `service off <name>`) |\n\nToggleable services: `rest`, `grpc`, `websocket`, `metrics`, `dns`, `dhcp`.\nDisabling `rest` warns first (it also serves the operator/billing API). The **IPC\ncontrol socket is not toggleable** — it is how this CLI reaches the agent.\n\n```bash\nsudo cenvero-str-ctl service status\nsudo cenvero-str-ctl service rest off\nsudo cenvero-str-ctl service websocket on\nsudo systemctl restart cenvero-stratum   # apply\n```\n\nEnabling `rest`, `grpc` or `websocket` is only half of it — the management APIs\nalso require an API token before they will serve, so a service you switch on with\nno token configured stays `down`. See `api-token` below.\n\n### `api-token`\n\nManage the bearer token the management APIs (REST, gRPC, WebSocket) require. With\nno token the agent refuses to open a management API at all rather than serve one\nwithout a credential, so this is what turns them on.\n\n| Command | Purpose |\n|---|---|\n| `api-token generate` | Mint a strong random token, store it, print it **once** |\n| `api-token set` | Store a token you supply, read from **stdin** |\n| `api-token status` | Report whether a token is set — never prints the value |\n| `api-token clear` | Remove it; the APIs stop serving at the next restart |\n\n```bash\nsudo cenvero-str-ctl api-token generate\nsudo cenvero-str-ctl service on rest\nsudo systemctl restart cenvero-stratum\n```\n\n`generate` shows the token once and it is not recoverable afterwards — copy it\nthen. To choose the value yourself, pipe it in so it never reaches your shell\nhistory; there is deliberately no flag to pass it as an argument:\n\n```bash\nprintf '%s' \"$MY_TOKEN\" | sudo cenvero-str-ctl api-token set\n```\n\nTokens shorter than 16 characters are refused. The value is stored in your local\noverrides, so a later configuration sync from the panel will not discard it. It is\nnot settable through `config set`, which rejects credential keys for the same\nshell-history reason.\n\nA management API binds only when **all three** hold: a token exists, the service\nis on, and the node has a TLS certificate — the agent never serves plaintext.\n\n### `tls`\n\nManage the management API's TLS certificate. After install the node serves a\ntemporary self-signed certificate; in CA mode it obtains a CA-signed certificate\nonce you approve the request in your account (Account → TLS). The private key never\nleaves the node.\n\n| Command | Purpose |\n|---|---|\n| `tls info` | Live certificate: mode (`ca-signed`/`self-signed`), expiry, SAN domains |\n| `tls show` | The certificate / key / public-key file locations |\n| `tls pubkey` | Print the public-key file location |\n| `tls request` | Request a CA-signed certificate from the panel now (online) |\n| `tls pull` | Pull this node's CA-signed certificate now (collect it once approved) |\n| `tls regenerate` | Generate a fresh certificate now (hot-reloaded, no restart) |\n| `tls csr` | Generate a key + CSR locally **without** contacting the panel (offline) |\n| `tls install <cert> [chain]` | Install a signed certificate obtained out-of-band |\n| `tls pending-status` | Report any pending certificate request (online or offline) |\n| `tls reset-pending` | Discard a pending offline CSR so you can start fresh |\n| `tls reset` | Clear the current certificate + pending request and re-obtain a fresh one |\n| `tls domain list` | List the SAN domains on the certificate |\n| `tls domain add <domain>` | Add a SAN domain (regenerates the certificate) |\n| `tls domain remove <domain>` | Remove a SAN domain (regenerates the certificate) |\n\n```bash\nsudo cenvero-str-ctl tls info\nsudo cenvero-str-ctl tls pull                 # collect the CA-signed cert after approval\nsudo cenvero-str-ctl tls domain add api.example.net\n```\n\nThe certificate always covers the node's IP(s) plus loopback; a domain you point at\nthe node's IP can be added with `tls domain add`. See\n[TLS & Licensing](/docs/tls-and-license) for the approval flow.\n\n### `update`\n\nPull-based agent updates from your licensed release channel.\n\n| Command | Purpose |\n|---|---|\n| `update check` | Report current vs latest version + channel (no download) |\n| `update apply` | Download, verify, and apply an available update now (alias `update now`) |\n| `update rollback` | Roll back to the previously-installed version |\n\n```bash\ncenvero-str-ctl update check\nsudo cenvero-str-ctl update apply\nsudo cenvero-str-ctl update rollback   # undo the last apply\n```\n\n`update apply` verifies the download's signature, swaps the binary atomically, and\nrestarts under watchdog supervision with self-rollback if the post-restart health\ncheck fails. A node in the **Frozen** license state keeps running but cannot pull\nupdates until the license is renewed. See [Upgrades](/docs/upgrades).\n\n`update rollback` restores the binary that the most recent `update apply`\npreserved, undoing that update; restart the agent (`systemctl restart\ncenvero-stratum`) to run the restored version. If no update has been applied on\nthis node there is nothing to restore and it reports *\"no previous version to roll\nback to\"*. Rollback is a change, so it is refused while the license is **Frozen**.\nRe-applying a version at or below the highest version this node has ever run is\nrefused by downgrade protection — to move forward again, install a newer release.\n\n### `license`\n\n| Command | Purpose |\n|---|---|\n| `license activate <license-key>` | Send this machine's activation request (confirm it in your account) |\n| `license fetch <license-key>` | Fetch the signed license once it has been confirmed |\n| `license renew` | Force a license renewal for this machine |\n| `license refresh` | Re-fetch the signed license for this machine |\n| `license load <file>` | Load a signed license file manually |\n| `license status` | Full installed-license picture: identity, validity/state, features, hardware binding |\n\nThe license key is **positional**, not a flag. Activation binds the license to this\nmachine's hardware ID and waits for you to confirm the machine in your account; the\nagent then installs the signed license automatically.\n\n```bash\nsudo cenvero-str-ctl license activate CNVR-XXXX-XXXX-XXXX-XXXX\nsudo cenvero-str-ctl license status\n```\n\n`license status` is read-only and works offline from on-disk state, so it still\nanswers when the agent is down or the node cannot reach the licence server.\n\nThe same picture is available over the API as `GET /api/v1/license`, which reads\nthe running agent rather than the disk — useful for checking a fleet's expiry\ndates without a shell on every box. See [API Reference](/docs/api).\n\nSee [Licensing](/docs/licensing) for the warning → grace → freeze model.\n\n---\n\n## Networking\n\n### `network`\n\nA *network* is a managed private network: a CIDR pool whose usable host IPs are\neach materialized into an **endpoint profile** (a fixed IP paired with a generated\nMAC). You attach a workload by claiming a free endpoint — the endpoint *is* the\nworkload's network identity.\n\n| Command | Purpose |\n|---|---|\n| `network create` | Create a network (`--name --cidr [--gateway --vlan --tenant]`) |\n| `network list` | List networks |\n| `network show <id>` | Network detail + its endpoints |\n| `network endpoints <id>` | List a network's endpoint profiles (IP ↔ MAC) |\n| `network attach <id> [--ip] [--mac]` | Claim an endpoint (optionally a specific IP and MAC) |\n| `network set-mac <endpoint-id> <mac>` | Change an endpoint's MAC, keeping its IP |\n| `network detach <endpoint-id>` | Free a bound endpoint |\n| `network delete <id>` | Delete a network |\n\n```bash\nsudo cenvero-str-ctl network create --name app-net --cidr 10.20.0.0/24 --gateway 10.20.0.1\nsudo cenvero-str-ctl network attach <network-id> --ip 10.20.0.50\n```\n\nEach endpoint is an IP paired with a MAC address, and the MAC is assigned for you.\nPass `--mac` when the workload already has a fixed address of its own — a virtual\nmachine image, or an appliance whose licence is tied to one — so the fabric\naccepts the address it will actually send from:\n\n```bash\nsudo cenvero-str-ctl network attach <network-id> --ip 10.20.0.50 --mac 52:54:00:ab:01:02\n\n# ...or change it afterwards, keeping the same IP\nsudo cenvero-str-ctl network set-mac <endpoint-id> 52:54:00:ab:01:02\n```\n\nA MAC must be unique across endpoints, and a multicast address is refused — one\ncan never be a source address, so traffic from it would be dropped.\n\n### `nic`\n\n| Command | Purpose |\n|---|---|\n| `nic list` | List detected network interfaces |\n| `nic detect` | Re-scan and list interfaces |\n| `nic accel` | Show the acceleration mode (hardware vs software) per interface |\n\n### `ipam`\n\n| Command | Purpose |\n|---|---|\n| `ipam pools` | List IP pools |\n| `ipam allocations` | List every allocation (optional tenant id) |\n| `ipam allocate` | Allocate an IP address |\n| `ipam release` | Release an IP address |\n\n### `dhcp`\n\n| Command | Purpose |\n|---|---|\n| `dhcp leases` | List DHCP leases |\n| `dhcp reservations` | List static MAC→IP reservations |\n| `dhcp reserve <mac> <ip> [--hostname]` | Pin a static MAC→IP reservation |\n| `dhcp release <mac>` | Remove a static reservation, returning the address to the pool |\n\n```bash\nsudo cenvero-str-ctl dhcp reserve 52:54:00:ab:01:02 10.0.0.50 --hostname db01\n```\n\nA reserved address is handed out on the client's next request, survives an agent\nrestart, and appears immediately in `dhcp leases`.\n\n### `dns`\n\nManage authoritative zones, records, recursive forwarders, and DNSSEC.\n\n| Command | Purpose |\n|---|---|\n| `dns zones` | List zones |\n| `dns records [zone_id]` / `dns list [zone_id]` | List records (optionally for one zone) |\n| `dns add <zone_id> <name> <type> <value> [ttl] [source_subnet]` | Add a record |\n| `dns delete <record_id>` | Delete a record |\n| `dns dnssec <zone>` | Show a zone's DNSSEC keys + the DS record to lodge with the parent |\n| `dns zone list/add <name>/delete <zone_id>` | Zone CRUD |\n| `dns record list [zone_id]/add .../delete <record_id>` | Record CRUD |\n| `dns forwarder list/set <ip…>/add <ip…>/remove <ip…>` | Manage recursive forwarders |\n\nEach forwarder is an IP or `IP:port` (bare IPs default to `:53`). `dns forwarder`\nchanges apply to the running agent; persist them across restarts with\n`config set dns_upstreams <ip,...>`.\n\n```bash\nsudo cenvero-str-ctl dns zone add app-net.internal\nsudo cenvero-str-ctl dns add 1 api A 10.20.0.55 300\n```\n\n### `vlan`\n\nA per-VLAN allow/deny table. An empty table means every VLAN is allowed (default).\n\n| Command | Purpose |\n|---|---|\n| `vlan list` | List the allow/deny policy |\n| `vlan deny <id>` | Lock down a VLAN |\n| `vlan allow <id>` | Record an explicit allow |\n| `vlan clear <id>` | Clear a VLAN's policy (back to default-open) |\n\n### `vxlan`\n\n| Command | Purpose |\n|---|---|\n| `vxlan list` | List overlay networks |\n| `vxlan create <vni> <subnet>` | Create an overlay network |\n| `vxlan delete <vni>` | Delete an overlay network |\n| `vxlan peers <vni>` | List a VNI's remote peers |\n| `vxlan peer-add <vni> <host> <mac> <vtep_ip>` | Add a remote peer |\n| `vxlan peer-remove <vni> <host>` | Remove a remote peer |\n| `vxlan fdb` | Dump the overlay forwarding database |\n\n### `route`\n\nStatic routes (optionally in a non-main table) and the policy rules that steer\ntraffic into those tables.\n\n| Command | Purpose |\n|---|---|\n| `route list [table]` | List routes (optional table id) |\n| `route add <json>` | Add a route — JSON `{destination,gateway,interface,metric,table}` |\n| `route delete <id>` | Delete a route by id |\n| `route rule list` | List policy-routing rules |\n| `route rule add <json>` | Add a rule — JSON `{priority,from,to,fwmark,iif,oif,table}` |\n| `route rule delete <id>` | Delete a policy-routing rule by id |\n\n---\n\n## Security\n\n### `firewall`\n\n| Command | Purpose |\n|---|---|\n| `firewall allow` | Add an allow rule |\n| `firewall deny` | Add a deny rule |\n| `firewall list` | List firewall rules |\n| `firewall delete` | Delete a rule |\n| `firewall conntrack` | Show the connection-tracking table |\n| `firewall conntrack-flush [ipv4]` | Drop connection-tracking state so rule changes apply to connections that are already open (optionally just one peer) |\n| `firewall schedule set/clear/list` | Attach a time-of-day/day-of-week activation window (UTC) to a rule |\n| `firewall connlimit set/clear/status` | Per-source concurrent-connection limits (IPv4) |\n\n### `rules`\n\nThe structured firewall rule table (chains, priorities, stateful matching).\n\n| Command | Purpose |\n|---|---|\n| `rules list` | List all rules |\n| `rules add` | Add a rule |\n| `rules remove <id>` | Remove a rule by id |\n| `rules preset <web/db/mail/game/minimal/open>` | Apply a server preset rule-set atomically |\n| `rules batch <json-rule-array>` | Apply a JSON array of rules atomically |\n\n---\n\n## Traffic shaping & visibility\n\n### `bandwidth`\n\n| Command | Purpose |\n|---|---|\n| `bandwidth list` | List per-MAC rate limits and shared pools |\n| `bandwidth set` | Create/update a per-MAC rate limit |\n| `bandwidth pool` | Manage shared bandwidth pools |\n\n### `quota`\n\nMonthly per-MAC usage caps that reset at the start of each UTC month.\n\n| Command | Purpose |\n|---|---|\n| `quota list` | List quotas with their status |\n| `quota set <json>` | Create/update a quota |\n| `quota get <mac>` | Show one MAC's quota + status |\n\n### `flow`\n\n| Command | Purpose |\n|---|---|\n| `flow list` | List active flows (optional state filter) |\n| `flow stats` | Aggregate flow statistics |\n\n---\n\n## Services & HA\n\n### `lb`\n\nL4 virtual IPs (VIPs) with a backend pool.\n\n| Command | Purpose |\n|---|---|\n| `lb list` | List VIPs |\n| `lb create` | Create a VIP and backend set |\n| `lb show` | Show a VIP's detail |\n| `lb backends <id>` | List a VIP's backends |\n| `lb add-backend` / `lb remove-backend` | Adjust backends live |\n| `lb drain <vip_id> <backend_id>` | Stop sending new connections to a backend and let the existing ones finish |\n| `lb set-health` | Configure a VIP's health check |\n| `lb delete` | Delete a VIP |\n\n### `bgp`\n\n| Command | Purpose |\n|---|---|\n| `bgp status` | Engine status |\n| `bgp neighbors` | List peers |\n| `bgp routes` / `bgp rib` / `bgp fib` | Route table / RIB / forwarding table |\n| `bgp peer` | Manage peers (add/list/remove) |\n| `bgp announce` / `bgp withdraw` | Advertise / withdraw a prefix |\n| `bgp announcements` | List active announcements |\n| `bgp prefix-list` | Manage prefix-lists (`add <json>` / `list`) |\n| `bgp route-map` | Manage route-maps (`add <json>` / `list`) |\n| `bgp policy` | Bind import/export route-maps (`import/export <neighbor> <route-map>` / `list`) |\n| `bgp import-policy` | Manage import policy |\n\n### `gateway`\n\n| Command | Purpose |\n|---|---|\n| `gateway status` | Gateway HA status |\n| `gateway failover` | Trigger a manual gateway failover |\n\n### `ha`\n\nGateway high-availability: two paired nodes run active/standby and the active node\nowns a virtual IP (VIP), taking it over on failover.\n\n| Command | Purpose |\n|---|---|\n| `ha status` | Show HA status (active/standby/solo, VIP, peer) |\n| `ha set-peer` | (Provisioned via the panel-delivered config) |\n| `ha configure` | (Provisioned via the panel-delivered config) |\n\nHA is configured from the panel-delivered configuration (peer address, priority,\nVIP, and a shared secret) and read at agent boot. Use `ha status` and the\n[REST gateway endpoints](/docs/api) for live status and\nmanual failover.\n\n### `bond`\n\nCombine physical NICs into a bond for redundancy or throughput. A bond is created\nwith a device name you choose (use the `cnv-` prefix, max 15 chars) in one of two\nmodes: `active-backup` (one member carries traffic, another takes over on failure)\nor `802.3ad` (LACP aggregation, needs a matching switch port-channel).\n\n| Command | Purpose |\n|---|---|\n| `bond list` | List bonds |\n| `bond show <id>` | Show a bond (mode, MTU, active member, members) |\n| `bond create --name <dev> --mode active-backup/802.3ad [--mtu N]` | Create a bond |\n| `bond add-member <id> --iface <nic>` | Enslave a NIC |\n| `bond remove-member <id> --iface <nic>` | Release a NIC |\n| `bond set-mtu <id> --mtu N` | Set the MTU across the bond + members |\n| `bond delete <id>` | Delete a bond (releases its members first) |\n\n```bash\nsudo cenvero-str-ctl bond create --name cnv-bond0 --mode active-backup\nsudo cenvero-str-ctl bond add-member <bond-id> --iface cnv-nic-1\nsudo cenvero-str-ctl bond set-mtu <bond-id> --mtu 9000\n```\n\n`create` prints the bond's **logical id** (e.g. `bond-1a2b…`); use that id — not the\ndevice name — with the other subcommands. Members are referenced by interface name.\n\n### `cluster`\n\nInspect this node's clustering state. Every member is the same kind of node, so\nthere is nothing to choose here — `cluster status` reports the local role in the\ncluster (leader or follower), not a node type.\n\n| Command | Purpose |\n|---|---|\n| `cluster status` | Cluster state, leader, and peers |\n| `cluster join` | (Configured via the panel-delivered config / REST API) |\n| `cluster leave` | (Configured via the panel-delivered config / REST API) |\n\nCluster membership is configured through the panel-delivered configuration; peers\nauthenticate with mutual TLS (no join token to type). Use `cluster status` to check\nthe local state. See [Clustering](/docs/clustering/overview).\n\n---\n\n## Tenants & billing\n\n### `tenant`\n\nTenants are your downstream customers on this node, each with a resource quota and\noptional scoped API keys.\n\n| Command | Purpose |\n|---|---|\n| `tenant list` | List tenants |\n| `tenant create --name <name>` | Create a tenant |\n| `tenant delete <id>` | Delete a tenant — also removes its scoped API keys, quota, private networks, and IPAM pools/allocations |\n| `tenant quota <id>` | Show a tenant's bandwidth cap |\n| `tenant quota-set <id> --max-bandwidth-bps N` | Set a tenant's bandwidth cap (`0` = unlimited) |\n| `tenant key-generate <id> [--name <label>] [--ttl 720h]` | Mint a scoped API key for a tenant |\n| `tenant key-list <id>` | List a tenant's scoped API keys |\n| `tenant key-revoke <key-id>` | Revoke a scoped API key |\n\nA scoped key authenticates as the tenant but is confined to that tenant's resources.\nThe secret is shown only once, at mint time.\n\n### `apikeys`\n\nOperator API keys for the billing API. A minted key authenticates your billing\nsystem against the agent's `/api/v1/billing` endpoints.\n\n| Command | Purpose |\n|---|---|\n| `apikeys mint <label>` | Mint a new key (secret shown once) |\n| `apikeys list` | List keys (no secrets) |\n| `apikeys revoke <id>` | Revoke a key by id |\n\n### `billing`\n\nDrive one of your customers' (a tenant's) account state — the same actions your\nbilling system calls over REST.\n\n| Command | Purpose |\n|---|---|\n| `billing suspend <tenant-id>` | Suspend a tenant |\n| `billing resume <tenant-id>` | Resume a tenant |\n| `billing limit <tenant-id> --rate-mbps N` | Apply an aggregate rate cap (Mbps; `0` = unlimited) |\n| `billing unlimit <tenant-id>` | Remove a tenant's rate limit |\n| `billing status <tenant-id>` | Show a tenant's billing state |\n\nSee [Billing Integration](/docs/billing-integration).\n\n---\n\n## Operations\n\n### `backup`\n\n| Command | Purpose |\n|---|---|\n| `backup create [config/full]` | Create a backup (default `config`) |\n| `backup restore <id/path>` | Restore from a backup |\n| `backup list` | List backups |\n| `backup schedule add <expression> [config/full] [retention]` | Add a schedule (e.g. `daily@03:00 full 7`) |\n| `backup schedule remove <id>` | Remove a schedule |\n\n### `alert`\n\n| Command | Purpose |\n|---|---|\n| `alert status` | Alerting status (counts + action-dispatch success/failure) |\n| `alert list` | List fired alerts (optional state filter) |\n| `alert history` | Full alert history |\n| `alert ack <alert_id>` | Acknowledge a firing alert |\n| `alert condition list` | List threshold conditions |\n| `alert condition add <json>` | Add a condition, e.g. `'{\"metric_type\":\"pps\",\"operator\":\"gt\",\"threshold\":1000}'` |\n| `alert condition remove <id>` | Remove a condition |\n| `alert action list` | List configured actions across all conditions |\n| `alert action add <condition_id> <websocket/log/webhook> [config]` | Attach an action to a condition |\n\n### `heal`\n\n| Command | Purpose |\n|---|---|\n| `heal status` | Latest health-check results |\n| `heal check` | Force an immediate health-check run |\n\n### `container`\n\nAttach a container's network namespace to a managed network using the same plumbing\na VM endpoint uses (a managed IP + MAC, a veth pair into the network's bridge).\n\n| Command | Purpose |\n|---|---|\n| `container list` | List attached containers |\n| `container show <id>` | Show an attachment by its logical id |\n| `container attach --runtime <lxc/docker/podman> --network <id> --netns-pid <pid> [--ip <ip>] [--firewall]` | Attach a container netns |\n| `container detach <id>` | Detach (tears down the veth, frees the endpoint) |\n\n```bash\nsudo cenvero-str-ctl container attach --runtime docker --network net-1 --netns-pid 12345\n```\n\n`--netns-pid` is the PID of any process inside the container (e.g. its init).\n`attach` prints a logical container id; use that id with `show` / `detach`.\n\n### `plugin`\n\n| Command | Purpose |\n|---|---|\n| `plugin install <target>` | Install a plugin — a bare `<name>` from the official store, `<username>/<name>` from a trusted external store, or a local package path |\n| `plugin list` | List installed plugins |\n| `plugin show` | Show plugin detail |\n| `plugin remove` | Remove a plugin |\n| `plugin verify` | Verify a plugin package signature |\n| `plugin enable` / `plugin disable` | Enable / disable a plugin |\n| `plugin store add <signed-store-file>` | Trust an external plugin store (verified offline) |\n| `plugin store list` | List trusted plugin stores |\n| `plugin store remove <username>` | Remove a trusted external store |\n\nThe official Cenvero store is always present (its plugins install as a bare\n`<name>`). An added external store's plugins install as `<username>/<name>`. See\n[Plugins](/docs/plugins/overview).\n\n### `node`\n\n| Command | Purpose |\n|---|---|\n| `node info` | Node information: hardware id, agent version |\n\n---\n\n## Exit codes\n\n| Code | Meaning |\n|---|---|\n| 0 | Success |\n| 1 | General error |\n| 2 | Invalid arguments |\n| 3 | Agent unreachable (is `cenvero-stratum.service` running?) |\n| 4 | Operation blocked by license enforcement (see [Licensing](/docs/licensing)) |\n\n## See also\n\n- **[API Reference](/docs/api)** — the same managers over REST/WebSocket/gRPC.\n- **[Configuration](/docs/configuration)** — the node config model and every field.\n- **[Operations](/docs/operations)** — day-2 running, updates, and troubleshooting.\n"
        }
    ]
}