Administration Guide

This guide is a reference for everything an operator does from /admin on the appliance. It does not cover analyst workflows — see the User Guide for those.

Manage License

The Manage License page is where the appliance moves from the open-core baseline (single admin, plain vault directory) to the licensed feature set (multi-user, groups, modules, ITSM, encrypted vaults, event log).

The page has two sections:

  1. Request a License — clicking Generate License Request reads this host's fingerprint (a set of hardware identifiers — machine-id, DMI system UUID, board and system serial — captured and encrypted at install time) and encodes the derived tokens into a short copy-pasteable key (prefixed SOSV1.). Copy the key and paste it at sos-vault.com under Verify License Request to purchase a license bound exclusively to this server. No file is generated and no sosreport is run — the key carries only this server's hardware fingerprint, so it is safe to share.
  2. Install License — once you have a signed .lic, upload it here. The signature is verified against the appliance's local public keyring, machine tokens are matched, and the license is persisted.

The installed-license card displays:

  • UUID and customer id
  • Status (ACTIVE / EXPIRED / REVOKED)
  • Seats used / total
  • Granted features
  • Issued at, expires at, and an "expiring soon" indicator

Multiple uploads keep a history. LocalLicense::current() returns the most recent ACTIVE license whose expiry is still in the future. When the license expires, the appliance reverts to the open-core baseline; existing extra users and groups are preserved in the database but cannot sign in until the license is renewed.

Disk Manager

Shows a single "Vault Directory" text input on every appliance install — licensed or not. The value is persisted to appliance.vault_dir in the settings table and used by sos-vault:ensure-plain-vault on next boot. Default is /vault.

sos-vault stores its vaults in this plain directory — no ZFS is required. The directory can live on the system disk, a dedicated mount, or a network share (NFS/CIFS) mounted by the operating system at the configured path. To point sos-vault at network storage, mount the share at /vault (or your chosen path) using /etc/fstab or your usual mount tooling, then set that path here.

Certificate Manager

Replaces the self-signed cert generated by the installer, and installs corporate root CAs into the host trust store.

  • Replace Server Certificate: upload fullchain.pem and privkey.pem. The helper validates with openssl x509 -noout / openssl pkey -noout before clobbering live files, then reloads nginx in the container.
  • Corporate Root CA: drops the uploaded PEM into /usr/local/share/ca-certificates/ and runs update-ca-certificates.
  • Uploaded PEM contents are staged to fixed /tmp/sosvault-cert-*.pem files and unlinked in a finally{} block — cert material never persists to disk beyond the staging path.

Outbound proxy (private networks)

The appliance needs no internet access for day-to-day work: the web UI and the command-line sosreport upload are LAN-local (inbound to the appliance), and extraction, vaults, search, licensing (offline signature verification) and 2FA (offline TOTP) all work air-gapped. A proxy only matters for the appliance's outbound calls, which happen only when an integration reaches the internet.

WhatUses HTTPS_PROXY?
Jira/ITSM, Telegram, remote AI (OpenAI)Yes — HTTPS via the HTTP client
SMTP mailNo — SMTP is a separate TCP connection, not HTTP. Use an internal/LAN relay or a smarthost
Docker image pulls / upgrades (ghcr.io)Configured on the host docker daemon, not here (a systemd drop-in under docker.service.d/)

Edit /opt/sos-vault/.env (the installer leaves a commented block at the bottom):

HTTPS_PROXY=http://proxy.example.com:3128
NO_PROXY=localhost,127.0.0.1,172.16.0.0/12,<appliance-host>,<internal-jira-host>,<mail-host>
  • Use HTTPS_PROXY, not HTTP_PROXY. In the web (php-fpm) context the HTTP client ignores HTTP_PROXY by design (httpoxy mitigation); since the integrations are all HTTPS, HTTPS_PROXY is what takes effect.
  • Keep LAN/internal hosts in NO_PROXY so the appliance, the docker network, and internal Jira/mail endpoints are not bounced through the proxy.
  • Restart after changing it: sudo systemctl restart sos-vault — the running PHP/queue/scheduler processes only re-read .env on restart.
  • If the proxy does TLS interception, upload its root CA via Certificate Manager → Corporate Root CA — otherwise outbound HTTPS fails certificate validation. (For docker image pulls the CA must also be in the host trust store.)

Manage Settings

The sections shown depend on license state.

Always visible on appliance:

  • Mail — SMTP for license-expiry reminders, password resets, and notifications. Visible even on the open-core baseline so the single admin can recover their password.

Visible only with an active license:

  • Authentication — sign-in providers, password rules
  • AI Assistant — bot model + system prompt
  • Appliance Vaults — default size for newly-provisioned group vaults
  • ServiceNow / ITSM — integration credentials

SaaS-only sections (Site, Logging, Social Auth, Analytics, Captcha, Billing, Telegram, AWS/S3, AI provider config, Self-Hosted Bundle, Licensing Key) are intentionally hidden on every appliance install regardless of license.

Two-factor authentication (2FA)

sos-vault ships offline TOTP two-factor authentication — it works air-gapped (no SMS, no third-party service).

  • Mandatory for admins. On first sign-in an administrator is redirected to Settings → Security to enrol with an authenticator app (Google Authenticator, Authy, 1Password, etc.). 2FA is optional for non-admin users, who can enable it on the same page.
  • Operator escape hatch. The mandatory-for-admins rule is gated by the auth.two_factor_required_for_admins setting (default on). Turning it off makes 2FA optional for everyone.
  • Break-glass (locked-out admin) — e.g. a lost device or clock drift on a box with no NTP. From a shell on the host, disable 2FA for one account so they can sign in and re-enrol:
    docker compose exec -T <app-container> \
      sudo -u www-data php artisan 2fa:disable <email|username|id>
  • Secrets and recovery codes are encrypted at rest. The authenticator entry is labelled per environment (sos-vault-self-hosted on the appliance) so several sos-vault instances can coexist in one app.

Users, roles, and teams

  • Users: on the open-core baseline (no license) the appliance allows exactly ONE user — the admin planted by ApplianceAdminSeeder. The Create User action is hidden and User::creating() refuses additional rows. Once a license is installed, new users can be created up to the seat cap; over-cap creation is refused with a Filament notification.
  • Roles: admin, Team Member, etc. from the shipped RolesTableSeeder. Assign per user.
  • Groups (teams): hidden entirely on the open-core baseline. Once a license is installed, the Groups CRUD reappears; each team owns a LUKS-encrypted vault provisioned inside the /vault directory.

Capture a server report for support

From a shell on the host:

docker compose exec -T <app-container> \
  sudo -u www-data php artisan sos-vault:capture-server-report

The command runs sosreport, GPG-encrypts the resulting tarball to the sos-vault support recipient, and drops the encrypted blob at storage/app/private/server-report.tar.xz.gpg. Attach that file to your support ticket. The unencrypted intermediate is unlinked on every code path.

Dashboard widgets

The admin dashboard on appliance shows an extra widget that does not appear on the SaaS build:

  • Appliance License: status + UUID, seats used/total, team count, days-to-expiry.