Security Best Practices for Pentagi Deployment: A Production Hardening Guide
Run the built-in installer to generate cryptographically-secure secrets, enforce TLS verification for all connections, and isolate worker nodes to create a hardened, production-grade PentAGI deployment.
PentAGI is a self-hosted, AI-driven penetration-testing platform developed by vxcontrol/pentagi. Because it executes powerful security tools and arbitrary code inside Docker containers, following strict security best practices for Pentagi deployment is mandatory to prevent privilege escalation, data exfiltration, and unauthorized system access.
Use the Built-In Installer to Automate Secret Hardening
The interactive installer eliminates hard-coded credentials by automatically generating cryptographically-secure values for every sensitive variable. In backend/cmd/installer/hardening/hardening.go, the GenerateHardenedEnv() function (lines 44-48) replaces placeholders like COOKIE_SIGNING_SALT and PENTAGI_POSTGRES_PASSWORD with high-entropy strings.
The generation policies are defined in varsHardeningPolicies (lines 102-108), specifying hex strings, UUIDs, and random passwords that satisfy the complexity rules documented in CLAUDE.md (lines 8-12).
# Clone and run the installer to create a hardened .env file
git clone https://github.com/vxcontrol/pentagi
cd pentagi
./installer # Interactive UI generates secure defaults automatically
After completion, inspect the generated credentials to verify no default passwords remain:
cat .env | grep -E 'COOKIE_SIGNING_SALT|PENTAGI_POSTGRES_PASSWORD'
Enforce TLS Verification for External Connections
All outbound connections to LLM providers and search engines must verify SSL certificates. The configuration flag ExternalSSLInsecure in backend/pkg/config/config.go (lines 92-94) controls this behavior and defaults to false.
Never set EXTERNAL_SSL_INSECURE=true in production environments. This flag should only be used temporarily when testing against servers with self-signed certificates. For private certificate authorities, mount the CA bundle and set EXTERNAL_SSL_CA_PATH.
# .env – secure TLS configuration
EXTERNAL_SSL_INSECURE=false
EXTERNAL_SSL_CA_PATH=/etc/ssl/certs/internal_ca.pem
The TLS implementation in backend/pkg/system/utils.go (lines 84-94) enforces these settings for all HTTP clients:
tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: cfg.ExternalSSLInsecure, // Must remain false
},
}
Isolate Execution with a Two-Node Architecture
Separate the control plane from execution environments to limit blast radius. The primary node runs the API, UI, database, and orchestration logic, while a dedicated worker node handles sandboxed Docker-in-Docker containers. This architecture is documented in README.md (lines 10-13) and detailed in examples/guides/worker_node.md.
Benefits include network isolation (workers cannot access internal LAN services) and TLS-authenticated Docker communication via DOCKER_TLS_VERIFY and DOCKER_CERT_PATH.
# docker-compose.yml on primary node
services:
pentagi:
image: vxcontrol/pentagi:latest
environment:
- PENTAGI_WORKER_URL=tls://worker.example.com:2376
- DOCKER_TLS_VERIFY=1
- DOCKER_CERT_PATH=/certs
ports: ["8443:8443"]
# docker-compose.yml on worker node
services:
worker:
image: vxcontrol/pentagi-worker:latest
privileged: false
environment:
- DOCKER_TLS_VERIFY=1
volumes:
- /var/lib/docker:/var/lib/docker
- ./certs:/certs
Run Docker in Rootless Mode to Prevent Privilege Escalation
Avoid running containers as root. The README.md security warning (lines 600-601) explicitly cautions against adding users to the Docker group, as this effectively grants root access.
Production deployments must use rootless Docker on worker nodes. The main PentAGI service already runs as the pentagi user (non-root UID) in the Dockerfile.
# Install and enable rootless Docker on the worker
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
dockerd-rootless-setuptool.sh install
If you must expose the Docker API over TCP, always enable TLS encryption and client certificate verification.
Secure API Tokens with Strict TTL and Rotation Policies
All programmatic access uses Bearer tokens with configurable lifespans. As documented in README.md (line 1198), tokens support a minimum TTL of 1 minute and maximum of 3 years. Choose the shortest lifespan practical for your workflow.
Rotate tokens regularly via the GraphQL API defined in backend/pkg/graph/schema.graphqls (lines 990-1005). Never commit tokens to repositories; inject them via environment variables or secret managers.
# Example API request with Bearer token
curl -X POST https://pentagi.example.com/api/v1/flows \
-H "Authorization: Bearer $PENTAGI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Security Scan","input":"https://target.example.com"}'
# Rotate a token via GraphQL
mutation RotateToken {
rotateToken(id: "abcd1234") {
token
expiresAt
}
}
Configure Network Segmentation and Firewall Rules
Restrict network exposure to essential ports only. Block outbound traffic from workers to prevent data exfiltration while allowing necessary inbound connections.
- Port 8443/tcp: HTTPS UI/API access
- Port 2376/tcp: TLS-protected Docker-in-Docker (worker node only)
# UFW firewall configuration example
sudo ufw allow 8443/tcp
sudo ufw allow from 10.0.0.0/24 to any port 2376 proto tcp
sudo ufw deny out on eth0 to any port 22 # Prevent SSH from worker
Prevent Secret Leakage in Source Control
The repository includes .gitignore rules to exclude .env files and private keys. The installer explicitly warns about secret handling in backend/cmd/installer/wizard/locale/locale.go (line 1853).
Use a dedicated secret manager (HashiCorp Vault, AWS Secrets Manager, or Kubernetes Secrets) to inject values at container startup. When sharing configuration examples, always replace real values with placeholders like YOUR_POSTGRES_PASSWORD.
Maintain Updated Dependencies and Images
PentAGI's container images receive frequent security updates. Pull the latest tags before each deployment and verify checksums.
# Update all services to latest security patches
docker pull vxcontrol/pentagi:latest
docker pull vxcontrol/pentagi-worker:latest
docker compose pull
docker compose up -d --force-recreate
Summary
- Run the installer to automatically generate hardened secrets via
backend/cmd/installer/hardening/hardening.go - Keep TLS verification enabled by ensuring
EXTERNAL_SSL_INSECURE=falseinbackend/pkg/config/config.go - Deploy two-node architecture with isolated workers running rootless Docker
- Use short-lived API tokens and rotate them via the GraphQL endpoint
- Restrict firewall rules to ports 8443 and 2376 only
- Never commit secrets; use external secret managers
- Update images regularly to incorporate security patches
Frequently Asked Questions
What is the most critical first step when deploying PentAGI securely?
Run the interactive installer immediately after cloning vxcontrol/pentagi. The hardening logic in backend/cmd/installer/hardening/hardening.go (lines 44-48) automatically generates cryptographically-secure values for all credentials, eliminating default passwords that could be exploited.
Can I disable TLS verification for testing with self-signed certificates?
While the ExternalSSLInsecure flag in backend/pkg/config/config.go (lines 92-94) allows setting EXTERNAL_SSL_INSECURE=true, never enable this in production. Doing so exposes your deployment to man-in-the-middle attacks. For internal CAs, mount the certificate bundle via EXTERNAL_SSL_CA_PATH instead.
How does the two-node architecture improve security?
Separating the primary node (API/UI) from worker nodes creates network and filesystem isolation. The worker node, which executes arbitrary penetration testing tools in Docker containers, cannot access your internal services or database. Communication occurs over TLS-authenticated Docker-in-Docker protocols defined in examples/guides/worker_node.md.
What is the recommended lifecycle for API tokens?
Configure the shortest Time-To-Live (TTL) feasible for your automation—minimum 1 minute, maximum 3 years. Regularly rotate tokens using the GraphQL mutation in backend/pkg/graph/schema.graphqls (lines 990-1005) and never store tokens in version control or environment files committed to repositories.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →