# Accounts and the portal Fluksio is self-hosted by default. An installation runs offline, keeps its data on its own disk, and never contacts anything unless you tell it to. The **portal** is optional, and it exists to solve two specific problems: 1. **Your machine has no inbound route.** A homelab behind CGNAT, a cluster node with no open ports, a laptop. Opening one is work, and often not allowed. 2. **You want a browser on it anyway.** A `pip install fluksio` installation has no web server for the dashboard at all. An enrolled installation dials *out* to the portal and holds one websocket open. The portal serves the dashboard from its own side, and only the API calls travel down the tunnel — so the interface loads at portal speed and your machine stays unreachable from the internet. ## Enrolling Two halves, deliberately: whoever performs the second step decides what the installation's owner gets. **On the portal** (`hub.${DOMAIN}`, or [fluksio.com](https://fluksio.com) for the hosted one): **Installations → Add installation**, give it a name, and copy the code. **On the installation**, either from the dashboard: > **Settings → Remote access**, enter the portal URL and the code, press > **Connect**. or from the command line, which is the path for an installation with no web interface of its own: ```sh fluksio enroll ABCD-1234 --portal https://hub.fluksio.com ``` The code is single-use and expires in fifteen minutes. A portal session then arrives as *that local account* — the settings screen states this plainly, because it is the whole security model in one sentence. Use `--as someone@example.com` to enrol as a specific local account when the installation has several superusers. Once enrolled, the installation appears under **Installations** with its status, when it was last seen and its version. **Open** takes you to its dashboard at `${DOMAIN}/i/{installation-id}`. ## What the portal can and cannot do The portal holds one credential for your installation and proxies requests down the tunnel. What those requests may do is decided **on the installation**, by the same checks a local session passes. The trust anchor is a signing keypair on the portal. Every installation pins its public half at enrolment and rejects anything else — which is what stops a hijacked DNS entry or a mis-issued certificate from impersonating the portal. ## Letting someone else in Anyone else on the portal reaches your installation only if a superuser there admits them, and they arrive as a local user of their own rather than as you. 1. **They**: **Installations → Join an installation**, and copy the code. It is bound to their portal account and expires in fifteen minutes. 2. **You**, on the installation: **Settings → Remote access → Add remote user**, and enter the code. 3. They now see the installation under **Installations**, marked *Shared by*, with **Open** and nothing else. Renaming, re-keying and removing stay with you. The installation redeems that code against the portal using its own credential. A portal session cannot do this — which is what stops somebody you let in from letting others in. On the installation they appear under **Admin → Users**, badged *Portal*, never a superuser and with no password. ## Cutting it off | From | Action | Effect | |---|---|---| | The portal | **New code** | rotates the credential and drops the current link | | The portal | **Remove** | deletes the registration and cuts the connection | | The installation | **Disconnect** | unilateral and immediate — the portal's tokens stop verifying here whatever the portal still has on file | | The installation | delete a user under **Admin → Users** | that one person, immediately, independent of the portal | **New code** also cuts every credential the portal minted for this installation, including [wall panels paired through it](dashboards.md#a-screen-somewhere-you-cannot-reach). The installation's own **Disconnect** is the one to reach for if you are ever unsure: it does not need the portal's cooperation. ## Running your own portal The portal is the `index` stack's `hub` service — accounts, the registry of connected installations, and the websocket each one dials in on. Two things about it are load-bearing: - **It runs a single process.** It keeps its attached installations in the memory of the process holding their sockets, so a second worker would answer for links it does not hold. Scaling out needs a routing layer first. - **Back up the signing keypair with the database.** Replacing it forces every installation to be enrolled again. Websocket upgrades must be enabled on the `hub` hostname in whatever proxy fronts it. Without them every installation sits in a reconnect loop and the portal shows them all offline. ## See also - [The `fluksio` command](../code/cli.md) — `fluksio enroll`, and what it writes - [Dashboards and panels](dashboards.md) — pairing a wall screen through the portal - [Getting started: data science](../getting-started/data-science.md) — the shortest path from a pip install to a browser