Skip to content

Security: vybe/sparky

Security

SECURITY.md

Security Policy

Supported Versions

Version Supported
1.x.x

Reporting a Vulnerability

If you discover a security vulnerability, please email the maintainers directly instead of opening a public issue.

Please do NOT:

  • Open a public GitHub issue
  • Post in discussions or forums
  • Disclose publicly before a fix is available

Please DO:

  • Email details to the maintainer
  • Allow reasonable time for a fix
  • Coordinate disclosure timing

Authentication (implemented 2026-08-02)

The UI requires HTTP Basic auth. This is not a hardening option — it is the only thing standing in front of a shell-exec endpoint.

The Agent tab spawns Claude Code as the deploying user with --dangerously-skip-permissions, and nginx binds 0.0.0.0:3080. Before this landed, anyone who could route to the port could run arbitrary commands as that user. A VPN ACL is not sufficient: it covers the VPN, not the LAN the machine also sits on.

Property Behaviour
Scope Every route except /health (needed by the container healthcheck)
Storage nginx {SHA} htpasswd line, hashed by deploy.sh before leaving the dev machine
Missing credential Fails closed — empty htpasswd, nginx denies everything
File mode 640 root:nginx; workers drop privileges, so 600 breaks every request

Set SPARKY_AUTH_USER / SPARKY_AUTH_PASS in the gitignored .env.

Two related properties:

  • The FastAPI backend binds 127.0.0.1:3081. It exposes container control and shell exec; on host networking 0.0.0.0 would publish that to the LAN and the VPN.
  • Config URLs resolve against location.origin, so opening the app as http://user:pass@host/ works. Without that, every fetch throws — Chrome refuses to build a Request from a URL carrying credentials.

Basic auth over plain HTTP sends the credential on every request. That is acceptable inside a WireGuard/Tailscale tunnel and on a trusted LAN; it is not acceptable on an open network. Terminate TLS first if the box is ever exposed.


Incident: credentials published in git history

Recorded because the failure mode is instructive.

The SSH password was committed in plaintext — in VALIDATION_REPORT.md, and in the two .claude/ security checklists that grepped for it literally. The tooling meant to prevent the leak was the leak. It was public for roughly six months.

History was rewritten with git filter-repo on 2026-08-02, but that is not sufficient on its own:

  • Force-pushing orphans commits; it does not delete them. GitHub still serves them by SHA until it garbage-collects, which only GitHub Support can force.
  • Forks are independent repositories. Three of them still carry the original history.

A credential that reached a public repository must be rotated, not just removed.

Scanners now read literal values from .secret-patterns (gitignored, with a committed .example), and IP checks are range patterns rather than one hardcoded address — so they also catch addresses nobody thought to list.


Security Best Practices

For Deployment

  1. Never commit sensitive data

    • Use .env files (excluded from git)
    • Use environment variables
    • Use SSH keys instead of passwords
  2. Secure your server

    • Use firewall (UFW, iptables)
    • Restrict port access
    • Keep system updated
    • Use HTTPS in production
  3. Docker Security

    • Run containers as non-root when possible
    • Limit Docker socket access
    • Use read-only mounts where possible
    • Keep images updated
  4. Access Control

    • Use VPN for remote access (recommended)
    • Implement reverse proxy with authentication
    • Use strong passwords
    • Regular security audits

Configuration Security

.env File

Never commit .env files. Use .env.example as a template:

# GOOD - Use .env.example with placeholder values
DGX_HOST=your-server-ip
DGX_PASS=your-password

# BAD - Don't commit real values
# (192.0.2.x is RFC 5737 documentation space, used here so this example is not
#  itself a leak of a real internal address)
DGX_HOST=192.0.2.10
DGX_PASS=actualpassword123

SSH Keys (Recommended)

Instead of passwords in .env:

# Generate SSH key
ssh-keygen -t ed25519 -C "your_email@example.com"

# Copy to server
ssh-copy-id user@server

