Reference·PentestGPTIndexClose
PentestGPT with an abliterated LLM
PentestGPT v1 drives Codex or Claude Code; this is the Codex provider block that puts Cyber v1, Nodecode's abliterated model, under it, and the base URL its interactive mode takes.
PentestGPT is the USENIX Security 2024 pentest agent, now at v1.0: it works through staged phases (asset discovery, vulnerability identification, report) and drives a coding agent to run the tools. That agent is Claude Code or Codex, which is what makes Cyber v1 reachable: both take a provider block.
The agent, on Codex
PentestGPT only ever calls the CLI in front of it, so the model is set in the CLI's own config. In ~/.codex/config.toml, the block the quickstart gives for Codex:
model = "nodecode-cyber-v1"
model_provider = "nodecode"
[model_providers.nodecode]
name = "Nodecode"
base_url = "https://api.nodecode.ai/v1"
env_key = "NODECODE_API_KEY"
wire_api = "responses"
env_key is the name of the variable the CLI reads the key from, so export it before a run:
export NODECODE_API_KEY=sk-nc-...
Then PentestGPT as its README has it:
git clone https://github.com/GreyDGL/PentestGPT.git
cd PentestGPT && make install
pentestgpt --target 10.10.11.234 --mode pentest
Inside its Docker flow the same block goes in the container's ~/.codex/config.toml, and MODEL=nodecode-cyber-v1 names it again on the command line:
make docker-run TARGET=10.10.11.234 BACKEND=codex MODEL=nodecode-cyber-v1 MODE=pentest
Two things this cost
Codex 0.162.1 refuses wire_api = "chat": it wants "responses", which this endpoint answers, so the block above is the working shape and the older examples that say chat are not.
A reasoning model spends tokens before it answers, and Codex counts them against the turn. A phase that ends early, with no tool call and no text, is a max_tokens that was too small rather than a refusal.
The interactive mode
pentestgpt-legacy is the human-in-the-loop agent from the paper. It talks to providers through its own SDKs, and the OpenAI connector takes a base URL of its own in .env:
OPENAI_API_KEY=sk-nc-...
OPENAI_BASE_URL=https://api.nodecode.ai/v1
Its model list is a registry (pentestgpt_legacy/llm/registry.py), and --list-models prints what it holds, so a model that is not in it is not selectable there: add one ModelSpec entry, since its OpenAI-compatible providers share one connector.
pentestgpt-legacy --list-models
pentestgpt-legacy --smoke-test