A full-stack prototype for managing local VirtualBox virtual machines through a web UI and validated natural-language commands. The backend is FastAPI; the frontend is Next.js; Supabase supplies authentication and application data.
Status: development prototype for a single VirtualBox host. A running deployment needs your own Supabase project, Groq key, and VirtualBox host. No production availability or autonomous agent behavior is claimed.
flowchart LR
U[User] --> W[Next.js portal]
W -->|Login and JWT + REST| F[FastAPI routes]
F -->|Sign in and JWKS discovery| S[(Supabase Auth)]
F --> DB[(Supabase data)]
F --> AI[AI command service]
AI -->|JSON action| V[Pydantic validation]
V --> VM[VM service]
VM --> CLI[VBoxManage wrapper]
CLI --> H[Local VirtualBox host]
AI --> G[Groq API]
F --> SCH[Scheduler]
SCH --> VM
The language model interprets a request as a structured action. The backend validates the action and runs the corresponding service method; the model does not execute shell commands. The VM service and wrapper enforce the application rules before calling VBoxManage.
sequenceDiagram
actor User
participant UI as Next.js portal
participant API as FastAPI
participant AI as AI service
participant VM as VM service
participant VBox as VBoxManage
User->>UI: "Start my Ubuntu VM"
UI->>API: POST /api/v1/ai/command + JWT
API->>AI: Interpret request with VM context
AI->>VM: Validated start_vm action
VM->>VBox: startvm with resolved VM ID
VBox-->>VM: Exit status
VM-->>API: Result
API-->>UI: Structured response
| Path | Purpose |
|---|---|
backend/app/routes |
HTTP endpoints and auth dependencies |
backend/app/services |
AI interpretation, VM operations, scheduling, analytics |
backend/app/models |
Pydantic command and response schemas |
backend/tests |
Unit and integration tests |
frontend/app |
Next.js pages for login, VMs, AI, logs, and analytics |
supabase/migrations |
Database schema migrations |
docs/implementation-plan.md |
Historical design plan; consult the code for current behavior |
- Install Python, Node.js, and VirtualBox. Create a Supabase project and apply the SQL files in
supabase/migrationsin numeric order. Obtain a Groq API key. - Use a Supabase secret API key for
SUPABASE_SECRET_KEYon the backend and a publishable API key forNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYon the frontend. Copybackend/.env.exampletobackend/.envandfrontend/.env.exampletofrontend/.env.local; replace placeholders locally. Keep both populated files out of Git. For Docker Compose, also copy.env.exampleto.envat the repository root and set the public Supabase URL and publishable key there; Next.js embedsNEXT_PUBLIC_values when the image is built, so rebuild the frontend after changing them. - Start the backend and frontend in separate terminals:
cd backend
python -m venv .venv
# Activate the environment for your shell.
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8001cd frontend
npm ci
npm run devOpen http://localhost:3000. The backend health endpoint is http://localhost:8001/api/v1/health; it reports whether VBoxManage is found. Docker Compose maps the backend container's port 8000 to host port 8001; access to a host VirtualBox installation requires host-specific configuration.
The frontend checks nexvm_token against backend /api/v1/auth/me before serving protected routes. Admin access uses the backend's is_admin response, not a browser cookie. Set BACKEND_INTERNAL_URL if the frontend server cannot reach NEXT_PUBLIC_API_URL (Docker Compose uses http://backend:8000). Restart or redeploy the frontend after changing environment variables or authentication code.
cd backend
pip install -r dev-requirements.txt
pytest -q -m "not integration"Integration tests require a real VirtualBox setup and are marked separately. The frontend can be checked with npx tsc --noEmit from frontend/.
- A short screen recording or screenshots from a configured, non-sensitive demo environment.
- A command evaluation set reporting action accuracy and ambiguous-request behavior.
- A verified deployment diagram and setup guide for one supported host configuration.
Do not put real API keys or service-role credentials in example files, screenshots, or issue reports.
- ISO and OVA folders. Users can only attach ISOs from
ISO_DIR(default:isosinside the VM storage folder). Export and import take a file name such asmy-vm.ova; each user's files live inEXPORT_DIR/<user id>/(defaultexports). Both folders are created at startup; set them inbackend/.envif you prefer other locations. - VirtualBox names. New VMs are registered as
<name>-<8 hex chars>and addressed by UUID, so two users can use the same VM name. Existing VMs keep their names. - No default SSH forward. New VMs no longer forward host port 2222; add a rule under Port forwarding when needed.
- AI deletions now ask for confirmation in the chat.
An earlier public revision of backend/.env.example contained values resembling a Supabase legacy service-role key and a Groq API key. Replacing that file does not revoke those values or erase copies of the Git history.
- In the Supabase dashboard, create a new server secret key and deploy it as
SUPABASE_SECRET_KEY. Configure and verify the frontend withNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, then check any other callers before deactivating the legacyanonandservice_rolekeys together in Settings > API Keys. - The leaked legacy
service_rolekey is also a JWT signed by the legacy JWT secret. The NexVM project now uses an asymmetric signing key, and the legacy signing key is revoked. The backend accepts only asymmetric JWTs through Supabase JWKS. RemoveSUPABASE_JWT_SECRETfrom every deployed backend environment before restarting it. - In the Groq Console, revoke the exposed key, create a replacement, and update
GROQ_API_KEYin the backend environment. Review recent usage for unexpected requests.
The old JWT-secret value in the example looked like placeholder text; rotate your actual signing secret if that value was reused. Follow the current Supabase key migration guide, Supabase signing-key guide, and Groq security guide for the dashboard steps.