# Use deploy.sh without DGX_PASS
DGX_HOST=server-ip
DGX_USER=username
# DGX_PASS not needed with SSH keys

API Security

The backend API has these security considerations:

  1. Docker Socket Access

    • Required for container management
    • Limits: User must be in docker group
    • Risk: Can start/stop containers
  2. Command Execution

    • Limited to whitelisted commands
    • Timeout enforced
    • No shell injection possible
  3. Claude Code Integration

    • Runs with --dangerously-skip-permissions
    • Has access to host filesystem
    • Suitable for trusted environments only

Network Security

  1. Firewall Rules
# Allow only specific ports
sudo ufw allow 22/tcp    # SSH
sudo ufw allow 3080/tcp  # Web UI (nginx; the only surface that should be reachable)
sudo ufw enable

# Do NOT open 3081. The backend binds 127.0.0.1 and exposes container control
# and shell exec; nginx reaches it over the host's own loopback.
  1. Reverse Proxy (Production)

Use nginx or Caddy with HTTPS:

server {
    listen 443 ssl http2;
    server_name your-domain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://localhost:3080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
  1. VPN Access

Recommended for remote access:

  • Tailscale (easy setup)
  • WireGuard (performance)
  • OpenVPN (traditional)

Known Security Considerations

Docker Socket Mounting

The backend container mounts /var/run/docker.sock for container management.

Risk: Container can control Docker daemon Mitigation:

  • Runs as non-root user
  • Requires docker group membership
  • Limited to trusted environments

Claude Code Integration

Claude Code runs with autonomous permissions.

Risk: Can execute arbitrary commands Mitigation:

  • Runs in backend container only
  • No direct web exposure
  • Suitable for private/trusted deployments

Cross-origin handling (do not use OLLAMA_ORIGINS=*)

Ollama and ComfyUI reject any request whose Origin is not localhost with 403. The obvious fix is OLLAMA_ORIGINS=*, and it is the wrong one: it accepts every origin from every client on the box, so any page in any browser on the network can drive the model server.

What this project does instead: nginx strips the Origin header on /ollama/ and /comfyui/. That vouches only for requests arriving through this proxy — which is itself behind Basic auth — and leaves both services rejecting everything else.

The failure is confusing to diagnose, so it is worth naming: curl succeeds (it sends no Origin) while the browser gets 403.

Security Checklist

Before deploying to production:

  • .env file not in git
  • Strong passwords or SSH keys
  • Firewall configured
  • HTTPS enabled (reverse proxy)
  • VPN for remote access
  • Docker images up to date
  • System packages updated
  • Regular backups configured
  • Logs monitored
  • Access limited to trusted users

Production Deployment Example

Secure setup with Caddy + Tailscale:

# 1. Install Tailscale VPN
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

# 2. Install Caddy
sudo apt install caddy

# 3. Configure Caddy
sudo nano /etc/caddy/Caddyfile

Caddyfile:

your-tailscale-name.ts.net {
    reverse_proxy localhost:3080
}
# 4. Start services
sudo systemctl restart caddy
./deploy.sh deploy

Access only via Tailscale VPN: https://your-tailscale-name.ts.net

Update Policy

  • Security patches: Released ASAP
  • Dependencies: Updated monthly
  • System: Keep OS and Docker updated

Dependencies

Monitor for security updates:

# Check outdated npm packages
npm audit

# Update packages
npm update

# Python dependencies
pip list --outdated

Incident Response

If compromised:

  1. Immediate Actions

    • Disconnect from network
    • Stop affected containers
    • Change all passwords
    • Revoke SSH keys
  2. Investigation

    • Check logs: docker logs <container>
    • Review system logs: /var/log/
    • Check for unauthorized changes
  3. Recovery

    • Restore from backup
    • Update all credentials
    • Apply security patches
    • Review access controls
  4. Prevention

    • Document what happened
    • Update security measures
    • Improve monitoring

Additional Resources

Contact

For security issues, contact the repository maintainer directly.

There aren't any published security advisories