Skip to content
PentAGI
Configuration

Security

Credentials, HTTPS, sign-in and network exposure of a PentAGI installation.

Change the defaults

A fresh installation creates the local administrator [email protected] with the password admin, which must be changed at first sign-in. If the password is lost, the installer's maintenance menu resets it as long as the account still uses the [email protected] address.

Set these values in .env before the first start; the installer generates the salt and the passwords for you. PostgreSQL and Neo4j take their credentials only when they create their data volumes, so changing them later breaks the connection:

VariablePurpose
COOKIE_SIGNING_SALTSigns session cookies and API tokens — set a random value
PENTAGI_POSTGRES_USER, PENTAGI_POSTGRES_PASSWORDPostgreSQL credentials
NEO4J_PASSWORDNeo4j password for the knowledge graph; NEO4J_USER must stay neo4j
PUBLIC_URLThe URL users open, for example https://pentagi.example.com

On a running installation, change a database password inside PostgreSQL or Neo4j first, then in .env.

HTTPS

PentAGI serves HTTPS on port 8443 with a self-signed certificate. To use your own, set SERVER_SSL_CRT and SERVER_SSL_KEY and mount the files in docker-compose.yml.

Users and sign-in

There is no sign-up form. Administrators manage local users through the Users API (/api/v1/users/) from a signed-in browser session — an API token gets 403 there — and roles restrict what each user can see and change. Local users change their own email and password under Settings → Account.

With GitHub or Google sign-in configured, a login whose provider-verified email matches an existing account, local accounts included, signs into that account with its role; any other login gets a new account with the default user role. Every installation starts with the administrator [email protected], so move it to an address you control under Settings → Account before you enable sign-in, and enable it only where new accounts are acceptable, for example with a Google Workspace app limited to your domain.

GitHub and Google sign-in are available through OAuth. Register an app with the callback ${PUBLIC_URL}/api/v1/auth/login-callback and add its credentials:

PUBLIC_URL=https://pentagi.example.com
OAUTH_GITHUB_CLIENT_ID=your_github_client_id
OAUTH_GITHUB_CLIENT_SECRET=your_github_client_secret

Network exposure

By default the PentAGI web interface listens on 127.0.0.1 only. To reach it from other machines:

PENTAGI_LISTEN_IP=0.0.0.0
PENTAGI_LISTEN_PORT=8443
PUBLIC_URL=https://192.168.1.100:8443
CORS_ORIGINS=https://localhost:8443,https://192.168.1.100:8443

Use the real address in PUBLIC_URL and CORS_ORIGINS, never 0.0.0.0. Recreate the containers with docker compose up -d --force-recreate and open port 8443 in the firewall.

Behind a reverse proxy, set TRUSTED_PROXIES to the proxy's address or CIDR, comma-separated. Otherwise every request seems to come from the proxy, and the sign-in limit per address — 30 failed attempts in five minutes, then a 15-minute lockout — is shared by all users.

Each flow's sandbox container also publishes two ports for out-of-band callbacks, such as reverse shells. They come from the 2000 ports that start at DOCKER_PORTS_BASE (default 28000) and are bound to DOCKER_PUBLIC_IP, the address the agents also give targets to call back to.

By default DOCKER_PUBLIC_IP is 0.0.0.0: the ports listen on every interface of the Docker host, and the agents look up their public address themselves. Set it to a specific address only if the host owns that address and the targets can reach it; behind NAT, keep the default. Ports that Docker publishes bypass ufw and firewalld rules on the host, so restrict the range with a firewall in front of the host, such as a cloud security group, or with rules in Docker's DOCKER-USER chain.

PROXY_URL routes the backend's calls to model providers, the embedding provider, search APIs and the update check through a proxy, which helps isolate the installation from external networks. Self-hosted endpoints such as Ollama, vLLM or SearXNG go through it too, as there is no NO_PROXY exception, so the proxy must be able to reach them. The flows' sandbox containers, where the agents run their commands, the scraper, which opens web pages for the browser tool, and the Graphiti service do not use it, so restrict their outbound traffic at the network level. Sign-in with GitHub or Google and calls to a Langfuse or OpenTelemetry endpoint outside the bundled stacks do not use it either, and the Docker daemon pulls images with its own proxy settings.

Update check

Within two minutes of starting and then every three hours, the server asks update.pentagi.com whether a newer build is available. The request carries the installation ID, the license key if one is set, the version and platform, and a summary of the installation: the configured provider and sign-in types, a few feature switches, counts of users, flows, tasks, containers, prompts, API tokens and tool calls, and token and cost totals per provider type — no names, addresses, prompts or flow content. UPDATE_CHECK_INTERVAL=0 turns it off. Each time the installer starts and after each action it runs, such as Apply Changes, Update, Start or Stop, it sends the installed images and the state of each stack, plus the same summary while PentAGI is running; UPDATE_CHECK_INTERVAL does not affect it.

The pentagi container runs as root because it manages containers through the Docker socket. For stronger isolation, run the tools on a separate worker node.

Last updated on