Skip to content

Admin access & split container

The admin area (everything under /admin) can be isolated from the user portal so a stolen super-admin account alone is not enough — the attacker also needs network access to the admin topology.

Three modes

Mode Who gets in Effort When to use
unrestricted (default) Anyone with a login none Single-person setup, no elevated threat
ip_allowlist Only IPs in your CIDR list 1 setting Office IP / VPN subnet — sufficient for most self-hosters
split_container Own container under its own address; optionally also only IPs from your CIDR list high IT firms with many tenants

You switch modes under Admin → Login & Security → Admin Access (cards "Unrestricted", "IP allowlist", "Separate container"; super admins only, with identity confirmation). split_container is set up by the assistant on the same page (see below).

Which address belongs in the allowlist? The one the server sees you as — the tab shows it above the list ("The server sees you as …") with a button that adds it directly. For an instance on the internet that is your public address, not your PC's LAN address. The nginx of the Vesana stack is always trusted; if you run your own reverse proxy in front of it (a second nginx, Caddy, Traefik), add its network under "Advanced: reverse proxies (X-Forwarded-For)" — this list can be set in every mode, even without an allowlist (it also decides which address the audit log and session list show). A list that would lock you out is not saved unless you explicitly confirm it.

The setup wizard does not ask for the mode — unrestricted applies on first start, and you set the mode you want any time afterwards under Admin → Login & Security → Admin Access.


Split container — a dedicated admin container

When you choose "Separate container", Vesana runs two API containers: one serves the user portal (without admin functions), the other the admin area under its own hostname or port. You set it up with the assistant under Admin → Login & Security → Admin Access → Separate container — there is nothing to copy and no script you have to maintain yourself.

How the assistant works

  1. Detect — the assistant determines whether the nginx of the Vesana stack terminates TLS itself or whether a reverse proxy of your own sits in front (it compares the certificate on port 443 with the stack's). It also checks that the Compose file and images are recent enough — otherwise it stops right here.
  2. Address — subdomain (admin.<host>, recommended), a separate port, or both. DNS check and a cookie-domain suggestion included.
  3. Build — Vesana starts the admin container and verifies it internally. Nothing changes for the running instance; the admin area stays reachable as before. If a step fails, everything is rolled back and the reason is shown in plain language.
  4. Verify — what remains manual (with a reverse proxy in front: a vhost you get as a script; a certificate for the admin name) plus a reachability probe from your browser and from the server. Only when one of them reaches the admin container can you continue.
  5. Switch — only now is the mode set and the main container restarted without admin functions (the user portal is away for about half a minute). From then on the admin area is reachable only under the new address.

Safety net: after switching, a 30-minute window starts. If nobody logs in via the admin host in that time (the Access tab there confirms automatically), Vesana reverts the switch on its own — nobody stays locked out. The same happens if the restart fails.

Who reaches the admin host

The split separates the containers, not the network. In subdomain mode the admin host sits on the same IP and the same port as the portal — the only difference is the host name the browser sends. Anyone who knows the address reaches the admin host's login page; a firewall cannot tell portal and admin host apart there.

Two ways to restrict it:

  • IP allowlist — it keeps applying in split mode. If you used ip_allowlist before, the assistant keeps the list and says so in the last step; if it would lock you out, it asks first. Afterwards you edit it under Admin → Login & Security → Admin Access → "Allowed IPs for the admin host (optional)". Empty means: no restriction by address.

    Up to v1.9.452 a stored list was silently ignored in split mode. So that an old list (e.g. with long-changed connection addresses) locks nobody out after the update, the update to v1.9.453 cleared such a list once on instances that had already switched. If you want to restrict by address in split mode, enter the list again. - Own port instead of a subdomain — then the admin port can be closed by a firewall.

Login, 2FA and step-up apply in every case.

The three setup profiles

Profile How the assistant recognises it Automated What you do
Stack nginx terminates TLS itself (default) port 443 presents the stack certificate everything up to the switch a certificate that also covers the admin name (easiest via Admin → System → Certificate; step 4 links there and alternatively shows the certbot path) — without it the browser merely warns
Reverse proxy in front (nginx, Caddy, Traefik …) port 443 presents a different certificate than the stack the whole stack part create the proxy vhost for the admin name — step 4 provides the nginx script with the correct stack port; translate for Caddy/Traefik
No Compose no Compose stack nothing run a second API process with VESANA_API_MODE=admin yourself

If detection is wrong, you can override the profile in step 1.

Going back

  • Before the switch: card "Dedicated admin container" in the Access tab → Cancel build.
  • Within the window: Revert switch — also possible from the user portal.
  • Afterwards: Deactivate — only via the admin host. A confirmed split cannot be lifted from the user portal; that is the protection.
  • Via the mode cards: choosing "Unrestricted" or "IP allowlist" and Save tears an active split down just as completely; the target mode is the chosen card. A mere build is cleaned up as well.
  • Emergency: docker compose exec api python -m api.app.cli.admin_recovery reset-mode unrestricted in the Vesana directory resets the mode immediately; then use Deactivate in the Access tab so the containers are torn down as well.

What runs on which host

After the switch both addresses serve the same instance, but not the same functions:

User portal Admin host
Devices, checks, alerting, maps, reports yes yes
Creating, renaming, copying, deleting tenants yes (with the required permissions) yes
Users, roles, updates, everything under /admin no — the notice links into the admin portal yes

If the user portal calls a pure administration route, Vesana answers with a clear message and code instead of "Method not allowed" (up to v1.9.447 that was exactly the error when creating a tenant).

The way back is offered in two places in the admin portal: the admin login page links to the normal user login, and the sidebar offers "Back to the user portal" next to "Log out".

Agent and collector install commands in the user portal again carry the gateway address and certificate fingerprint in split mode; portal layout, license notices and discovery defaults apply there as well.

Notes

  • Cookie domain: the assistant suggests the narrowest common domain (admin.app.example.com under app.example.com ⇒ app.example.com) so the login applies to both addresses without being shared with other services in the same zone. Leave it empty to log in again on the admin host.
  • Separate port instead of subdomain: browsers do not isolate cookies by port — the admin area is then protected by the permission check only, not by the browser origin. For instances reachable by IP only it is nevertheless the only option.

Further reading

  • Permissions: Roles & permissions — how the fine-grained audit_log.view_* / trash.view_* levels interact with the access modes.
  • 2FA: 2FA — an additional protection layer at the individual-user level rather than the whole admin area.