Secure Voice-to-CLI Network Agent for ExtremeXOS switches. Accepts Speech-to-Text (STT) input, returns Text-to-Speech (TTS) responses, with strict RBAC, approvals, and read-back confirmation.
- Allowlist-only command execution — Only commands from
data/exos_commands.jsonare permitted - Strict parameter validation — Fail-closed validation for ports, VLANs, IPs, descriptions
- RBAC + school scoping — Roles (viewer, operator, engineer, enterprise_admin) and per-school access
- Read-back + confirmation — Two-step flow:
/planreturns readback text,/executerequires confirmation - Credential security — Credentials never exposed to LLM; stored encrypted (Fernet); JIT decrypt at execution
- Universal LLM — Ollama (local), OpenAI, or OpenAI-compatible providers
pip install -r requirements.txtpython scripts/init_db.py
python scripts/demo_seed.py
python scripts/generate_key.py # Create Fernet key for credential encryptionCopy .env.example to .env and set:
LLM_PROVIDER—ollama|openai|openai_compatibleLLM_MODEL— Model nameLLM_BASE_URL— For ollama (e.g.http://localhost:11434) or openai_compatibleLLM_API_KEY— For OpenAI / openai_compatibleHMAC_SECRET— Generate with:python -c "import secrets; print(secrets.token_hex(32))"DEMO_MODE=1— Mock SSH execution for testing
python run.py
# or: uvicorn exos_agent.app.main:app --host 0.0.0.0 --port 8000- STT — User speaks: "Add vlan 99 to Thomas Jefferson Elementary switch JP9 port 18"
- Plan — POST
/planwithstt_text,device_selector,voice_session_id - Readback — Agent returns
tts_response_textandapproval_token - TTS — Client speaks the readback to user
- Confirm — User says "confirm"
- Execute — POST
/executewithapproval_token,confirm_text, and optionally credentials
For highest-approval changes: enterprise_admin calls /approve first, then /execute includes approver_token.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /health | No | Health check |
| GET | /commands | Yes | List allowlisted commands |
| GET | /devices | Yes | List devices (school-scoped) |
| POST | /devices | enterprise_admin | Add device |
| POST | /devices/{id}/credentials | enterprise_admin | Store encrypted creds |
| POST | /plan | Yes | Plan command, mint approval token |
| POST | /approve | enterprise_admin | Approve highest-level change |
| POST | /execute | Yes | Execute with approval token |
All authenticated endpoints require X-Api-Key header.
# Health
curl http://localhost:8000/health
# Plan (use API key from config/rbac.json)
curl -X POST http://localhost:8000/plan \
-H "X-Api-Key: operator-tj-key-67890" \
-H "Content-Type: application/json" \
-d '{
"user_id": "op1",
"voice_session_id": "sess-1",
"device_selector": {"device_name": "JP9", "school_name": "Thomas Jefferson Elementary"},
"stt_text": "Add vlan 99 to port 18"
}'
# Execute (use approval_token from plan response)
curl -X POST http://localhost:8000/execute \
-H "X-Api-Key: operator-tj-key-67890" \
-H "Content-Type: application/json" \
-d '{
"approval_token": "<from_plan>",
"confirm_text": "confirm",
"credentials": {"username": "admin", "password": "secret", "store_creds": false}
}'- TLS — Run behind a reverse proxy (nginx, Caddy) with HTTPS
- Network — Internal network or VPN only; firewall allowlist
- Rate limiting — Enable at reverse proxy
- Key rotation — Run
scripts/generate_key.pyto add new Fernet key;creds_key_idsupports multiple keys - Host key pinning — Set
TOFU_ALLOW=1to learn SSH host keys on first connect; then disable for strict pinning
pytest tests/ -vexos_agent/
app/ - FastAPI app, API, planner, executor, validators, policy, rbac, audit
core/ - db, crypto, security, command_library, ssh_trust, llm providers
data/ - exos_commands.json (allowlist)
config/ - rbac.json, keys.json
scripts/ - init_db, demo_seed, generate_key
tests/ - Unit tests