# 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.

Source: https://nodecode.ai/docs/cyber-pentestgpt
Updated: 2026-11-10

[PentestGPT](https://pentestgpt.com) 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](https://nodecode.ai/docs/cyber#codex-cli) gives for Codex:

```toml
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:

```sh
export NODECODE_API_KEY=sk-nc-...
```

Then PentestGPT as its README has it:

```sh
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:

```sh
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`:

```sh
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.

```sh
pentestgpt-legacy --list-models
pentestgpt-legacy --smoke-test
```
