Security considerations and best practices for running Apantli.
- Security Model
- Network Exposure
- API Key Management
- Database Security
- Production Deployment
- Security Checklist
- Reporting Security Issues
Apantli provides NO authentication or authorization by default.
It is designed for:
- ✅ Local development on a single-user machine
- ✅ Trusted network environments
- ✅ Personal use with localhost-only binding
It is NOT designed for:
- ❌ Public internet exposure without additional security
- ❌ Multi-user environments without authentication
- ❌ Untrusted networks
By default, Apantli binds to 0.0.0.0:4000 (all network interfaces):
apantli # Binds to 0.0.0.0:4000This means anyone on your network can:
- Send requests to any configured LLM model using your API keys
- Access the web dashboard and view all conversation history
- Read all stored requests and responses
- Query cost and usage statistics
For single-user local development, bind to localhost only:
apantli --host 127.0.0.1This ensures only processes on your machine can access the server.
If you must bind to 0.0.0.0 (for example, to access from other devices on your local network):
-
Use a firewall to restrict access:
# macOS sudo /usr/libexec/ApplicationFirewall/socketfilterfw --add /path/to/python sudo /usr/libexec/ApplicationFirewall/socketfilterfw --block /path/to/python # Linux (ufw) sudo ufw deny 4000 sudo ufw allow from 192.168.1.0/24 to any port 4000 # Allow local network only
-
Use SSH tunneling to access remotely:
# On remote machine ssh -L 4000:localhost:4000 user@your-machine # Then access http://localhost:4000 in browser
-
Use a reverse proxy with authentication (see Production Deployment)
DO:
- ✅ Store API keys in
.envfile (gitignored) - ✅ Use
os.environ/VAR_NAMEformat inconfig.yaml - ✅ Use separate API keys for development and production
- ✅ Rotate API keys periodically
- ✅ Use provider-specific key scopes (e.g., read-only keys where possible)
DON'T:
- ❌ Hardcode API keys in
config.yaml - ❌ Commit
.envto version control - ❌ Share API keys between environments
- ❌ Use root/admin keys if provider offers scoped keys
- ❌ Log API keys to stdout/stderr
Protect your .env file:
chmod 600 .env # Owner read/write onlyCheck permissions:
ls -la .env
# Should show: -rw------- (600)Important: Apantli stores full request JSON (including API keys) in requests.db for debugging purposes.
Implications:
- The database contains sensitive data
- Anyone with read access can see your API keys
- Backup files must be protected
- Database exports must be treated as sensitive
Mitigation:
-
Protect database file:
chmod 600 requests.db
-
Use separate API keys for Apantli (not your main production keys)
-
Implement data retention to delete old requests:
# Delete requests older than 30 days sqlite3 requests.db "DELETE FROM requests WHERE timestamp < datetime('now', '-30 days')" sqlite3 requests.db "VACUUM"
-
Consider API key redaction (future enhancement):
- Modify
database.pyto redact keys before storage - Or set
request_data = Noneto skip JSON storage
- Modify
The SQLite database (requests.db) contains:
- Full conversation history (all messages)
- API keys (in request JSON)
- Metadata (timestamps, costs, models)
- Error messages and stack traces
Default location: Project root directory
Best practices:
-
Restrict file permissions:
chmod 600 requests.db
-
Use custom location for sensitive environments:
# Store in secure directory mkdir -p ~/.apantli chmod 700 ~/.apantli apantli --db ~/.apantli/requests.db
-
Encrypt storage volume (OS-level):
- macOS: Use FileVault
- Linux: Use LUKS/dm-crypt
- Windows: Use BitLocker
Database backups contain sensitive data:
# Secure backup
cp requests.db ~/.apantli/requests.db.backup
chmod 600 ~/.apantli/requests.db.backup
# Or encrypt backup
tar czf - requests.db | gpg -c > requests.db.backup.tar.gz.gpgNever:
- Store backups in cloud storage without encryption
- Email database files
- Share database files via insecure channels
For production or network-exposed deployments, implement additional security layers.
Use nginx or similar to add authentication:
# /etc/nginx/sites-available/apantli
server {
listen 443 ssl;
server_name apantli.yourdomain.com;
# SSL configuration
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# Basic authentication
auth_basic "Apantli Access";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://127.0.0.1:4000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Create password file:
sudo htpasswd -c /etc/nginx/.htpasswd usernameFor programmatic access, consider implementing API key auth in a fork or wrapper:
from fastapi import Security, HTTPException
from fastapi.security import APIKeyHeader
api_key_header = APIKeyHeader(name="X-API-Key")
async def verify_api_key(api_key: str = Security(api_key_header)):
if api_key != os.environ.get("APANTLI_API_KEY"):
raise HTTPException(status_code=403, detail="Invalid API key")
return api_key
# Add to routes
@app.post("/v1/chat/completions", dependencies=[Depends(verify_api_key)])
async def chat_completions(request: Request):
# ...Always use HTTPS for network-exposed deployments:
- Use a reverse proxy (nginx, caddy) with TLS termination
- Get certificates from Let's Encrypt or your certificate authority
- Enforce HTTPS (redirect HTTP to HTTPS)
If deploying with Docker:
# Dockerfile
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY apantli/ ./apantli/
COPY templates/ ./templates/
COPY config.yaml .
# Non-root user
RUN useradd -m -u 1000 apantli && \
chown -R apantli:apantli /app
USER apantli
CMD ["python", "-m", "apantli.server", "--host", "0.0.0.0", "--port", "4000"]Security considerations:
- Run as non-root user
- Use
.envfile or secrets management - Mount database volume with proper permissions
- Limit container capabilities
-
.envfile has mode 600 permissions -
.envis in.gitignore - Server binds to
127.0.0.1(localhost only) - Database file has mode 600 permissions
- Using separate API keys (not production keys)
- Authentication implemented (reverse proxy, API keys, or both)
- HTTPS/TLS enabled
- Firewall configured to restrict access
- Database encrypted at rest (volume encryption)
- Database location outside web root
- Regular backups configured (encrypted)
- Data retention policy implemented
- Monitoring and alerting configured
- Security updates applied regularly
- Data retention policy documented
- Old requests deleted automatically
- Database backups encrypted
- API keys rotated periodically
- Access logs reviewed regularly
Apantli does not include authentication or authorization. You must implement this yourself or use a reverse proxy.
Mitigation: See Production Deployment for options.
Full request JSON (including API keys) is stored in the database for debugging.
Mitigation:
- Use separate API keys for Apantli
- Protect database file with 600 permissions
- Implement data retention to delete old requests
- Consider forking and modifying to redact keys
Apantli does not implement rate limiting. Anyone with access can make unlimited requests.
Mitigation:
- Bind to localhost only (
--host 127.0.0.1) - Use firewall rules to restrict access
- Implement reverse proxy with rate limiting
- Monitor provider API usage
SQLite uses file-level locking and provides no network access control.
Mitigation:
- Protect file with permissions (600)
- Use encrypted filesystem
- Consider Postgres for multi-user deployments
The dashboard displays user-supplied content (request/response JSON). While escapeHtml() is used, complex JSON may contain edge cases.
Mitigation:
- Dashboard is meant for trusted users only
- Always bind to localhost for personal use
- Use authentication if exposing to network
If you discover a security vulnerability in Apantli:
- DO NOT open a public GitHub issue
- DO report via email to the project maintainer
- Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
We will respond within 48 hours and work with you to address the issue.
Remember: Apantli is designed for local, single-user use. If you need multi-user support or network exposure, implement proper authentication, authorization, and encryption before deployment.