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=false in backend/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.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →