Skip to content
MagicFrog

Admin Console

Manage computers, enrollments, plugins, runs, forms, and the audit log.

The admin console is a standalone management surface for a MagicFrog control plane. It lives at /admin on the console web deployment and shares nothing with the workspace: it has its own login gate, its own session storage, and its own admission check. Signing in to the desktop or web workspace never grants access to the admin console.


Access model

Admission is based on the account's explicit role. Accounts carry a role field with a closed set of values: owner or member. Only owner accounts may use the admin console — there is no grant, invite, or escalation path that turns a member into an owner from inside the product, and the first account to register on a deployment does not become an owner implicitly. The owner account is created by the deployment itself at first boot (see Self-hosting).

Enforcement is server-side. Every /v1/admin/* endpoint resolves the caller's identity and requires the owner role at a single centralized guard; a non-owner request fails with 403 regardless of what the UI sends. The console's own checks are presentation only.


The login gate

The /admin entry presents one of four states, derived from the admin session alone:

State When What you see
login No admin session The admin sign-in form
change-password The account still uses its initial deployment password A forced password-change form; the session is held in memory only until the change succeeds
forbidden Signed in, but the role is not owner (or the session payload is malformed) An explicit no-access screen — never a silent downgrade
ready Signed in as an owner with no pending password change The admin shell with the six resource faces

The admin session is stored under its own browser storage key, separate from the account session used by the workspace. A tampered or stale session payload is discarded and treated as signed out.

While the forced password change is pending, the server rejects every business endpoint except login and password change with 403 password_change_required — this applies to any account in that state, not only owners.


Managed resources

The admin shell has six faces. /admin redirects to the first one.

Face What it shows Actions
Computers Name, type, source (provisioned / enrolled), status Create a provisioned computer on behalf of an account (account ID, OS linux/windows, name, CPU cores, memory, optional image); start and stop provisioned computers; destroy provisioned computers; revoke enrolled machines
Enrollments Account, device, computer, name, state, egress authorization Revoke an enrollment; grant or revoke the egress grant
Plugins Kind, state, source Install (source plus kind directory/url/registry), enable, disable, update, uninstall
Runs Runtime owner, location, target computer, egress, terminal state Cancel a run
Forms Session, state, creation time Expire a form
Audit log Actor, action, resource, time, summary Read-only, cursor-paginated (50 entries per page), filterable by resource type

The egress grant on an enrollment is written as a unit: granting requires the protocol (socks5 or http), the local port, and the remote port together — an incomplete grant is rejected by the server. Revoking takes the authorization away.


Destroy and revoke are different operations

Destroying a computer and revoking one are two separate actions with separate confirmations, and they never share an endpoint or a copy:

  • Destroy applies to provisioned computers only — machines created through a provider. It destroys the provider-managed machine.
  • Revoke applies to enrolled machines only — real computers registered through the CLI. It withdraws the enrollment and the machine's access; the machine itself, its data, and its running state are untouched. Revoking an enrollment does not shut the machine down or wipe it.

The UI scopes each action to the rows it applies to, and the server rejects the mismatch independently: a destroy against an enrolled machine, or a revoke against a provisioned one, fails.


Audit log

Every admin change writes an audit record with the operator account, the target resource, and the time, committed in the same transaction as the change itself. There is no admin action that bypasses the audit trail. The audit face queries these records with cursor pagination and an optional filter by target resource type (computer, enrollment, plugin, run, or form).


HTTP API

All endpoints below require an authenticated owner session; any other caller gets 403. The admin face authenticates through the regular account endpoints (POST /v1/account/login, POST /v1/account/change-password, POST /v1/account/logout) and then calls the /v1/admin/* surface.

Method Path Purpose
GET /v1/admin/audit-log Query the audit log (cursor, limit, resourceType)
GET /v1/admin/computers List computers
POST /v1/admin/computers Create a provisioned computer for an account
POST /v1/admin/computers/:computerId/start Start a provisioned computer
POST /v1/admin/computers/:computerId/stop Stop a provisioned computer
POST /v1/admin/computers/:computerId/destroy Destroy a provisioned computer
POST /v1/admin/computers/:computerId/revoke Revoke an enrolled machine
GET /v1/admin/enrollments List enrollments
POST /v1/admin/enrollments/:enrollmentId/revoke Revoke an enrollment
PATCH /v1/admin/enrollments/:enrollmentId/egress-grant Grant or revoke the egress grant
POST /v1/admin/plugins Install a plugin
GET /v1/admin/plugins List plugins
POST /v1/admin/plugins/:pluginId/enable Enable a plugin
POST /v1/admin/plugins/:pluginId/disable Disable a plugin
POST /v1/admin/plugins/:pluginId/update Update a plugin
POST /v1/admin/plugins/:pluginId/uninstall Uninstall a plugin
GET /v1/admin/runs List runs
POST /v1/admin/runs/:runId/cancel Cancel a run
GET /v1/admin/forms List forms
POST /v1/admin/forms/:formId/expire Expire a form

Deployment

The admin console is part of the console web deployment. It authenticates against the control plane origin configured at deploy time via VITE_ADMIN_CONTROL_PLANE_URL; when that variable is unset, the login gate reports the missing configuration instead of guessing an origin. If the console is served from a different origin than the control plane, allow the console origin on the server with magicfrog serve --cors <origin>. See Self-hosting for the control plane deployment.