⟩ Documentation
Vigilus documentation
Install, configure, and run Vigilus in your homelab.
Introduction
Vigilus is a self-hosted AI ops platform for homelabs. You get a web dashboard, a conversational orchestrator, agents you define (Operators), and an MCP server manager in one deployable service.
It runs on your hardware, uses your LLM keys or local models, and stays inside permission boundaries you set. Everything is logged. Nothing runs outside your rules.
It is for people who run their own infrastructure and want AI help without shipping data to a third party or handing control to a cloud service.
The mental model
Think of it as a four-layer stack:
- Orchestrator: the top-level router that takes your requests and sends them to the right Operator.
- Operators: sub-agents you define, each with its own prompt, model, tools, and permission level.
- Tools: the actions an Operator can take (SSH, Docker, filesystem, and more), usually from MCP servers.
- RBAC & audit: every tool call goes through the policy engine and lands in an append-only log.
Key features
- Self-hosted on bare metal or Docker as a single service.
- Bring your own models: Anthropic, OpenAI, Google, Ollama, LM Studio, vLLM, OpenRouter, xAI, or any OpenAI-compatible endpoint.
- User-defined Operators from the dashboard. No YAML, no CLI flag soup.
- MCP-native tool discovery from servers on the host.
- Just-In-Time (JIT) elevation with scoped, time-limited, signed tokens for write and exec actions.
- Append-only audit log with secret redaction.
- Interactive API docs at
/docs(Swagger) and/redoc.
Quickstart
Prerequisites
- A Linux host (bare metal or VM) with Docker, or Python 3.11+ for bare-metal installs.
- An LLM API key from at least one supported provider.
Docker (recommended)
$ docker run -d \
--name vigilus \
-p 8000:8000 \
-e VIGILUS_SECRET="$(openssl rand -hex 32)" \
-v vigilus-data:/app/data \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
ghcr.io/vigilus-labs/vigilus:latest Bare metal
Clone the repo and run the startup script:
$ git clone https://github.com/vigilus-labs/vigilus.git
$ cd vigilus
$ ./start.sh
The script creates a Python virtual environment, installs dependencies, and starts the FastAPI backend (which also serves the built React frontend). The app binds to 0.0.0.0:8000 by default.
First-run checklist
- Open
http://localhost:8000in your browser. - Set a secret. The dashboard asks for
VIGILUS_SECRETon first launch. This key encrypts stored credentials. Keep it stable. If it changes, existing API keys and SSH credentials cannot be decrypted. - Add a provider. Go to Settings → Providers and add an LLM provider (for example Anthropic with your API key).
- Add a server. Go to Servers and add an SSH host to manage.
- Talk to Vigilus. Open the chat and ask it to check your infrastructure.
Configuration
Vigilus is configured mainly through environment variables. The important one is VIGILUS_SECRET. Do not change it after first run, or you lose access to encrypted credentials.
| Variable | Default | Description |
|---|---|---|
VIGILUS_SECRET | required | Encryption key for all stored secrets (API keys, SSH credentials). Must remain stable across restarts. |
VIGILUS_DATA_DIR | ~/.vigilus | Directory for the SQLite database, logs, and MCP config. Mapped to /app/data in Docker. |
VIGILUS_HOST | 0.0.0.0 | Bind address for the HTTP server. |
VIGILUS_PORT | 8000 | Bind port. |
VIGILUS_DATABASE_URL | SQLite | SQLAlchemy async connection string. Use a PostgreSQL URL for production-like setups (e.g. postgresql+asyncpg://user:pass@host/vigilus). |
VIGILUS_CORS_ORIGINS | same-origin | Comma-separated list of allowed CORS origins. Lock this down in production. |
SQLite vs PostgreSQL
SQLite is the default and fine for single-user homelab use. The database file lives in your data directory. For setups with concurrent writes or if you want WAL-mode resilience, switch to PostgreSQL by setting VIGILUS_DATABASE_URL.
Database migrations run automatically via Alembic on startup. No manual migration steps.
Core concepts
Orchestrator
The orchestrator is the routing agent. When you send a chat message, it picks the Operator best suited for the task and dispatches it. You do not pick the Operator by hand. The orchestrator reads each Operator's system prompt and tool assignments and routes from that.
The orchestrator itself is not configurable. It is the fixed top layer. You shape behavior by defining Operators and their capabilities.
Operators
An Operator is a sub-agent you define. Each one has:
- System prompt: instructions for behavior, scope, and tone.
- Model: which LLM to use from any configured provider, local or cloud.
- Tools: which MCP server tools it can call.
- Permission level: the maximum privilege ceiling for its tool calls.
Configure Operators from the web dashboard. No YAML files, no CLI flag salad. You might run one Operator for infrastructure monitoring, another for security scanning, and another for patch management, each with different models and permission levels.
Tools
Tools are the actions an Operator can take: SSH commands, Docker management, file operations, network scans, and more. They come from two places:
- MCP servers: external tool servers on the host, auto-discovered by Vigilus.
- Native tools: built-ins shipped with Vigilus (SSH exec, Docker management, and similar).
You assign tools to Operators in the dashboard. An Operator can only use tools you give it.
Memory & Soul
Each Operator keeps conversational memory inside a chat session. Its "soul" (the system prompt) is always prepended to context so behavior stays consistent.
Permission levels & RBAC
Every tool call is classified by intent and checked against the Operator's permission level. Those levels are hard ceilings. An Operator cannot exceed what you assigned.
- Read: always available. Logs, status, metrics, queries. No elevation required.
- Write: modifies state. Requires JIT elevation.
- Exec: runs commands. Requires JIT elevation.
- Elevate: grants elevated access. Requires JIT elevation.
Write, Exec, and Elevate actions go through the JIT system. They never run silently without the policy engine.
JIT & trust modes
JIT (Just-In-Time) elevation is the only way past read-only permissions. When an Operator needs to write or exec, it requests a JIT token scoped to a specific resource and action, time-limited, and HMAC-signed.
You choose the trust mode per Operator or globally:
- Strict: every elevation request waits in the dashboard for your approval. Nothing runs without you. Approve or deny each request.
- Lenient: elevation requests are auto-approved and logged. Review them later in the audit log.
JIT tokens are short-lived (configurable TTL), revocable, and resource-scoped. A token for restarting a Docker container cannot be used to SSH into a server.
MCP servers
Vigilus is MCP-native. MCP (Model Context Protocol) servers run on the host and expose tools that Vigilus auto-discovers. Once discovered, you assign those tools to Operators in the dashboard.
Common MCP servers include:
- nmap: network scanning and discovery
- WireGuard: VPN tunnel management
- filesystem: host file read/write
- Wazuh: SIEM integration (alerts, logs, vulnerabilities)
- Docker: container and compose stack management
Install an MCP server on the host, restart Vigilus, and its tools show up for assignment.
Providers
Vigilus supports any provider that speaks the OpenAI API format, plus native integrations for Anthropic, OpenAI, Google, Ollama, LM Studio, vLLM, OpenRouter, and xAI. Configure providers in the dashboard with an API key and endpoint URL.
You can mix them. Use a local Ollama model for routine checks and a cloud model for harder reasoning. Each Operator can use a different model from a different provider.
Servers & credentials
Vigilus talks to your infrastructure over SSH and Docker. Manage server inventory, SSH credentials, and connection details from the dashboard. Credentials are encrypted at rest with AES via Fernet.
Scheduled tasks
Schedule recurring work with cron expressions. Vigilus uses APScheduler for things like nightly security scans, weekly patch checks, or hourly health probes. Create scheduled tasks from the dashboard. They follow the same RBAC and JIT rules as interactive tasks.
Audit log
Every tool call, allowed or denied, is recorded in an append-only audit log. No opt-in, no extra config. Secrets are redacted before logging. The audit log is the record of what happened, when, and why.
Guides
Connect your first server
- Generate an SSH key pair on the Vigilus host (if you don't already have one):
$ ssh-keygen -t ed25519 -f ~/.ssh/vigilus_key -N "" - Add the public key to the target server's
authorized_keys:$ ssh-copy-id -i ~/.ssh/vigilus_key.pub user@your-serverThe key must be in
~/.ssh/authorized_keyson the target server, and the file must have correct permissions (600for the file,700for~/.ssh/). - Add the server in Vigilus. Go to Servers → Add Server. Enter the hostname, port, username, and paste the private key. Vigilus stores it encrypted.
- First connection. Vigilus uses trust-on-first-use (TOFU) for host keys. On the first SSH connection, the server's host key is pinned. If that key changes later, future connections fail. That is intentional and helps block MITM attacks.
Add an LLM provider
- Go to Settings → Providers → Add Provider.
- Select the provider type (e.g., Anthropic, OpenAI, Ollama).
- Enter your API key and (if applicable) a custom endpoint URL.
- Save. The provider is now available for Operators.
For local providers like Ollama or LM Studio, use the base URL (e.g., http://localhost:11434). No API key is required for most local providers.
Create an operator
- Go to Operators → Create Operator.
- Give it a name and a system prompt describing its purpose (e.g., "Monitor all infrastructure servers and report anomalies").
- Select a model from a configured provider.
- Assign tools from your MCP servers and native tool set.
- Set the permission level (read-only, read-write with JIT, etc.).
- Choose a JIT trust mode (strict or lenient).
- Save. The Operator is now available for the orchestrator to route tasks to.
Add an MCP server
You can add MCP servers in three ways:
- npm package: provide the package name (for example
@vigilus/mcp-nmap). Vigilus installs and runs it. - Command: provide a shell command that starts the MCP server. Useful for custom or local servers.
- GitHub + JSON import: paste a GitHub repo URL or a JSON config block. Vigilus pulls and configures the server.
After adding an MCP server, restart Vigilus (or click "Rescan" in the dashboard). New tools from the server appear in the tool assignment panel.
Schedule a task
- Go to Scheduled Tasks → Create Task.
- Select an Operator to handle the task.
- Write the prompt (e.g., "Check disk usage on all servers and report any above 85%").
- Set a cron expression for the schedule (e.g.,
0 2 * * *for 2 AM daily). - Save. The task runs on schedule, subject to the same permissions and JIT rules as interactive tasks.
Use the chat
The chat is your primary interface to Vigilus. Type a natural-language request and the orchestrator routes it to the appropriate Operator.
- Markdown: responses render as Markdown, including code blocks, tables, and lists.
- @mentions: prefix a message with
@operator-nameto route it to a specific Operator instead of letting the orchestrator choose. - Stopping tasks: use the Stop button to cancel a running task. You can also manage running tasks from the running-tasks panel.
- Restoring tasks: cancelled or completed tasks can be inspected and re-run from task history.
Reference
Native tools catalog
| Tool | Required permission | Description |
|---|---|---|
ssh.exec | Exec | Execute a command on a remote server via SSH. |
docker.list | Read | List containers on a Docker host. |
docker.restart | Write | Restart a Docker container. |
docker.logs | Read | Fetch logs from a Docker container. |
docker.compose | Write | Manage Docker Compose stacks (up, down, pull). |
filesystem.read | Read | Read a file from the Operator's working directory on the host. |
filesystem.write | Write | Write a file to the Operator's working directory on the host. |
shell.exec | Exec | Run a shell command on the Vigilus host, confined to the Operator's working directory. |
nmap.scan | Exec | Run a network scan against a target range (via MCP nmap server). |
wazuh.query | Read | Query Wazuh SIEM for alerts, logs, or vulnerability data. |
Permission levels
| Level | Description | JIT required? |
|---|---|---|
| Read | Query state, read logs, list resources. | No |
| Write | Modify state: restart containers, write files, update configs. | Yes |
| Exec | Execute commands: SSH, shell, network scans. | Yes |
| Elevate | Grant elevated access beyond the current scope. | Yes |
Supported providers
- Anthropic (Claude)
- OpenAI (GPT-4, GPT-4o, etc.)
- Google (Gemini)
- Ollama (local models)
- LM Studio (local models)
- vLLM (local models)
- OpenRouter (multi-provider gateway)
- xAI (Grok)
- Any OpenAI-compatible endpoint
Interactive API docs
Vigilus auto-generates an interactive API reference from the FastAPI schema. Access it at:
http://localhost:8000/docs: Swagger UI (try endpoints live)http://localhost:8000/redoc: ReDoc (readable reference)
Security
Vigilus is built to keep trust low and visibility high. Here is how each layer is protected:
| Layer | Mechanism |
|---|---|
| Secrets at rest | All stored credentials (API keys, SSH private keys) are encrypted with AES via Fernet. The encryption key is VIGILUS_SECRET. Keep it stable and keep it safe. |
| RBAC policy engine | Every tool call passes through the RBAC policy engine. Permission levels are hard ceilings. No Operator can exceed its assigned level. JIT is the only elevation path. |
| Audit log | Append-only log of every tool call (allowed and denied). Secrets are redacted before logging. No opt-out. |
| JIT tokens | HMAC-signed, short-lived (configurable TTL), revocable, and resource-scoped. A token for one action on one resource cannot be reused for another. |
| SSH host keys | Trust-on-first-use (TOFU). Host keys are pinned on the first connection. If a host's key changes, connections fail. This prevents man-in-the-middle attacks. |
| Host filesystem / shell | Host tools are confined to the Operator's working directory. Symlink- and traversal-safe. Operators cannot break out of their assigned directory. |
| CORS | Locked to configured origins via VIGILUS_CORS_ORIGINS. Default is same-origin only. |
Troubleshooting / FAQ
"SSH authentication failed"
Check the following:
- The SSH public key is in the target server's
~/.ssh/authorized_keys. - File permissions are correct:
700 ~/.ssh/and600 ~/.ssh/authorized_keys. - The private key you entered in Vigilus matches the public key on the target.
- The target server's SSH daemon is running and allows key-based auth.
"Host key verification failed"
This means the target server's SSH host key has changed since the first connection (Vigilus uses trust-on-first-use). If this is expected (e.g., you reinstalled the OS), remove the old host key from Vigilus's known hosts and reconnect. If it's unexpected, investigate potential MITM interference before proceeding.
"Stored API key can't be decrypted"
This happens when VIGILUS_SECRET has changed since the credential was stored. The encryption is one-way. You cannot recover the old key. Re-enter the API key in provider settings with the current secret.
"A task is running away"
Use the chat Stop button to cancel the task immediately. You can also open the running-tasks panel from the dashboard to view and cancel active tasks.
"MCP server tools aren't appearing"
- Make sure the MCP server process is running on the host.
- Click "Rescan" in the MCP servers section of the dashboard, or restart Vigilus.
- Check that the server's command/path is correct and executable.