Admin Web UI

Vue admin console served at /admin/.

Admin Web UI

Vue 3 + Vite SPA served by the existing HTTP server at /admin/ (same origin as the JSON API).

Build

cd admin
rm -rf node_modules   # optional; avoids stale installs after new deps (e.g. xterm)
npm ci                # installs from package-lock.json (required on every build host)
npm run build
# → admin/dist/

npm run build refuses to start if package.json dependencies are missing from node_modules (see scripts/check-deps.mjs). Packaging/makepkg always runs a clean npm ci first.

Server config (default already points here):

"adminDistPath": "admin/dist"

Restart lindir-server. Open http://127.0.0.1:1289/admin/ and sign in with the bootstrap token or an API token (ldt_…).

Dev

# terminal 1 — API
dub run --compiler=ldc2 -- --config config.json

# terminal 2 — Vite (proxies /v1 and /health)
cd admin && npm run dev
# → http://127.0.0.1:5173/admin/

Two-level IA: primary sidebar and secondary section tabs.

Primary: Dashboard, Directory, Hosts, Host access, Software, Compliance, Automation, Platform, Audit.

Workflow pages (Create user, Set password, Enroll host) are actions on the Users / Hosts lists, not secondary tabs (routes remain for deep links).

On desktop the sidebar can be resized (drag the edge) or hidden (‹ / Menu); preference is stored in localStorage. Main content uses the full remaining width (tables are not capped at ~64rem).

Legacy paths (/users, /groups, /fleet, /tokens, /oidc, /policy) redirect into this hierarchy. Most page URLs stay under /directory, /hosts, /policy, /fleet, /access — only the menu grouping changed.

Pages

Section / route Capabilities
Login /login Bearer token → sessionStorage only
Dashboard / Needs attention: stale sync, reboot recommended, failed package jobs, recent auth denials, upgradable counts, open vulns; queue reboot; upgradable links open Software → Upgrades (?hostId= for a host)
Directory → Users /directory/users List + enable/disable; Create user / Set password actions
Directory → Create user /directory/users/create Create account (from Users actions)
Directory → Set password /directory/users/password Reset password (from Users actions)
Directory → Groups /directory/groups Create groups; add/remove members; list members
Directory → Passkeys /access/passkeys List/register/revoke WebAuthn passkeys per user
Directory → Account policy /directory/account-policy Min length, complexity, max age, lockout, must-change-on-create
Hosts → Hosts /hosts Hostnames, OS, last seen; Console link; Enroll host / enroll-tokens actions
Hosts → Console /hosts/console Interactive agent PTY (xterm.js ↔ WebSocket); optional ?hostId=; root-equivalent
Hosts → Inventory /fleet/inventory Collected inventory; hostname → host Systemd; per-row links to Systemd / Upgrades / Apt sources / Cron / Timers / Oneshots / Services (?hostId=); upgradable count links to host Upgrades; summary panels; queue reboot if recommended
Hosts → Labels /fleet/labels Host sets; assign/unassign hosts; membership list; sync from HBAC
Hosts → Enroll tokens /hosts/enroll-tokens One-shot len_… tokens + copy join command
Hosts → Enroll host /hosts/enroll Admin-token enroll + copy secret; optional skip VPN (from Hosts actions)
Host access → HBAC /policy/hbac Host-based access rules; dry-run check (groups × host → allowed/denied)
Host access → Sudo /policy/sudo Sudo rules
Host access → SSH keys /policy/ssh-keys Per-user public keys
Software → Packages /fleet/packages Install/remove/upgrade/reboot/update-agent/add-ppa/enable-ppa/disable-ppa/remove-ppa by host or label; apt-source actions pick from reported sources; pending jobs list with cancel; job history (+ ?job= deep link to stdout/stderr)
Software → Upgrades /fleet/upgrades Upgradable packages from apt/dnf/pacman/zypper indexes; optional ?hostId= filter; select packages or Queue upgrade all (full system upgrade)
Software → Apt sources /fleet/apt-sources sources.list.d / Launchpad PPAs from inventory (incl. disabled); Enable / Disable / Remove; optional ?hostId=
Software → Vulnerabilities /fleet/vulns Distro-aware CVE findings (Ubuntu + Arch + OSV for Debian/RHEL/SUSE); scan / refresh / force refresh; background job status
Compliance → Devices /fleet/devices Host posture; lock / retire
Compliance → Policies /fleet/compliance MDM policies (distro, encryption, password); assign/unassign; target list with unassign
Compliance → Scripts /fleet/compliance-scripts Custom discovery scripts
Compliance → Energy /fleet/energy Sleep/screen/lid policies; assign/unassign host/label; target list with unassign
Automation → Cron /fleet/cron User crontabs + /etc/cron.d/lindir-*; add / enable / disable / remove; pending cancel; notes hosts missing user crontab (informational — Inventory omits that note)
Automation → Timers /fleet/timers System + user lindir-*.timer / .service; add / enable / disable / remove; optional linger for user scope
Automation → Oneshots /fleet/oneshots Login (default.target) / boot (multi-user.target) lindir-*.service oneshots; leave linger off for login-only
Automation → Services /fleet/services Always-on Type=simple lindir-*.service (user or system); linger on by default for user scope; restart / enable / disable / remove
Automation → Systemd /fleet/systemd Pick a host (dropdown or list), then browse that host’s unit catalog; queue start/stop/restart/reload/enable/disable/mask/unmask; denylist for critical units; ?hostId= from Inventory
Automation → Queries /fleet/queries Define + queue queries
Automation → Scripts /fleet/scripts Define + queue scripts
Automation → Runs /fleet/runs Query/script run results
Platform → API tokens /access/tokens Create/list/revoke
Platform → OIDC /access/oidc Relying-party clients; optional require compliant device
Platform → VPN /vpn Sync ACLs
Audit /audit Filters; Logins; Host logins; Denials; Export CSV; clickable column sort (default When newest first); expand row for detail + package job stdout/stderr (hostname resolved)

Uses Vue 3 (versioned via npm/package-lock.json) and vue-router 4.

Mobile

Wide tables scroll horizontally inside panels (cells stay in-column). Primary/secondary nav scroll sideways on narrow viewports.

Security notes

  • Long-lived Bearer in sessionStorage is XSS-sensitive — see OWASP Controls A01/A07.
  • Fleet package/script/energy/cron/timer/oneshot/systemd-operate actions are root-equivalent on targeted hosts.
  • Hosts → Console is an interactive root shell via the agent — treat like fleet scripts (OWASP Controls).
  • MDM retire clears enrollment; lock is loginctl lock-sessions — see MDM & Compliance.