Overall risk: High. The LangChain agent runs as root with no command logging or kill switch. Three .env files containing API keys are world-readable in the web root. The server has no firewall and Ollama is exposed to the public internet on port 11434. The first fix to make: move the agent off root and install the kill switch.
| ID | Finding | Severity | Evidence | Status |
|---|---|---|---|---|
| F1 | .env exposure — 3 files world-readable in web root | Critical | stat -c '%a' /var/www/app/.env → 644. Contains OpenAI API key, database password, Stripe secret key. | FIXED |
| F2 | Agent runs as root | Critical | ps -o user= -p $(pgrep -f langchain | head -1) → root. Agent has full system access, can read all .env files, modify system configs, install packages. | FIXED |
| F3 | No firewall active | High | ufw status → inactive. firewalld not installed. iptables -S → default ACCEPT all. | FIXED |
| F4 | Ollama on 0.0.0.0:11434 | High | ss -tlnH | grep 11434 → 0.0.0.0:11434. Anyone on the internet can query the local LLM, see model names, and send inference requests. | FIXED |
| F5 | No command logging | High | No aiguard log, no auditd exec rules, no shell history for the agent user. Zero record of what commands the agent has run. | FIXED |
| F6 | No kill switch | Medium | No aiguard wrapper, no KILL file, no systemd watchdog. Only way to stop the agent is kill or systemctl stop, which requires knowing the PID. | FIXED |
| F7 | Backup exists but never restore-tested | Medium | Cron job runs restic backup nightly. /etc/aiguard.restore-tested does not exist. Last backup: 2026-09-14 (confirmed present). | OPEN |
| F8 | SSH PasswordAuthentication not explicitly set | Low | sshd -T | grep password → not in output. OpenSSH default is yes. PermitRootLogin is correctly set to no. | FIXED |
| F9 | No disk gate | Low | No disk usage monitoring. df -h / → 43% used. Agent could fill the disk with logs or model downloads without triggering any alert. | FIXED |
chmod 600 /var/www/app/.env /var/www/app/.env.local /var/www/app/.env.production chown appuser:appuser /var/www/app/.env /var/www/app/.env.local /var/www/app/.env.production # Rotate all secrets that were exposed: # - OpenAI API key (sk-...) # - Database password # - Stripe secret key (sk_live_...)
$ stat -c '%a %U' /var/www/app/.env
600 appuser
$ curl -s -o /dev/null -w '%{http_code}' https://app.example.com/.env
403
adduser --system --group --home /srv/agent agent # In /etc/systemd/system/langchain-agent.service: [Service] User=agent Group=agent NoNewPrivileges=true ProtectSystem=strict ReadWritePaths=/srv/agent /var/log/agent systemctl daemon-reload && systemctl restart langchain-agent
$ ps -o user= -p $(pgrep -f langchain | head -1) agent $ ls -la /etc/shadow # agent user cannot read /etc/shadow: $ sudo -u agent cat /etc/shadow cat: /etc/shadow: Permission denied
# systemctl edit ollama: [Service] Environment="OLLAMA_HOST=127.0.0.1:11434" systemctl daemon-reload && systemctl restart ollama
$ ss -tlnH | grep 11434 127.0.0.1:11434 # From another machine: $ nmap -Pn -p 11434 [SERVER_IP] PORT STATE SERVICE 11434/tcp filtered unknown
Findings marked FIXED were re-tested on 2026-09-22 using the acceptance tests above. Finding F7 (backup restore test) remained open — the client chose to schedule the restore test for their next maintenance window. This report covers the server and agents named above on the date shown. It is not a guarantee that no other weakness exists.