{
    "product": "Cenvero Stratum",
    "generated_at": "2026-10-10T15:58:24+00:00",
    "format": "cenvero-docs-v1",
    "document_count": 1,
    "documents": [
        {
            "slug": "compute/web-console",
            "title": "The Web Console",
            "category": "Compute",
            "url": "https://www.stratum.cenvero.com/docs/compute/web-console",
            "headings": [
                {
                    "level": 1,
                    "text": "The Web Console"
                },
                {
                    "level": 2,
                    "text": "Opening it"
                },
                {
                    "level": 2,
                    "text": "Signing in"
                },
                {
                    "level": 2,
                    "text": "What it shows"
                },
                {
                    "level": 3,
                    "text": "Tasks"
                },
                {
                    "level": 3,
                    "text": "Graphs"
                },
                {
                    "level": 3,
                    "text": "The log"
                },
                {
                    "level": 3,
                    "text": "Creating a machine"
                },
                {
                    "level": 3,
                    "text": "Every node of a cluster"
                },
                {
                    "level": 2,
                    "text": "A machine's screen and serial console"
                },
                {
                    "level": 2,
                    "text": "When the licence refuses changes"
                },
                {
                    "level": 2,
                    "text": "Security"
                },
                {
                    "level": 2,
                    "text": "A portal for your customers"
                },
                {
                    "level": 2,
                    "text": "Current limits"
                },
                {
                    "level": 2,
                    "text": "See also"
                }
            ],
            "word_count": 3416,
            "markdown": "# The Web Console\n\nEvery node whose local API is on serves a console in the browser: the\nnode's operator sees what runs on it and manages its networks, machines,\nimages, volumes and tenants — including each machine's screen and serial\nconsole, its graphs, and every task and change made on the node — without a\ncommand line.\n\nThe same page is also a **portal for your customers**: a customer who signs in\nwith their tenant key sees only their own machines, networks and public\naddresses, and can start, stop and restart their machines, open their consoles\nand reset a password — see [A portal for your customers](#a-portal-for-your-customers).\n\n> Part of [Compute](/docs/compute/overview), in early access. The console is\n> served by the node itself; it never passes through Cenvero.\n\n## Opening it\n\nThe console lives on the same address and port as the node's local API, under\n`/console/`; the node's address on its own (`https://<node>:7070/`) leads there\ntoo:\n\n```\nhttps://<node>:7070/console/\n```\n\n- The local API must be on. A node installed with the `compute` or `suite`\n  profile has it on from the start: the installer generates the node's API\n  token, keeps it root-only in `/etc/cenvero-str/api-token`, and ends by\n  printing the console's address. Otherwise the API is off until a token is\n  set — see [API Reference](/docs/api) (`cenvero-str-ctl api-token generate`).\n  The console is on whenever the API is; there is no separate switch.\n- The page uses the node's own certificate. If the node's certificate is not\n  one your browser trusts, the browser warns first; check that the address is\n  the node's before you continue.\n- If you restricted the API to certain addresses (`api_allowed_ips`), the\n  console is restricted to them too. In a cluster, each member's own list\n  applies to your address, whichever member you signed in to (see\n  [Every node of a cluster](#every-node-of-a-cluster)).\n\n## Signing in\n\nOperators sign in with an **operator API key** or the node's **API token**\n(customers sign in with their tenant key — see\n[A portal for your customers](#a-portal-for-your-customers)):\n\n```bash\nsudo cenvero-str-ctl apikeys mint \"web console\"   # prints the key once\n```\n\nA key per person is better than sharing the token: the node records which key\nsigned in, and you can revoke one person's key without affecting anyone else.\n\n- The key is sent once, in the sign-in request, over the node's encrypted\n  connection. The browser never stores it; the node keeps it in memory for the\n  session only.\n- The session is held in a cookie the page's scripts cannot read. It ends after\n  **30 minutes without activity** (the page warns you two minutes before), after\n  **12 hours** in all, when you sign out, and when the agent restarts. Typing\n  or using the mouse in a machine's console counts as activity; a page left\n  open on its own does not.\n- Revoking the key (`cenvero-str-ctl apikeys revoke <id>`) or changing the API\n  token ends every session signed in with it, at its next request, and closes\n  the machine consoles opened with it within a few seconds.\n- A tenant key signs in to that tenant's portal, never to the operator\n  console.\n- Up to 64 operator sessions can be open at once; signing in again when they\n  are all in use closes the one used least recently. Customers' sessions are\n  counted apart — at most eight per customer account, where a ninth sign-in\n  closes that account's least recently used session — so a customer signing\n  in again and again never signs you out.\n- Sign-in attempts are limited per address (a burst of 5, then 10 a minute).\n  Five wrong keys lock that address out of the API — console included — for\n  five minutes.\n\n## What it shows\n\nThe console is laid out like a datacenter manager: a bar along the top, a tree\nof everything on the left, the page of what you selected in the middle, and\nthe node's tasks along the bottom.\n\n- **The top bar.** Search (press **Ctrl K** or **/** from anywhere), the tasks\n  running now, the alerts firing, the licence's state, and your sign-in.\n- **The tree.** *Datacenter* → the node → its **Machines**, **Networks**,\n  **Storage**, **Images** and **Tenants**, each machine with its state as a\n  shape and, when it is not the usual one, a word (*stopped*, *suspended*,\n  *degraded*). Switch to the **Tenants** view to see each tenant's machines,\n  networks and volumes together, and the operator's own apart. Type in the\n  filter box to find something by name, id, address or tenant. On a phone the\n  tree opens from the menu button.\n- **Pages with tabs.** Every object has its own address, so a reload — or a\n  link you send someone — opens the same page and tab.\n\n| Page | Tabs | What you can do |\n|---|---|---|\n| **Datacenter** | Summary (nodes, totals, what needs attention — with the button that fixes it —, running tasks) · Cluster · Tasks · Log · Search | Start a machine that should be running; form, join or manage a [cluster](#every-node-of-a-cluster) |\n| **Node** | Summary (graphs of CPU, memory, disk space and network; version, licence, modules, services, self-healing checks, capacity, alerts) · Machines · Networks · Storage · Images · Tenants · Tasks | Create a machine (the wizard, below) |\n| **Machine** | Summary (its state explained, graphs of CPU, memory, disk activity and network, guest agent, open consoles) · Hardware (size, network cards, volumes) · Console · Tasks · Log | Start, stop, restart, force stop; change size; add, reconnect or remove a network card; delete |\n| **Network** | Summary · Addresses (which are in use, and by what) · Machines | Turn the host gateway (masquerade, DHCP) on or off; delete |\n| **Volume** | Summary (size, what it is attached to, protection) · Snapshots · Backups · Tasks | Attach, detach, back up now, snapshot, grow, set how many backups to keep, revert to a snapshot, restore a backup, delete |\n| **Tenant** | Summary (usage against quotas) · Machines · Networks · Volumes | Set quotas; suspend and resume; delete |\n| **Task** | What it does and to what, who started it, how far it has got, when it started and ended, and its log, which follows the task while it runs | Cancel, where the operation can stop safely |\n\nDeleting anything asks you to confirm, and deleting a machine, network, volume\nor tenant asks you to type its name.\n\n**Changes appear as they happen.** A machine that stops, a task's progress, a\nvolume that is attached: the tree, the task panel and the page you are on\nfollow the node as it changes, without a reload. If that live connection is\ninterrupted the console reconnects on its own and catches up on what it\nmissed; until it is back, pages refresh every 15 seconds. (The customer\nportal refreshes every 15 seconds.)\n\n### Tasks\n\nStarting a machine, downloading an image, backing up a volume and every other\nlonger operation is a **task**. The panel along the bottom lists the latest\ntasks with their progress — for downloads and backups, the bytes done of the\ntotal — and opens at once when you start one. Open a task to read its log as\nit is written, and to cancel it where the operation can stop safely. On a\nphone, the tasks are a page of their own.\n\n### Graphs\n\nA node's and a machine's graphs cover the last hour as it happens (**Live**),\nor an hour, a day, a week, a month or a year. **Average** shows each point as\nthe average of its time step and **Peak** as its highest value. Point at a\ngraph, or focus it and use the arrow keys, to read the figures at a moment;\nevery graph can also show its figures as a table. Times are in UTC. A break in\na line is a time when nothing was recorded — the machine was stopped, or the\nagent was not running.\n\n### The log\n\nThe Datacenter's **Log** tab lists every change made to the node (and every\nattempt that was refused), every console sign-in and sign-out, and each task's\nstart and end: when, who, what, on which object, from which address, and how\nit ended. Filter by time, person, action, object or outcome; **Download**\nsaves every record the filters select, one per line; **Verify the log** checks\nthat no record was changed or removed since it was written, and says so in a\nsentence. A machine's own **Log** tab shows the records about it.\n\n### Creating a machine\n\n**Create machine** opens a wizard: its name and owner, the image it starts\nfrom, its size, its disk, its network cards and public address, and what it is\ntold when it first starts (hostname and SSH keys). Sensible defaults are filled\nin — two vCPUs, 2 GiB of memory, a disk the image's size rounded up to the next\n10 GiB, the owner's first network — and a mistake is named beside the field\nbefore anything is sent. The last step says in one sentence what will be\ncreated. **Show as command** gives the `cenvero-str-ctl` command that creates\nexactly the same machine (run it on the node as root), and **Show as API call**\nthe same request for the [API](/docs/api).\n\n### Every node of a cluster\n\nOn a member of a [cluster](/docs/clustering/overview) (agent 1.0.0-rc.81 or\nlater), the console manages every member, whichever one you signed in to:\n\n- **The tree** lists every member under *Datacenter*, each with its machines,\n  networks, storage and images; tenants are shared by the members and appear\n  once. A member that stops answering is marked, within a few seconds, with\n  when it was last heard from (*last seen 12 s ago*), and its objects stay\n  listed from its last answer. A member that has not finished joining is shown\n  as *joining*, and one on a version that cannot be managed from here as\n  *update needed*, with a link to its own console.\n- **Actions** on another member's machines, networks and volumes work as on the\n  node you signed in to: the member that holds them does the work, under its own\n  licence. A machine's screen and serial console open through the node you\n  signed in to.\n- **Tasks, the Log and live changes** cover every member. The Log can be\n  filtered by node, and **Verify the log** answers for each member, since each\n  keeps its own log.\n- **Datacenter › Cluster** lists the members — role, whether it votes, its\n  state (online, or when it was last seen), version, cluster address, when its\n  identity expires, and a warning when its clock is off. It offers **Make a join\n  code** (the code is shown once, with a copy button, a countdown and the\n  command to run on the new node), the codes made so far with **Revoke**, and\n  **Remove…** on each other member's row (type the node's name, then press\n  **Remove node**). Under **Advanced**: giving a member a new identity,\n  replacing the cluster's certificate authority, and **Leave the cluster…**,\n  which takes the node you signed in to out of the cluster (type the cluster's\n  name to confirm).\n- **On a member whose plan no longer includes clustering**, Datacenter ›\n  Cluster says so. It still lists the members and the join codes, with\n  **Revoke**, **Remove…** and **Leave the cluster…**. Making a join code,\n  giving a member a new identity and replacing the authority wait until the\n  plan includes clustering again.\n- **On a node that is not in a cluster**, Datacenter › Cluster offers **Form a\n  cluster** (a name and this node's address, then **Form the cluster**) and\n  **Join a cluster**: paste a join code, check the address offered for this\n  node, and press **Next**. The node asks the cluster what joining would mean,\n  without using up the code, and the summary names the cluster and its size,\n  the address, the tenants that will be shared, and any conflicts that stop the\n  join. Nothing changes until you press **Join the cluster**.\n- **Creating a machine** asks where: it offers the members that can run\n  machines, have Compute in their licence and are not frozen. **Show as\n  command** says which node to run it on, and **Show as API call** addresses\n  that node (`/api/v1/nodes/<node id>/…`).\n- **A member that is not answering** keeps its pages, showing what it last\n  reported; changes to it are held back, with when it was last heard from,\n  until it is back. Everything else keeps working.\n- **A member that does not accept your address.** Each member applies its own\n  `api_allowed_ips` to your browser's address, also when you signed in to\n  another member. If a member's list does not include it, every action and\n  console on that member is refused with **403**\n  `forbidden: source address not allowed`, and Tasks and the Log name it among\n  the members that did not answer. Its machines and networks still appear in\n  the tree: that is a known limitation.\n\n## A machine's screen and serial console\n\nA running machine's **Console** tab opens its consoles in the browser:\n\n- **Display** — the machine's screen, keyboard and mouse. Buttons send\n  Ctrl+Alt+Del, switch between fitting the window and actual size, and go full\n  screen. Up to four people can watch at once.\n- **Serial console** — the machine's first serial port, in a terminal. One\n  session per machine; if another session has it, **Take over** closes that one\n  and connects you.\n\nThe console opens these exactly as described in [Consoles](/docs/compute/consoles):\nwith a single-use ticket, from the node's own address. The same limits apply —\na session closes after 30 minutes without input, and when the machine stops.\nA machine's console never outlives your sign-in: it closes at once when you\nsign out, and when your session ends or the key you signed in with is revoked.\n\nLinks in the serial console's output are shown as text only: the console never\nopens them, so nothing a machine prints can open a window or leave the page.\n\n## When the licence refuses changes\n\nThe console shows what the licence allows, with the node's own reason:\n\n- **A frozen licence** (or none installed): a banner says the console is\n  read-only. Everything keeps running, and you can still look at everything and\n  open consoles; every change is refused until the licence is renewed. In a\n  cluster, removing a member, leaving and revoking a join code still work, so\n  a node can always be taken out.\n- **A module not in the plan**: its pages still show what exists, but the\n  buttons that would change it are disabled, with the reason — for example,\n  that Storage is not included in the plan.\n- **A module that is not available on the node** (Compute on a server where the\n  virtualization service is not installed, say): the page says why, in the\n  node's words.\n\nThe console enforces nothing itself: every action goes to the node's API with\nyour key, and the API applies the same checks it applies to any other client.\nA button the console shows as enabled can still be refused, and the console\nthen shows the node's answer.\n\n## Security\n\n- Every change the page makes carries a per-session token and must come from\n  the console's own page; a page on another site cannot act through your\n  session.\n- The console's pages load nothing from anywhere else and cannot be framed by\n  another site.\n- Sign-ins, refused sign-ins, sign-outs and sessions that end are recorded in\n  the node's audit log (see [Monitoring](/docs/monitoring)), and every change\n  made through the console is recorded with the session it came through. They\n  are also written to the node's log as audit entries (`audit=true`) and\n  published as the events\n  `console.signed_in`, `console.sign_in_refused`, `console.signed_out` and\n  `console.session_ended`, so the [event stream](/docs/api) and webhooks carry\n  them. They name the key that was used, never the key itself.\n\n## A portal for your customers\n\nIf you host machines for customers, each customer can have the same console,\nconfined to their own account. You create a **tenant** for the customer, give\ntheir machines to that tenant, and hand the customer a **tenant key**; they\nsign in at the same address with that key.\n\n**1. Create the customer's key.**\n\n```bash\nsudo cenvero-str-ctl tenant key-generate <tenant-id> --name \"acme portal\" --ttl 2160h\n```\n\nThe key is printed once. Send it to the customer over a channel you trust, and\ngive it an expiry (`--ttl`) so it lapses on its own if it is forgotten. A key\ncan also be minted over the API (`POST /api/v1/tenant/{id}/keys`, see\n[Tenants](/docs/tenants)). Revoke it with\n`sudo cenvero-str-ctl tenant key-revoke <key-id>`: every session signed in with\nit ends at its next request, and the machine consoles opened with it close\nwithin a few seconds.\n\n**2. Send the customer the address.** It is the node's console address,\n`https://<node>:7070/console/`. The customer's browser must be able to reach\nit, and must trust the node's certificate (see [Opening it](#opening-it)); if\nyou restricted the API to certain addresses (`api_allowed_ips`), include the\ncustomer's.\n\n**What the customer sees and can do.** The portal wears the same layout, with\na tree of the customer's own machines and networks:\n\n| Page | What they see | What they can do |\n|---|---|---|\n| **Overview** | Their account's state (active or suspended), their limits and usage (machines, bandwidth, volumes), and their machines | — |\n| **Machines** | Their own machines: state, size, addresses, network cards, open consoles, guest agent, and graphs of CPU, memory, disk activity and network | Start, stop, restart, force stop; open the display and serial console; reset a user's password through the guest agent |\n| **Networks** | Their own private networks and which of their machines use them | — |\n| **Public addresses** | The public addresses their machines hold | — |\n| **Tasks** | What was done to their machines and volumes, by them or by you, and how it ended | — |\n| **Activity** | What was done with their keys: portal sign-ins and actions on their machines | — |\n\n**What stays with you.** Creating and deleting machines, networks and volumes,\nchanging a machine's size or interfaces, and changing the account's limits,\nbandwidth or state are not in the portal, and the node refuses them to a\ntenant key whatever it sends. A customer never sees another customer's\nmachines, networks or addresses — asking for one by its id answers exactly as\nif it did not exist — nor your own machines, the node's licence or anything\nelse on the node.\n\n**When you suspend the account.** Suspending a tenant stops its machines. The\ncustomer can still sign in and look at everything, with a banner saying the\naccount is suspended, but starting, stopping or restarting a machine, opening a\nconsole and resetting a password are refused until you resume the account. A\nconsole ticket issued before the suspension is refused when it is used, and a\nconsole the customer already has open closes within a few seconds.\n\n**What the customer is told when something fails.** The portal answers in\nplain, fixed sentences — that the machine cannot be started right now, that no\nguest agent is running in it, and so on — never with the server's own error\ntext. When a machine itself refuses a new password (an unknown user, say), the\ncustomer is shown the machine's own reason.\n\n**When the node's licence refuses changes.** A frozen licence refuses the\ncustomer's power actions and password resets just as it refuses yours; the\ncustomer is told that changes are paused on the server and that their machines\nkeep running. Looking and opening consoles still work.\n\n**What the customer's actions leave behind.** Power actions, password resets,\nconsole sessions and portal sign-ins are recorded in the node's audit log naming\nthe tenant key's id (`cenvero-str-ctl audit list --tenant <id>`), like yours; the\ncustomer can read its own records in the portal's API\n(`GET /api/v1/tenant/{id}/audit`). Consoles the customer opens appear on\nthe machine's page in your console.\n\nThe portal shows what the customer's key allows; the node's API decides. A\ncustomer holding the key can make the same calls with any HTTP client — the\n[API Reference](/docs/api) lists what a tenant key may call.\n\n## Current limits\n\n- Without a cluster, one node per console: open each node's own address. Join\n  the nodes into a [cluster](/docs/clustering/overview) to manage them all from\n  any one of them.\n- In a cluster, the customer portal still shows a customer only what is on the\n  node whose tenant key they hold: tenant keys are not shared between members.\n- Personal accounts with passwords and roles are planned; today you sign in\n  with an API key or the node's API token.\n- The customer portal carries Stratum's name; your own logo and colours are\n  planned. Customers cannot yet create their own machines — provisioning goes\n  through you (or your billing system over the API).\n- Sessions live in the agent's memory: restarting or updating the agent signs\n  everyone out.\n\n## See also\n\n- [Consoles](/docs/compute/consoles)\n- [Virtual machines](/docs/compute/virtual-machines)\n- [Tenants](/docs/tenants)\n"
        }
    ]
}